#rem One Arrow Version 0.1 Beta By Ben McGaughey for LudumDare 28 Copyright 2013 #end Import mojo #GLFW_USE_MINGW=true #GLFW_WINDOW_TITLE="LD28" #GLFW_WINDOW_WIDTH=800 '1024 #GLFW_WINDOW_HEIGHT=600 '768 #GLFW_WINDOW_RESIZABLE=False #GLFW_WINDOW_FULLSCREEN=False #OPENGL_GLES20_ENABLED=False #OPENGL_DEPTH_BUFFER_ENABLED=False #MOJO_AUTO_SUSPEND_ENABLED=False #MOJO_IMAGE_FILTERING_ENABLED=True Const WIDTH# = 800 '1024 Const HEIGHT# = 600 '768 Const WIDTH_HALF# = 400 '512 Const HEIGHT_HALF# = 300 '384 Const GAME_STATE_LOADING:Int = 0 Const GAME_STATE_MENU:Int = 1 Const GAME_STATE_PLAY:Int = 2 Const GAME_STATE_PAUSED:Int = 3 Const GAME_STATE_LOADGAME:Int = 4 Const GAME_STATE_SUREQUIT:Int = 5 Const GAME_STATE_GAMEOVER:Int = 6 Const TOUCHED_NONE:Int = 0 Const TOUCHED_NEWGAME:Int = 1 Const TOUCHED_TWITTER:Int = 2 Const TOUCHED_FACEBOOK:Int = 3 Const TOUCHED_MOREGAMES:Int = 4 Const TOUCHED_EXIT:Int = 5 Const TOUCHED_UNPAUSE:Int = 6 Const TOUCHED_QUITYES:Int = 9 Const TOUCHED_QUITNO:Int = 10 Const TOUCHED_PAUSE:Int = 11 Const TOUCHED_SOUND:Int = 12 Const TOUCHED_MUSIC:Int = 14 Const TOUCHED_PLAY:Int = 16 Global SCALE_RATIO_X# Global SCALE_RATIO_Y# Global DevWidth# Global DevHeight# Const FPS = 60 Const VERSION = 1 Const MAPTYPE_WALL = 0 Const MAPTYPE_GRASS = 1 Const MAPTYPE_TREE = 2 Const MAPTYPE_ROCK = 3 Const MAPTYPE_BRUSH = 4 Const MAPTYPE_WATER = 5 Const TILE_SIZE = 128 Class Game Extends App Field gameState:Int = GAME_STATE_LOADING Field gameAtlas:Image Field menuAtlas:Image Field loadAtlas:Image Field loadImage:Image Field pauseImage:Image Field createImage:Image Field sureQuitImage:Image Field yesnoImage:Image Field numberImages:Image Field dtd:Float Field adt:Float Field delta:Float Field loadState:Int = 0 Field dt:MyTimer Field mx:Float Field my:Float Field mSounds:Int = 1 Field mMusic:Int = 1 Field mBestScore:Int = 0 Field mPlayCount:Int = 0 Field mTouching:Bool = False Field mTouched:Int = TOUCHED_NONE Field vfile:VirtualFile Field wasPaused:Bool = False Field player:Actor Field bullet:Actor Field enemy:Actor[100] Field bulletSteps:Int = 0 Field ENEMY_COUNT:Int = 100 Field PLAYER_SPEED:Float = 2 Field i:Int = 0 Field j:Int = 0 Field r:Int = 0 Field c:Int = 0 Field d:Float Field mapWidth:Int = 100 Field mapHeight:Int = 100 Field map:Map[10000] Field mapOffsetX:Float = 0 Field mapOffsetY:Float = 0 Field tmpImage:Image Field mapImages:Image[6] Field lives:Int = 3 Field dead:Bool = False Field hurt:Bool = False Field hurtCounter:Int = 0 Field killCount:Int = 0 Field archer:Image[3] Field feet:Image[4] Field arrow:Image Field feetAnimaaa:Float = 0 Field feetAnim:Int = 0 Field zombie:Image[4] Field enemyAnimaaa:Int = 0 Field score:Int = 0 Field scoreup:Int = 0 Method OnCreate() gameState = GAME_STATE_LOADING loadState = 0 adt = 0 ' separate loading image so we can see something on the screen while assets are being loaded. ' loadAtlas = LoadImage("loadatlas.png",1) ' loadImage = loadAtlas.GrabImage(0,0,1024,768,1,Image.MidHandle) ' res changed SCALE_RATIO_X = DeviceWidth()/WIDTH SCALE_RATIO_Y = DeviceHeight()/HEIGHT Seed = -Int(GetDate[0] + "" + GetDate[1] + "" + GetDate[2] + "" + GetDate[3] + "" + GetDate[4] + "" + GetDate[5] + "" + GetDate[6]) SetUpdateRate FPS dt = New MyTimer() adt = 0 End Method ' Load all the game assets behind a loading screen. Method GS_Loading() If loadState = 0 Then ' load the assets Elseif loadState = 1 Then 'Print "Here" tmpImage = LoadImage("grass.png",1,0) mapImages[MAPTYPE_GRASS] = tmpImage.GrabImage(0,0,128,128,1,Image.MidHandle) tmpImage = LoadImage("rock.png",1,0) mapImages[MAPTYPE_ROCK] = tmpImage.GrabImage(0,0,128,128,1,Image.MidHandle) tmpImage = LoadImage("water.png",1,0) mapImages[MAPTYPE_WATER] = tmpImage.GrabImage(0,0,128,128,1,Image.MidHandle) tmpImage = LoadImage("tree.png",1,0) mapImages[MAPTYPE_TREE] = tmpImage.GrabImage(0,0,200,200,2,Image.MidHandle) tmpImage = LoadImage("brush.png",1,0) mapImages[MAPTYPE_BRUSH] = tmpImage.GrabImage(0,0,128,128,1,Image.MidHandle) tmpImage = LoadImage("archer.png",1,0) archer[0] = tmpImage.GrabImage(0,0,32,32,1,0) archer[1] = tmpImage.GrabImage(32,0,32,32,1,0) feet[0] = tmpImage.GrabImage(0,32,32,32,1,0) ' feet 1 feet[1] = tmpImage.GrabImage(32,32,32,32,1,0) ' feet 2 feet[2] = tmpImage.GrabImage(64,32,32,32,1,0) ' feet 3 feet[3] = tmpImage.GrabImage(96,32,32,32,1,0) ' feet 3 arrow = tmpImage.GrabImage(64,0,32,32,1,0) tmpImage = LoadImage("zombie.png",1,0) zombie[0] = tmpImage.GrabImage(0,0,32,32,1,0) zombie[1] = tmpImage.GrabImage(32,0,32,32,1,0) zombie[2] = tmpImage.GrabImage(64,0,32,32,1,0) zombie[3] = tmpImage.GrabImage(96,0,32,32,1,0) F_ResetVars() loadState = 2 ' draw the assets once Elseif loadState >= 2 Then adt = adt + dtd If adt > 0 Then gameState = GAME_STATE_MENU loadState = 0 adt = 0 End If End If End Method ' Render the loading screen Method GS_Loading_Render() ' Draw assets If loadState = 1 Then 'draw the assets once End If ' Draw a loading screen Cls 0,0,0 'DrawTextNormal "LOADING", WIDTH_HALF, HEIGHT_HALF, 0.5, 0.5 loadState = loadState + 1 End Method ' Show the title or menu screen Method GS_Menu() mTouching = False If TouchDown(0) Then mx = TouchX(0) my = TouchY(0) mx = mx / SCALE_RATIO_X my = my / SCALE_RATIO_Y mTouching=True mTouched = TOUCHED_NONE If mx >= 0 And mx <= 1024 And my >= 0 And my <= 768 Then mTouched = TOUCHED_NEWGAME End If End If If mTouching = False Then If mTouched = TOUCHED_NEWGAME Then gameState = GAME_STATE_LOADGAME End If mTouched = TOUCHED_NONE End If If KeyHit(KEY_SPACE) Then gameState = GAME_STATE_LOADGAME End If 'gameState = GAME_STATE_LOADGAME End Method ' Render the menu screen Method GS_Menu_Render() Cls 0,0,0 DrawTextNormal "*** ONE ARROW - Version 0.1 Beta ***", WIDTH_HALF, HEIGHT_HALF-100, 0.5, 0.5 DrawTextNormal "Game by Ben McGaughey for LudumDare 28, Copyright 2013", WIDTH_HALF, HEIGHT_HALF-80, 0.5, 0.5 DrawTextNormal "You only get 1 arrow to defend yourself against the zombies.", WIDTH_HALF, HEIGHT_HALF-40, 0.5, 0.5 DrawTextNormal "After you shoot your arrow, you have to pick it back up again.", WIDTH_HALF, HEIGHT_HALF-20, 0.5, 0.5 DrawTextNormal "The further away the zombie is when you shoot it, the more points you will get.", WIDTH_HALF, HEIGHT_HALF, 0.5, 0.5 DrawTextNormal "UP Arrow moves you forward. Left and Right Arrows rotate. X or Control Shoot.", WIDTH_HALF, HEIGHT_HALF+40, 0.5, 0.5 DrawTextNormal "CLICK ANYHWERE OR PRESS SPACE TO START", WIDTH_HALF, HEIGHT_HALF+90, 0.5, 0.5 End Method ' Load the game elements, reset the game Method GS_LoadGame() If loadState = 0 Then Elseif loadState >= 1 Then adt = adt + dtd If adt > 1 Then gameState = GAME_STATE_PLAY loadState = 0 adt = 0 End If End If End Method ' Render the load game screen with splash image Method GS_LoadGame_Render() Cls 0,0,0 'DrawTextNormal "LOADING GAME", WIDTH_HALF, HEIGHT_HALF, 0.5, 0.5 loadState = loadState + 1 End Method ' Get Touch Events Method GS_PlayTouch() mTouching = False If TouchDown(0) Then mx = TouchX(0) my = TouchY(0) mx = mx / SCALE_RATIO_X my = my / SCALE_RATIO_Y mTouching=True mTouched = TOUCHED_NONE 'If mx >= 0 And mx <= 1024 And my >= 0 And my <= 768 Then ' mTouched = TOUCHED_PAUSE 'End If End If If KeyHit(KEY_X) Or KeyHit(KEY_CONTROL) Then If bullet.moving=False And bullet.atrest=False Then bullet.x = player.x bullet.y = player.y bulletSteps = 0 bullet.xvel = bullet.speed bullet.yvel = bullet.speed bullet.moving = True End If End If If KeyDown(KEY_P) Then mTouched = TOUCHED_PAUSE mTouching = True Elseif KeyDown(KEY_RIGHT) Then player.rot = player.rot - 3 If player.rot < 0 Then player.rot = player.rot + 360 Elseif KeyDown(KEY_LEFT) Then player.rot = player.rot + 3 If player.rot > 360 Then player.rot = player.rot - 360 End If If bullet.moving=False And bullet.atrest=False Then bullet.rot = player.rot End If If KeyDown(KEY_UP) Then Local moveX:Float = Sin(-player.rot) * PLAYER_SPEED Local moveY:Float = (-Cos(-player.rot)) * PLAYER_SPEED player.x = player.x + moveX; player.y = player.y + moveY; Local playerCell:Int Local dontmove:Bool = False playerCell = (((Floor(player.y / TILE_SIZE)+1) * 100)) + Floor(player.x / TILE_SIZE)+1 If map[playerCell].type=MAPTYPE_ROCK Or map[playerCell].type=MAPTYPE_WATER Or map[playerCell].type=MAPTYPE_WALL Then Local hardHit:Bool = False ' Print Int(player.x) + ", " + Int(player.y) + " and " + map[playerCell].x + ", " + map[playerCell].y ' check to see if we are close or ON the obstacle If player.x > map[playerCell].x+10 And player.x < map[playerCell].x+118 And player.y > map[playerCell].y+10 And player.y < map[playerCell].y+118 Then hardHit = True End If If hardHit=True Then player.x = player.x - moveX; moveX = 0 player.y = player.y - moveY; moveY = 0 dontmove = True End If End If mapOffsetX = mapOffsetX - moveX mapOffsetY = mapOffsetY - moveY If dontmove=False And bullet.moving=False And bullet.atrest=False Then bullet.x = bullet.x + Sin(-bullet.rot) * PLAYER_SPEED; bullet.y = bullet.y + (-Cos(-bullet.rot)) * PLAYER_SPEED; End If F_CheckCollision(player,bullet,True) feetAnimaaa = feetAnimaaa + 1 If feetAnimaaa > 6 Then feetAnim = feetAnim + 1 If feetAnim > 3 Then feetAnim = 0 End If feetAnimaaa = 0 End If ' Print playerCell + ", " + map[playerCell].type End If If mTouching = False Then If mTouched = TOUCHED_PAUSE Then gameState = GAME_STATE_PAUSED End If mTouched = TOUCHED_NONE End If End Method ' Play the game Method GS_Play() If dead=False Then If hurt=False then GS_PlayTouch() End If ' move the arrow If bullet.moving=True And bullet.atrest=False Then bullet.x = bullet.x + Sin(-bullet.rot) * bullet.xvel; bullet.y = bullet.y + -Cos(-bullet.rot) * bullet.yvel; Local bulletCell:Int Local dontmove:Bool = False bulletCell = (((Floor(bullet.y / TILE_SIZE)+1) * 100)) + Floor(bullet.x / TILE_SIZE)+1 If map[bulletCell].type=MAPTYPE_ROCK Or map[bulletCell].type=MAPTYPE_WALL Then Local hardHit:Bool = False ' Print Int(player.x) + ", " + Int(player.y) + " and " + map[playerCell].x + ", " + map[playerCell].y ' check to see if we are close or ON the obstacle If bullet.x > map[bulletCell].x+7 And bullet.x < map[bulletCell].x+121 And bullet.y > map[bulletCell].y+7 And bullet.y < map[bulletCell].y+121 Then hardHit = True End If If map[bulletCell].type=MAPTYPE_WALL Or hardHit=True Then bullet.x = bullet.x - Sin(-bullet.rot) * bullet.xvel; bullet.y = bullet.y - -Cos(-bullet.rot) * bullet.yvel; bulletSteps = 45 dontmove = True End If End If bulletSteps = bulletSteps + 1 ' If bullet.x < 64 Or bullet.x > 960 Or bullet.y < 64 Or bullet.y > 704 Then If bulletSteps > 45 Then bulletSteps = 0 bullet.xvel = 0 bullet.yvel = 0 bullet.moving = False bullet.atrest = True End If End If Local okUpdateEnemyFrame:Bool = False enemyAnimaaa = enemyAnimaaa + 1 If enemyAnimaaa > 6 Then okUpdateEnemyFrame = True enemyAnimaaa = 0 End If For i = 0 To ENEMY_COUNT-1 If enemy[i].isdead=False Then If hurt=False And enemy[i].dontrot = 0 Then enemy[i].rot = (180+ATan2(player.x-enemy[i].x, player.y-enemy[i].y))-180 End If If enemy[i].dontrot > 0 Then enemy[i].dontrot = enemy[i].dontrot - 1 If enemy[i].dontrot < 0 Then enemy[i].dontrot = 0 End If Local moveX:Float = Sin(-enemy[i].rot) * enemy[i].speed Local moveY:Float = (-Cos(-enemy[i].rot)) * enemy[i].speed enemy[i].x = enemy[i].x - moveX; enemy[i].y = enemy[i].y - moveY; Local enemyCell:Int Local dontmove:Bool = False enemyCell = (((Floor(enemy[i].y / TILE_SIZE)+1) * 100)) + Floor(enemy[i].x / TILE_SIZE)+1 If map[enemyCell].type=MAPTYPE_ROCK Or map[enemyCell].type=MAPTYPE_WATER Or map[enemyCell].type=MAPTYPE_WALL Then Local hardHit:Bool = False ' check to see if we are close or ON the obstacle If enemy[i].x > map[enemyCell].x+10 And enemy[i].x < map[enemyCell].x+118 And enemy[i].y > map[enemyCell].y+10 And enemy[i].y < map[enemyCell].y+118 Then hardHit = True enemy[i].rot = enemy[i].rot + 180 enemy[i].dontrot = 90 End If If map[enemyCell].type=MAPTYPE_WALL Or hardHit=True Then enemy[i].x = enemy[i].x + moveX; enemy[i].y = enemy[i].y + moveY; dontmove = True End If End If 'Else ' ' enemy[i].x = (enemy[i].x - Sin(-enemy[i].rot) * enemy[i].speed) ; ' enemy[i].y = (enemy[i].y - (-Cos(-enemy[i].rot)) * enemy[i].speed) ; ' 'End If If okUpdateEnemyFrame = True Then enemy[i].onFrame = enemy[i].onFrame + 1 If enemy[i].onFrame > 3 Then enemy[i].onFrame = 0 End If End If ' Print enemy[i].x + ", " + enemy[i].y If hurt = False Then If enemy[i].x >= player.x-10 And enemy[i].x <= player.x+10 And enemy[i].y >= player.y-10 And enemy[i].y <= player.y+10 Then lives = lives - 1 If lives < 1 Then dead = True Else For j = 0 To ENEMY_COUNT - 1 If enemy[j].isdead=False Then enemy[j].rot = (180+ATan2(player.x-enemy[i].x, player.y-enemy[i].y))-Rnd(-30,30) End If Next j hurt = True hurtCounter = 0 End If End If End If End If Next i hurtCounter = hurtCounter + 1 If hurtCounter > 240 Then hurt = False End if F_CheckBulletCollision() Else If KeyHit(KEY_SPACE) Or TouchDown(0) Then F_ResetVars() End If End If End Method ' Render the game Method GS_Play_Render() Cls 0, 60, 0 ' Draw dead enemies Local startCol = Int(player.x/128)-4 If startCol < 0 Then startCol = 0 Local endCol = startCol + 10 If endCol > 99 Then endCol = 99 Local startRow = Int(player.y/128)-4 If startRow < 0 Then startRow = 0 Local endRow = startRow + 9 If endRow > 99 Then endRow = 99 'Print startCol + ", " + endCol + " and " + startRow + ", " + endRow 'Print Int(player.x / 128) SetColor 255,255,255 i = 0 For r = startRow To endRow For c = startCol To endCol i = (r * 100) + c if map[i].type = MAPTYPE_GRASS Then SetColor 255,255,255 DrawImage mapImages[MAPTYPE_GRASS], (c * TILE_SIZE)+mapOffsetX-64, (r * TILE_SIZE)+mapOffsetY-64, 0, 1, 1, 0 End If If map[i].type=MAPTYPE_WALL Then SetColor 40,40,40 DrawRect (r * TILE_SIZE)+mapOffsetX, (c * TILE_SIZE)+mapOffsetY, TILE_SIZE, TILE_SIZE End If if map[i].type = MAPTYPE_BRUSH Then DrawImage mapImages[MAPTYPE_BRUSH], (c * TILE_SIZE)+mapOffsetX-64, (r * TILE_SIZE)+mapOffsetY-64, 0, 1, 1, 0 End If Next c Next r SetColor 255,255,255 i = 0 For r = startRow To endRow For c = startCol To endCol i = (r * 100) + c If map[i].type = MAPTYPE_TREE Then DrawImage mapImages[MAPTYPE_TREE], (c * TILE_SIZE)+mapOffsetX-64, (r * TILE_SIZE)+mapOffsetY-64, 0, 1, 1, 0 End If Next c Next r i = 0 For r = startRow To endRow For c = startCol To endCol 'If c > startCol And c < endCol And r > startRow And r < endRow then i = (r * 100) + c If map[i].type=MAPTYPE_WALL Then SetColor 40,40,40 DrawRect (r * TILE_SIZE)+mapOffsetX, (c * TILE_SIZE)+mapOffsetY, TILE_SIZE, TILE_SIZE End If SetColor 255,255,255 if map[i].type = MAPTYPE_ROCK Then DrawImage mapImages[MAPTYPE_ROCK], (c * TILE_SIZE)+mapOffsetX-64, (r * TILE_SIZE)+mapOffsetY-64, 0, 1, 1, 0 Elseif map[i].type = MAPTYPE_WATER Then DrawImage mapImages[MAPTYPE_WATER], (c * TILE_SIZE)+mapOffsetX-64, (r * TILE_SIZE)+mapOffsetY-64, 0, 1, 1, 0 End If 'End If Next c Next r SetColor 40,40,40 For i = 0 To ENEMY_COUNT-1 If enemy[i].isdead=True Then PushMatrix Translate enemy[i].x+mapOffsetX, enemy[i].y+mapOffsetY Rotate enemy[i].rot DrawImage zombie[enemy[i].onFrame], -(enemy[i].width/2), -(enemy[i].height/2), 0, 1, 1 'DrawRect -(enemy[i].width/2), -(enemy[i].height/2), enemy[i].width, enemy[i].height 'DrawRect -(enemy[i].width/2), -(enemy[i].height/2), enemy[i].width, enemy[i].height/4 PopMatrix End If Next i SetColor 255,255,255 ' draw player PushMatrix Translate player.x+mapOffsetX, player.y+mapOffsetY Rotate player.rot DrawImage feet[feetAnim], -(player.width/2),-(player.height/2), 0, 1, 1 DrawImage archer[0], -(player.width/2),-(player.height/2), 0, 1, 1 PopMatrix PushMatrix Translate bullet.x+mapOffsetX, bullet.y+mapOffsetY Rotate bullet.rot DrawImage arrow, -(bullet.width/2),-(bullet.height/2),0,1,1 PopMatrix PushMatrix Translate player.x+mapOffsetX, player.y+mapOffsetY Rotate player.rot DrawImage archer[1], -(player.width/2),-(player.height/2), 0, 1, 1 PopMatrix ' draw the... uhm.... alive zombies SetColor 255,255,255 For i = 0 To ENEMY_COUNT-1 If enemy[i].isdead=False Then PushMatrix Translate enemy[i].x+mapOffsetX, enemy[i].y+mapOffsetY Rotate enemy[i].rot DrawImage zombie[enemy[i].onFrame], -(enemy[i].width/2), -(enemy[i].height/2), 0, 1, 1 PopMatrix End If Next i SetColor 255,255,255 i = 0 SetAlpha 0.9 For r = startRow To endRow For c = startCol To endCol i = (r * 100) + c If map[i].type = MAPTYPE_TREE Then DrawImage mapImages[MAPTYPE_TREE], (c * TILE_SIZE)+mapOffsetX-64, (r * TILE_SIZE)+mapOffsetY-64, 0, 1, 1, 1 End If Next c Next r SetAlpha 1 PushMatrix Scale 2,2 DrawTextNormal "KILLS: "+killCount +" OF " + ENEMY_COUNT + " SCORE: " + score, 10,10 PopMatrix If bullet.atrest=True Then PushMatrix Translate bullet.x+mapOffsetX, bullet.y+mapOffsetY Rotate bullet.rot DrawImage arrow, -(bullet.width/2),-(bullet.height/2),0,1,1 PopMatrix End If If dead=True Then PushMatrix Scale 2,2 SetColor 0,0,0 DrawTextNormal "YOU ARE DEAD", WIDTH_HALF/2,(HEIGHT_HALF/2)+12, 0.5, 0.5 SetColor 255,0,0 DrawTextNormal "YOU ARE DEAD", WIDTH_HALF/2,(HEIGHT_HALF/2)+10,0.5,0.5 SetColor 0,0,0 DrawTextNormal "PRESS SPACE TO RESTART", WIDTH_HALF/2,(HEIGHT_HALF/2)+32, 0.5, 0.5 SetColor 255,0,0 DrawTextNormal "PRESS SPACE TO RESTART", WIDTH_HALF/2,(HEIGHT_HALF/2)+30, 0.5, 0.5 SetColor 255,255,255 PopMatrix End If ' DrawTextNormal "PLAY", WIDTH_HALF, HEIGHT_HALF, 0.5, 0.5 End Method ' Ask the player if they are sure they want to quit. Method GS_SureQuit() End Method ' Render the ask to quit screen Method GS_SureQuit_Render() End Method ' Show the Pause screen, get input Method GS_Paused() mTouching = False If TouchDown(0) Then mx = TouchX(0) my = TouchY(0) mx = mx / SCALE_RATIO_X my = my / SCALE_RATIO_Y mTouching=True mTouched = TOUCHED_NONE 'If mx >= 0 And mx <= 1024 And my >= 0 And my <= 768 Then ' mTouched = TOUCHED_PAUSE 'End If End If If KeyDown(KEY_P) Then mTouched = TOUCHED_PAUSE mTouching = True End If If mTouching = False Then If mTouched = TOUCHED_PAUSE Then gameState = GAME_STATE_PLAY End If mTouched = TOUCHED_NONE End If End Method ' Render the paused screen Method GS_Paused_Render() Cls 100, 50, 200 DrawTextNormal "PAUSED", WIDTH_HALF, HEIGHT_HALF, 0.5, 0.5 End Method ' Show the game over screen Method GS_GameOver() End Method ' Render the Game Over Screen Method GS_GameOver_Render() End Method Method F_ResetVars() lives = 1 score = 0 hurt = False dead = False killCount = 0 ' 512, 384 player = New Actor(((TILE_SIZE * 100) / 2)+400,((TILE_SIZE * 100) / 2)+300,32,32,0,PLAYER_SPEED) bullet = New Actor(((TILE_SIZE * 100) / 2)+400,((TILE_SIZE * 100) / 2)+300,32,32,0,10) mapOffsetX = -(TILE_SIZE * 100) / 2 mapOffsetY = -(TILE_SIZE * 100) / 2 For i = 0 To ENEMY_COUNT-1 enemy[i] = New Actor(Rnd(250,(TILE_SIZE * 100) - 250),Rnd(250,(TILE_SIZE * 100) - 250),32,32,0,Rnd(5,15)*0.1) Next i i = 0 For r = 0 To 99 For c = 0 to 99 map[i] = New Map() map[i].col = c map[i].row = r map[i].x = (c * TILE_SIZE)-128 map[i].y = (r * TILE_SIZE)-128 If r = 0 Or r = 99 Then map[i].type = MAPTYPE_WALL Elseif c = 0 Or c = 99 Then map[i].type = MAPTYPE_WALL Else If (Rnd(1,100)<50) Then map[i].type = MAPTYPE_TREE Elseif (Rnd(1,100)<50) Then map[i].type = MAPTYPE_GRASS Else map[i].type = Rnd(1,6) End If End If i = i + 1 Next c Next r Local playerCell:Int Local dontmove:Bool = False playerCell = (((Floor(player.y / TILE_SIZE)+1) * 100)) + Floor(player.x / TILE_SIZE)+1 map[playerCell].type = MAPTYPE_GRASS map[playerCell-1].type = MAPTYPE_GRASS map[playerCell+1].type = MAPTYPE_GRASS map[playerCell+99].type = MAPTYPE_GRASS map[playerCell+100].type = MAPTYPE_GRASS map[playerCell+101].type = MAPTYPE_GRASS map[playerCell-99].type = MAPTYPE_GRASS map[playerCell-100].type = MAPTYPE_GRASS map[playerCell-101].type = MAPTYPE_GRASS For i = 0 To ENEMY_COUNT-1 playerCell = (((Floor(enemy[i].y / TILE_SIZE)+1) * 100)) + Floor(enemy[i].x / TILE_SIZE)+1 If playerCell >= 0 And playerCell <= 9999 Then map[playerCell].type = MAPTYPE_GRASS End If If playerCell-1 >= 0 And playerCell-1 <= 9999 Then map[playerCell-1].type = MAPTYPE_GRASS End If If playerCell+1 >= 0 And playerCell+1 <= 9999 Then map[playerCell+1].type = MAPTYPE_GRASS End If If playerCell+100 >= 0 And playerCell+100 <= 9999 Then map[playerCell+100].type = MAPTYPE_GRASS End If If playerCell-100 >= 0 And playerCell-100 <= 9999 Then map[playerCell-100].type = MAPTYPE_GRASS End If Next i End Method Method F_CheckBulletCollision() If bullet.atrest = False And bullet.moving=True Then For j = 0 To ENEMY_COUNT - 1 If Not enemy[j].isdead then d = Sqrt((((bullet.x)-(enemy[j].x))*((bullet.x)-(enemy[j].x)))+(((bullet.y)-(enemy[j].y))*((bullet.y)-(enemy[j].y)))); If d < 20 Then score = score + (bulletSteps*bulletSteps) killCount= killCount + 1 enemy[j].isdead=True bulletSteps = 0 bullet.xvel = 0 bullet.yvel = 0 bullet.atrest = True bullet.moving = False Exit End If End If Next j End If End Method Method F_CheckCollision(actor1:Actor,actor2:Actor,radial:Bool) If radial = True Then If bullet.atrest=True Then d = Sqrt((((actor2.x)-(actor1.x))*((actor2.x)-(actor1.x)))+(((actor2.y)-(actor1.y))*((actor2.y)-(actor1.y)))); If (d<30) Then bullet.x = player.x bullet.y = player.y bulletSteps = 0 bullet.xvel = 0 bullet.yvel = 0 bullet.atrest = False bullet.moving = False End If End If End If End Method ' We always have to update our time... ' dtd is used to increment timers I'm checking. Method F_UpdateTime() delta = dt.UpdateDelta dtd = dt.delta End Method ' When the back button is pressed, or ESC is pressed Method OnBack() If gameState = GAME_STATE_LOADING Then ' Nothing Elseif gameState = GAME_STATE_MENU Then Error "" Elseif gameState = GAME_STATE_LOADGAME Then ' Nothing Elseif gameState = GAME_STATE_SUREQUIT Then If wasPaused = True Then gameState = GAME_STATE_PAUSED Else gameState = GAME_STATE_PLAY End If Elseif gameState = GAME_STATE_PLAY Then gameState = GAME_STATE_PAUSED Elseif gameState = GAME_STATE_PAUSED Then gameState = GAME_STATE_PLAY End If End Method ' Update the game Method OnUpdate() F_UpdateTime() ' kind-of an override for the back button when on a PC If KeyHit(KEY_ESCAPE) Then OnBack() End If ' The core elements I add to any new game If gameState = GAME_STATE_LOADING Then GS_Loading() Elseif gameState = GAME_STATE_MENU Then GS_Menu() Elseif gameState = GAME_STATE_LOADGAME Then GS_LoadGame() Elseif gameState = GAME_STATE_SUREQUIT Then GS_SureQuit() Elseif gameState = GAME_STATE_PLAY Then GS_Play() Elseif gameState = GAME_STATE_PAUSED Then GS_Paused() Elseif gameState = GAME_STATE_GAMEOVER Then GS_GameOver() End If End Method ' Render the game Method OnRender() ' Scale to the screen size in case it changes 'PushMatrix() 'Scale SCALE_RATIO_X, SCALE_RATIO_Y Cls 0,0,0 ' How we render... If gameState = GAME_STATE_LOADING Then GS_Loading_Render() Elseif gameState = GAME_STATE_MENU Then GS_Menu_Render() Elseif gameState = GAME_STATE_LOADGAME Then GS_LoadGame_Render() Elseif gameState = GAME_STATE_SUREQUIT Then GS_SureQuit_Render() Elseif gameState = GAME_STATE_PLAY Then GS_Play_Render() Elseif gameState = GAME_STATE_GAMEOVER Then GS_GameOver_Render() Elseif gameState = GAME_STATE_PAUSED Then GS_Paused_Render() End If 'PopMatrix() End Method End Class Class Map Field col:Int Field row:Int Field type:Int Field x:Int Field y:Int Method New() End Method End Class Class Actor Field x:Float Field y:Float Field worldX:Float Field worldY:Float Field xvel:Float Field yvel:Float Field rot:Float Field width:Int Field height:Int Field moving:Bool Field atrest:Bool Field isdead:Bool Field speed:Float Field runawaystep:Int Field onFrame:Int = 0 Field dontrot:Int = 0 Method New(nx:Float,ny:Float,w:Int,h:Int,nrot:Float,nspeed:Float) x = nx y = ny worldX = 3200 ' 64 * 100 / 2 worldY = 3200 width = w height = h xvel = 0 yvel = 0 speed = nspeed runawaystep = 15 moving = False atrest = False isdead = false rot = nrot onFrame = 0 dontrot = 0 End Method End Class Class VirtualFile Field FILE_VER:String = "1" Method New() End Method Method F_LoadOptions() Local str:String = "" Local sndstr:String = "" Local hasState:Bool = False Local propsData3:String[] = [] Local propsData4:String[] = [] SoundSetting = Int(F_LoadVFile("SOUND","1")) MusicSetting = Int(F_LoadVFile("MUSIC","1")) End Method Method F_LoadVFile:String(filename:String, defaultstr:String="", parseStr:String="") Local str:String = "" Local tmpstr:String = "" Local bFoundStr:Bool = False Local propsData1:String[] = [] Local propsData2:String[] = [] If parseStr="" Then str = LoadState() Else str = parseStr End If tmpstr = "" propsData1 = str.Split("!") For Local pi:Int = 0 To propsData1.Length-1 propsData2 = propsData1[pi].Split("@") If propsData2[0] = filename Then tmpstr = propsData2[1] bFoundStr = True End If Next For If bFoundStr = False Then tmpstr = defaultstr F_SaveVFile(filename, defaultstr) End If Return tmpstr End Method Method F_SaveVFile(filename:String, fstr:String) Local str:String = "" Local tmpstr:String = "" Local bFoundStr:Bool = False Local propsData1:String[] = [] Local propsData2:String[] = [] str = LoadState() tmpstr = "empty"+FILE_VER propsData1 = str.Split("!") For Local pi:Int = 0 To propsData1.Length-1 propsData2 = propsData1[pi].Split("@") If propsData2[0] = filename Then tmpstr = tmpstr + "!" + propsData2[0] + "@" + fstr bFoundStr = True Else If propsData1[pi]<>"empty"+FILE_VER Then tmpstr = tmpstr + "!" + propsData1[pi] End If End If Next For If bFoundStr = False Then tmpstr = tmpstr + "!" + filename + "@" + fstr End If tmpstr = tmpstr + "!empty"+FILE_VER SaveState(tmpstr) End Method Method F_EraseVFile:String(filename:String) Local str:String = "" Local tmpstr:String = "" Local bFoundStr:Bool = False Local propsData1:String[] = [] Local propsData2:String[] = [] str = LoadState() tmpstr = "empty"+FILE_VER propsData1 = str.Split("!") For Local pi:Int = 0 To propsData1.Length-1 propsData2 = propsData1[pi].Split("@") If propsData2[0] = filename Then bFoundStr = True Else tmpstr = tmpstr + "!" + propsData1[pi] End If Next For tmpstr = tmpstr + "!empty"+FILE_VER SaveState(tmpstr) Return tmpstr End Method Method F_EmptyVFile() SaveState("empty!empty!") End Method Method F_CheckVFile() Local tmpstr:String Local propsData:String[] = [] tmpstr = LoadState() propsData = tmpstr.Split("!") If propsData[0]="empty"+FILE_VER Then ' we have done this before :) Else F_EmptyVFile() ' clear the whole thing End If End Method End Class Function OpenBrowser(which:String) OpenUrl which End Function Class MyTimer Field targetfps:Float = 60 Field currentticks:Float Field lastticks:Float Field frametime:Float Field delta:Float Field dfps:Float Method New () lastticks = Millisecs dfps = (1000.0 / targetfps) End Method UpdateDelta () currentticks = Millisecs frametime = currentticks - lastticks lastticks = currentticks delta = frametime / dfps Return delta End End Function Main() New Game End Function