< Zurück

02.12.2012 22:56:00 • Categories: Monkey X, 2D Game SDK / Framework, Multiplatform • Tags: Monkey, Game

Monkey: asteroids game example

Strict

Import mojo

Global game:MyGame

Function Main:Int()     game = New MyGame     Return 0 End Function

Const PDM_smlparticle%=0 Const PDM_medparticle%=1 Const PDM_bigparticle%=2 Const PDM_spark%=3

Global ASTEROIDS_NUM% = 6 Global ASTEROIDS_SIZE% = 4

' Store the device width and height Global SCREEN_WIDTH% Global SCREEN_HEIGHT% ' Half of SCREEN_WIDTH and HEIGHT Global SCREEN_WIDTH2% Global SCREEN_HEIGHT2%

' Used for delta timing movement Global dt:DeltaTimer

' Screen states Const STATE_TITLE% = 1 Const STATE_GAME% = 2 Const STATE_GAME_OVER% = 3

Class MyGame Extends App

Field player:Player Field cg%, cr%, cb% Field level% = 1 Field score% = 0 Field bestScore% = 0

Field FPS% = 60 ' Current game state Global gameState:Int = STATE_TITLE

Method OnCreate:Int()     ' Store the device width and height     SCREEN_WIDTH = DeviceWidth()     SCREEN_HEIGHT = DeviceHeight()     SCREEN_WIDTH2 = SCREEN_WIDTH / 2     SCREEN_HEIGHT2 = SCREEN_HEIGHT / 2     ' Set the Random seed     Seed = Millisecs()     ' Create the delta timer     dt = New DeltaTimer(FPS)     SetUpdateRate FPS

    reset()     Return 0    End Method

Method OnLoading:Int()     Cls 0,0,0     DrawText("Loading", SCREEN_WIDTH2, SCREEN_HEIGHT2, 0.5, 0)     Return 0 End Method

Method OnUpdate:Int()     FPSCounter.update()     dt.UpdateDelta()

    Select gameState     Case STATE_TITLE         Asteroid.updateAll()         If KeyHit(KEY_SPACE)            setState(STATE_GAME)         Endif       Case STATE_GAME         player.Update()         Bullet.updateAll()         Asteroid.updateAll()         Particle.updateAll()         checkCollisions()         clscolor()     Case STATE_GAME_OVER         Asteroid.updateAll()         Particle.updateAll()            If KeyHit(KEY_SPACE)            setState(STATE_TITLE)             reset()         Endif     End Select

    Return 0 End Method

Method OnRender:Int()     Select gameState     Case STATE_TITLE     Cls 0, 0, 0     Asteroid.drawAll()     DrawText ("ASTEROIDS - MONKEY STYLE!", SCREEN_WIDTH2, SCREEN_HEIGHT2, 0.5, 0.5)     DrawText ("BEST SCORE: "+Self.bestScore, SCREEN_WIDTH2, SCREEN_HEIGHT2 + 30, 0.5, 0.5)     DrawText ("PRESS <space> TO PLAY", SCREEN_WIDTH2, SCREEN_HEIGHT2 + 60, 0.5, 0.5)     Case STATE_GAME     Cls cr, cg, cb     player.draw()     Bullet.drawAll()     Asteroid.drawAll()     Particle.drawAll()     drawHUD()     Case STATE_GAME_OVER     Cls 0, 0, 0     Asteroid.drawAll()     Particle.drawAll()     DrawText ("GAME OVER!", SCREEN_WIDTH2, SCREEN_HEIGHT2, 0.5, 0.5)     DrawText ("SCORE: "+score, SCREEN_WIDTH2, SCREEN_HEIGHT2 + 30, 0.5, 0.5)     DrawText ("BEST SCORE: "+Self.bestScore, SCREEN_WIDTH2, SCREEN_HEIGHT2 + 60, 0.5, 0.5)     DrawText ("PRESS <space> TO RETURN TO THE TITLE SCREEN", SCREEN_WIDTH2, SCREEN_HEIGHT2 + 90, 0.5, 0.5)     End Select     Return 0 End Method

Method setState:Void(state:Int)     gameState = state End

Method clscolor:Void()     If cr > 0     cr-=2*dt.delta     Else     cr = 0     Endif End Method

Method reset:Void()     Bullet.list.Clear()     Asteroid.list.Clear()     Particle.list.Clear()     cg = 0     cr = 0     cb = 0     level = 1     ASTEROIDS_NUM = 6     ASTEROIDS_SIZE = 4     score = 0     player = New Player(SCREEN_WIDTH2, SCREEN_HEIGHT2)     fillAsteroids(ASTEROIDS_NUM, ASTEROIDS_SIZE)    End Method

