Unlimited Bobs - mojo2

Rich

Active Member
3rd Party Module Dev
3rd Party Tool Dev
Joined
Sep 9, 2017
Hi
Not sure if this has been posted before. Thought I'd play last night.
Takes me back to the Amiga days

Cerberus X:
Strict
' credit https://www.pygame.org/pcr/unlimited_sprites/index.php

Import mojo2

Class game Extends App
    Field canvas:Canvas
    Field images:Image[25]
    Field frame:Int
    Field cx:Int,cy:Int
    Field xa:Float,ya:Float
    Field icanvas:Canvas

    ' increase number of frames to make a largger gap between "new balls"
    Const frames:=10

    Method OnCreate:Int()
        Local i:Int
    
        cx=DeviceWidth()/2
        cy=DeviceHeight()/2
    
        canvas = New Canvas
        icanvas = New Canvas
    
        SetUpdateRate(60)
        i=0
        While i<frames
            images[i] = New Image(cx*2,cy*2)
            i=i+1
        Wend

        xa=0
        ya=0

        frame=0
        Return 0
    End

    Method OnUpdate:Int()
        Return True
    End

    Method OnRender:Int()
        Local x:Float,y:Float

        ' MATHS stuff, play with these numbers to produce different routes for the balls
        x = cx*Sin(xa*0.74)
        y = cy*Cos(ya*0.64)

        ' move angle
        xa = xa + 1.1
        ya = ya + 1.3

        ' draw into image frame only
        icanvas.SetRenderTarget(images[frame])
    
        ' just draw the ball (dont clear old balls <<< thats the trick)
        DrawBall(icanvas,cx+x,cy+y)
        icanvas.Flush

        ' draw image frame to screen
        canvas.Clear
        canvas.DrawImage images[frame],cx,cy
        canvas.Flush
    
        frame=(frame+1) Mod frames
        Return True
    End

    Method DrawBall:Void(c:Canvas,x:Float,y:Float)
        ' draw simple shaded ball using DrawOval (vert Amiga like)
        c.SetColor 0,0,0
        c.DrawOval x-20,y-20,40,40
        c.SetColor 0.4,0.5,0.5
        c.DrawOval x-18,y-18,36,36
        c.SetColor 0.6,0.8,0.8
        c.DrawOval x-17,y-17,30,30
        c.SetColor 0.8,0.9,0.9
        c.DrawOval x-16,y-16,20,20
        c.SetColor 1,1,1
        c.DrawOval x-12,y-12,8,8
    End
End

Function Main:Int()
    New game    
    Return 0
End
Cant think of a way to do this in Mojo 1 as it uses multiple images to draw into before flushing it onto the screen
 

Attachments

Last edited by a moderator:

AutmnLeaf

New Member
Joined
Feb 19, 2018
For curiosity, I made sometime last year "unlimited objects" video, too. My implementation was a bit clumsy, but did the job.

The Monkey X Pro / Cerberus X source code, that does the job (no external graphics files):

Cerberus X:
Import mojo2

Function Main()
    New MyApp
End

Class MyApp Extends App

    Field gfxCopy:Image[16]
    Field ccanvas:Canvas[16]
    Field counter:Int
    Field angle:Float
    Field canvas:Canvas

    Field x:Float, y:Float
    Field r:Float

    Method OnCreate()
    
        canvas = New Canvas()
        counter = 0
    
        For Local i:Int = 0 To 15
            gfxCopy[i] = New Image(640,480,.0,.0)
            ccanvas[i] = New Canvas(gfxCopy[i])
        Next
    
        r = 100
        SetUpdateRate(60)
    End

    Method OnUpdate()
        angle = angle + 2
    End

    Method OnRender()
    
        ccanvas[counter].PushMatrix()
    
        x = Cos(angle) * r + 640 / 2
        y = Sin(angle) * r + 480 / 2
    
        r = r + 0.1
    
        ccanvas[counter].SetColor(0,0,1)
        ccanvas[counter].DrawCircle(x,y,32)
        ccanvas[counter].SetColor(1,0,1)
        ccanvas[counter].DrawCircle(x,y,30)
    
        ccanvas[counter].Flush()
        ccanvas[counter].PopMatrix()
    
        canvas.PushMatrix()
        canvas.Clear

        canvas.DrawImage(gfxCopy[counter],0,0)

        canvas.Flush()
        canvas.PopMatrix()
            
        counter = counter + 1
        If counter = 16 Then counter = 0
    
    End

End Class
Copy/paste the code into Cerberus X editor and see the miracle -- unlimited objects! :)

Screenshot of the program:

unlimited objects.png


Below is the video I made:

 
Last edited by a moderator:

AutmnLeaf

New Member
Joined
Feb 19, 2018
I tried it this morning by using only two canvases, too. The effect is same.

Cerberus X:
Import mojo2

Function Main()
    New MyApp
End

Class MyApp Extends App
 
    Field gfxCopy:Image[16]
    Field ccanvas:Canvas
    Field counter:Int
    Field angle:Float 
    Field canvas:Canvas
 
    Field scaleX:Float, scaleY:Float
     
    Field x:Float, y:Float
    Field r:Float
 
    Method OnCreate()
         
        canvas = New Canvas()
        counter = 0
     
        For Local i:Int = 0 To 15
            gfxCopy[i] = New Image(640,480,.0,.0)
        Next
     
        ccanvas = New Canvas(gfxCopy[0])
     
        scaleX = DeviceWidth / 640
        scaleY = DeviceHeight / 480
     
        r = 100
        SetUpdateRate(60)
    End
 
    Method OnUpdate()

    End
 
    Method OnRender()
     
        angle = angle + 2

        x = Cos(angle) * r + 640 / 2
        y = Sin(angle) * r + 480 / 2
     
        r = r + 0.1

        counter = counter + 1
        If counter = 16 Then counter = 0
             
        ccanvas.SetRenderTarget(gfxCopy[counter])
        ccanvas.SetColor(1,1,0)
        ccanvas.DrawCircle(x,y,32)
        ccanvas.SetColor(1,0,1)
        ccanvas.DrawCircle(x,y,30)
     
        ccanvas.Flush()
     
        canvas.PushMatrix()
        canvas.Scale(scaleX,scaleY)
     
        canvas.Clear 

        canvas.DrawImage(gfxCopy[counter],0,0)

        canvas.Flush()
        canvas.PopMatrix()
                     
    End
 
End Class
I edited the code so that, it gives same output on HTML5 target as in other targets. I noticed, that if calculations are done in OnUpdate() on HTML5 target, the effect is not the same as in Desktop target.
 
Last edited by a moderator:
Top Bottom