Method checkCollisions:Void()     For Local a:Asteroid = Eachin Asteroid.list

        If dist(player.x, player.y, a.x, a.y) <= a.avgrad         If cr = 0 Then cr = Rnd(100, 155)         player.shield-=2         Endif

        For Local b:Bullet = Eachin Bullet.list             If a <> Null Then                 If dist(b.x, b.y, a.x, a.y) <= a.avgrad                     a.life = a.life - 1                     b.life = 0                     For Local t%=1 To 4                         New Particle(a.x, a.y, Rnd(-8,8), Rnd(-8,8), 0.95, 30, PDM_spark, 255, 192, 64, 16)                     Next                     For Local t%=1 To 4                         New Particle(a.x, a.y, Rnd(-4,4), Rnd(-4,4), 0.95, 60, PDM_smlparticle, 160, 160, 160, 0)                     Next                 Endif                 If a.life <= 0

                For Local t%=1 To 8                     New Particle(a.x,a.y,Rnd(-10,10),Rnd(-10,10),0.95,30,PDM_spark,255,192,64,64)                 Next                 For Local t%=1 To 6                     New Particle(a.x,a.y,Rnd(-6,6),Rnd(-6,6),0.95,30,PDM_medparticle,255,192,64,128)                 Next                 For Local t%=1 To 6                     New Particle(a.x,a.y,Rnd(-8,8),Rnd(-8,8),0.99,60,PDM_smlparticle,160,160,160,0)                 Next                 For Local t%=1 To 5                     New Particle(a.x,a.y,Rnd(-6,6),Rnd(-6,6),0.99,60,PDM_medparticle,160,160,160,0)                 Next                 For Local t%=1 To 4                     New Particle(a.x,a.y,Rnd(-4,4),Rnd(-4,4),0.99,60,PDM_bigparticle,160,160,160,0)                 Next

                If a.size > 1                     For Local t% = 1 To 2                         New Asteroid(a.x, a.y, Rnd(-5,5), Rnd(-5,5), a.size-1)                     Next                 Endif                 Asteroid.list.Remove(a)                 a = Null                 score+=5                 Endif             Endif         Next     Next     If Asteroid.list.Count() = 0         level+=1         ASTEROIDS_SIZE+=1         ASTEROIDS_NUM+=1         fillAsteroids(ASTEROIDS_NUM, ASTEROIDS_SIZE)     Endif End Method

    Method drawHUD:Void()         DrawText ("LEVEL: "+level, 0, 0)         DrawText("SCORE: "+score, SCREEN_WIDTH, 0, 1, 0)

        FPSCounter.draw(SCREEN_WIDTH,SCREEN_HEIGHT, 1, 1)     End Method

    Method fillAsteroids:Void(num%, size%)         Local tx#         Local ty#         For Local t% = 1 To num             Repeat                 tx=Rnd(640)                 ty=Rnd(480)             Until ( tx<280 or="" tx="">360 ) And ( ty<200 or="" ty="">280 )             New Asteroid(tx, ty, Rnd(-3,3), Rnd(-3,3), size+Rnd(1))         Next     End Method End Class

Class Sprite     Field xv# ,yv#     Field x#, y#     Field rotation# End Class

Class Player Extends Sprite     Field angVel#     Field velmul#     Field vel#     Field acc#     Field drag#     'Field xv#,yv#     Field xa#,ya#     Field firedel#

    Field ship_angvel#     Field ship_acc#     Field ship_velmul#     Field ship_firedel#

    Field shield#=100

    Method New(x#, y#)         Self.x = x         Self.y = y         ship_angvel = 6         ship_acc = 0.16         ship_velmul = -0.0005         ship_firedel = 4         shield = 100     End Method

    Method Update:Void()

        If KeyDown(KEY_UP)             acc =  ship_acc             drag = vel ship_velmul         Else If KeyDown(KEY_DOWN)             drag = vel ship_velmul 50         Else             acc = 0             drag = 0         End If          If KeyDown(KEY_LEFT)             rotation+=ship_angvel dt.delta         End If         If KeyDown(KEY_RIGHT)             rotation-=ship_angvel * dt.delta         End If

        If KeyDown(KEY_SPACE) And Self.firedel<=0             Local tang#=Rnd(-4,4)             New Bullet(x - (Sin(rotation)8), y-(Cos(rotation)8), xv - (Sin(rotation + tang ) 12), yv-(Cos(rotation + tang ) 12), 45, 255-Rnd(4), 192+Rnd(-4,4), 64+Rnd(4,4))             firedel = ship_firedel         Endif         firedel-=dt.delta

        xa = (drag xv) - (Sin(rotation) acc)         ya = (drag yv) - (Cos(rotation) acc)         xv = xv + xa dt.delta         yv = yv + ya dt.delta         x = x + xv dt.delta         y = y + yv dt.delta         vel = dist(0, 0, xv, yv)         '           If x < 0 x = SCREEN_WIDTH         If x > SCREEN_WIDTH x = 0         If y < 0 y = SCREEN_HEIGHT         If y > SCREEN_HEIGHT y = 0

        If shield <= 0         For Local t%=1 To 18             New Particle( x, y,Rnd(-10,10),Rnd(-10,10),0.95,130,PDM_spark,255,192,64,64)         Next         For Local t%=1 To 16             New Particle( x, y,Rnd(-6,6),Rnd(-6,6),0.95,130,PDM_medparticle,255,192,64,128)         Next         For Local t%=1 To 16             New Particle( x, y,Rnd(-8,8),Rnd(-8,8),0.99,160,PDM_smlparticle,160,160,160,0)         Next         For Local t%=1 To 15             New Particle( x, y,Rnd(-6,6),Rnd(-6,6),0.99,160,PDM_medparticle,160,160,160,0)         Next         For Local t%=1 To 14             New Particle( x, y,Rnd(-4,4),Rnd(-4,4),0.99,160,PDM_bigparticle,160,160,160,0)         Next

        If game.score>game.bestScore             game.bestScore = game.score         Endif

        game.setState(STATE_GAME_OVER)         Endif     End Method

    Method draw:Void()         Local x1# = x-(Sin(rotation) 10)         Local y1# = y-(Cos(rotation) 10)         Local x2# = x-(Sin(rotation + 140 ) 8)         Local y2# = y-(Cos(rotation + 140 ) 8)         Local x3# = x-(Sin(rotation - 140 ) 8)         Local y3# = y-(Cos(rotation - 140 ) 8)         SetColor 255, 255, 255         DrawLine x1, y1, x2, y2         DrawLine x2, y2, x3, y3         DrawLine x3, y3, x1, y1

        SetAlpha 0.5         If shield < 50 Then SetColor 255,0,0         DrawRect 10,SCREEN_HEIGHT - 15, Self.shield, 10         SetAlpha 1         SetColor 255,0,0     End Method

End Class

Class Bullet Extends Sprite     Global list:List<bullet> = New List<bullet>

    Field life#     Field cr%, cg%, cb%

    Method New(x#,y#,xv#,yv#,life#,cr%,cg%,cb%)         Self.x = x         Self.y = y         Self.xv = xv         Self.yv = yv         Self.life = life         Self.cr = cr         Self.cg = cg         Self.cb = cb

        list.AddLast Self     End Method

    Function updateAll:Void()         If Not list Return         For Local b:Bullet = Eachin list             b.update()             If b.life < 0                 Bullet.list.Remove(b)             b = Null         Endif

        Next     End Function

    Method update:Void()         x = x + xv dt.delta         y = y + yv dt.delta

        life-=dt.delta         If x < 0 x = SCREEN_WIDTH         If x > SCREEN_WIDTH x = 0         If y < 0 y = SCREEN_HEIGHT         If y > SCREEN_HEIGHT y = 0     End Method

    Function drawAll:Void()         If Not list Return         For Local b:Bullet = Eachin list             b.draw()         Next        End Function

    Method draw:Void()     Local tmul#     If life <= 15.0     tmul = life / 15.0     Else     tmul = 1.0     Endif     SetColor crtmul, cgtmul, cb*tmul     DrawLine x, y, x + xv, y + yv     End Method End Class

Class Asteroid Extends Sprite     Global list:List<asteroid> = New List<asteroid>

    Field ang#,angvel#     Field rad#[9]     Field avgrad#     Field size%     Field life%     Field cr%, cg%, cb%

    Method New(x#,y#,xv#,yv#,size%)         Self.x =x         Self.y =y         Self.xv =xv         Self.yv =yv         Self.ang =Rnd(360)         Self.angvel =Rnd(-6,6)         Self.size=size         Self.life=size         Local tcol% = Rnd(-48,48)         Self.cr=128+tcol         Self.cg=128+tcol         Self.cb=128+tcol         ' Create "Rockiness"         Self.avgrad =0         For Local t% = 0 To 7             Self.rad [t]=size8.0+Rnd(-size4.0,size*4.0)             Self.avgrad =Self.avgrad +Self.rad[t]         Next         Self.avgrad =Self.avgrad /6.0         Self.rad[8] = Self.rad[0]

        list.AddLast Self     End Method

    Function drawAll:Void()         If Not list Return             For Local b:Asteroid = Eachin list             b.draw()         Next        End Function

    Function updateAll:Void()         If Not list Return             For Local b:Asteroid = Eachin list             b.update()          Next     End Function

    Method update:Void()         Self.x =Self.x +Self.xv dt.delta         Self.y =Self.y +Self.yv dt.delta         Self.rotation =Self.rotation +Self.angvel * dt.delta

        If Self.x <-Self.avgrad  Then Self.x =Self.x + SCREEN_WIDTH + Self.avgrad 2         If Self.x >SCREEN_WIDTH+Self.avgrad  Then Self.x =Self.x - SCREEN_WIDTH - Self.avgrad 2         If Self.y <-Self.avgrad  Then Self.y =Self.y + SCREEN_HEIGHT + Self.avgrad 2         If Self.y >SCREEN_HEIGHT+Self.avgrad  Then Self.y =Self.y - SCREEN_HEIGHT - Self.avgrad 2     End Method

    Method draw:Void()         Local tmul# = 360.0 / 8.0         SetColor cr, cg, cb         For Local t% = 0 To 7             DrawLine x-(Sin(rotation+(t)tmul)rad[t]),y-(Cos(rotation+(t)tmul)rad[t]),x-(Sin(rotation+(t+1)tmul)rad[t+1]),y-(Cos(rotation+(t+1)tmul)rad[t+1])         Next     End Method End Class

Class Particle Extends Sprite     Global list:List<particle> = New List<particle>

    Field vm#     Field life#,mlife#     Field drawmode%     Field cr%,cg%,cb%     Field cflash%

    Method New(x#,y#,xv#,yv#,vm#,life#,drawmode%,cr%,cg%,cb%,cflash%)         Self.x=x         Self.y=y         Self.xv=xv         Self.yv=yv         Self.vm=vm         Self.life=life         Self.mlife=life         Self.drawmode=drawmode         Self.cr=cr         Self.cg=cg         Self.cb=cb         Self.cflash=cflash

        list.AddLast Self     End Method

    Function updateAll:Void()         If Not list Return         For Local b:Particle = Eachin list             b.update()          Next     End Function

    Function drawAll:Void()         If Not list Return         For Local b:Particle = Eachin list             b.draw()         Next            End Function

    Method update:Void()         Self.x =Self.x +Self.xv dt.delta         Self.y =Self.y +Self.yv dt.delta         Self.xv =Self.xv (1.0-(1.0-Self.vm )dt.delta )         Self.yv =Self.yv (1.0-(1.0-Self.vm )dt.delta )         Self.life =Self.life -dt.delta         If Self.life <0 then="" selflife="0" if="" listremoveself="" endif="" end="" method="" draw:void="" local="" tmul="Self.life" selfmlife="" tfls="Rnd(-Self.cflash,Self.cflash)" setcolor="" limit="" selfcrtmul="" tfls0255limit="" selfcgtmul="" selfcb="" tmultfls0255="" select="" selfdrawmode="" case="" pdm_smlparticle="" drawrect="" selfx="" selfy="" 1="" pdm_medparticle="" drawoval="" -1selfy="" -133="" pdm_bigparticle="" -2selfy="" -255="" pdm_spark="" drawline="" selfxv="" selfyv="" class="" fpscounter="" abstract="" global="" fpscount:int="" starttime:int="" totalfps:int="" function="" update:void="" millisecs="" -="" starttime="">= 1000             totalFPS = fpsCount             fpsCount = 0             startTime = Millisecs()         Else             fpsCount+=1         Endif     End Function

    Function draw:Void(x% = 0, y% = 0, ax# = 0, ay# = 0)         DrawText("FPS: " + totalFPS, x, y, ax, ay)     End Function End Class

' From James Boyd Class DeltaTimer     Field targetfps:Float = 60     Field currentticks:Float     Field lastticks:Float     Field frametime:Float     Field delta:Float

    Method New (fps:Float)         targetfps = fps         lastticks = Millisecs()     End

    Method UpdateDelta:Void()         currentticks = Millisecs()         frametime = currentticks - lastticks         delta = frametime / (1000.0 / targetfps)         lastticks = currentticks     End End

Function dist#(x1#,y1#,x2#,y2#)     Return Sqrt(Pow((x1-x2),2) + Pow((y1-y2),2)) End Function

Function limit#(value#,low#,high#)     If value < low Then Return low     If value > high Then Return high     Return value End Function </particle></particle></asteroid></asteroid></bullet></bullet></space></space>

 


< Zurück | ^ nach oben