: TExplosion; begin explostion := TExplosion.Create(fRenderer); explostion.Sprite.Texture.Assign(fTextures[Ord(TSpriteKind.Explosion)]); explostion.Sprite.InitFrames(1,1); explostion.Position := Position; fExplosions.Add(explostion); end;begin if ( Sender is TShot ) then begin shot := TShot(Sender); if (Suspect is TEnemy) and (TEnemy(Suspect).HP > 0) then begin enemy := TEnemy(Suspect); enemy.Hit( 1 ); Mix_PlayChannel(-1, fSounds[ Ord(TSoundKind.sndEnemyHit) ], 0); if enemy.Alive then Inc(fScore, 10) else begin Inc(fScore, 100); CreateExplosion(enemy.Position); end; fShots.Remove( shot ); StopChecking := true; exit; end; if ( Suspect is TPlayer ) then begin fPlayer.Hit( 1 ); CreateExplosion(TPlayer(Suspect).Position); Mix_PlayChannel(-1, fSounds[ Ord(TSoundKind.sndEnemyHit) ], 0); fShots.Remove( shot ); end; end;end;Simples nao? Mas faz uma diferenca e tanto!Com a soma destas pequenas mudancas, o game ja esta bem mais interessante. Para finalizar este artigo, vamos adicionar duas novas caracteristicas. Uma tela de Game Over e a capacidade de pausar/retomar o game.Estados do GameGame exibindo a tela de pause/resumeAte agora o jogo nao pode perdido, nao pode ser ganho nem pode ser pausado. Se pararmos pra pensar, veremos que estes sao estados fundamentais de qualquer jogo, mas ate agora so temos um: o estado em que o game se encontra quando e possivel joga-lo.Vamos introduzir uma maquina de estados no nivel de TGame para implementar ostes estados essenciais e alterar alguns metodos para serem executados ou nao de acordo ela.O metodo mais facil de implementar e pause. Quando o game estiver pausado, o estado dos objetos nao e atualizado ou seja, nenhum TGameObject.Update deve ser chamado, mas as rotinas de renderizacao continuam com seu fluxo normal. Vamos utilizar tanto a tecla quanto o botao do joystick para pausar e retomar o game.Declare uma variavel privada do tipo TGameState em TGame e inicialize-a com TGameState.Playing. Em seguida, vamos alterar o estado do jogo em resposta aos comando de pausa/retorno alterando a funcao TGame.HandleEvents. Note que tambem vamos tocar um som em resposta a esta mudanca de status. TGameState = ( Playing, Paused, GameOver );(...)procedure TGame.HandleEvents;var event : TSDL_Event;begin while SDL_PollEvent( @event ) = 1 do begin case event.type_ of SDL_QUITEV : fRunning := false; SDL_KEYDOWN : case event.key.keysym.sym of //player controls SDLK_LEFT, SDLK_A : fPlayer.Input[Ord(TPlayerInput.Left)] := true; SDLK_RIGHT, SDLK_D : fPlayer.Input[Ord(TPlayerInput.Right)]:= true; SDLK_SPACE : fPlayer.Input[Ord(TPlayerInput.Shot)] := true; SDLK_p : ScreenShot; SDLK_g : SetDebugView( not fDebugView ); SDLK_ESCAPE : fRunning := false; end; SDL_KEYUP : case event.key.keysym.sym of //player controls SDLK_LEFT, SDLK_A : fPlayer.Input[Ord(TPlayerInput.Left)] := false; SDLK_RIGHT, SDLK_D : fPlayer.Input[Ord(TPlayerInput.Right)]:= false; SDLK_SPACE : fPlayer.Input[Ord(TPlayerInput.Shot)] := false; SDLK_f: ToggleFullScreen; SDLK_o: begin fGameState := TGameState.GameOver; Mix_PlayChannel(0, fSounds[ Ord(TSoundKind.sndGameOver) ], 0); end; SDLK_r: StartNewGame; //reset the game SDLK_RETURN : begin case fGameState of TGameState.Paused : begin fGameState:= TGameState.Playing; Mix_PlayChannel(-1, fSounds[ Ord(TSoundKind.sndGameResume) ], 0); end; TGameState.Playing : begin fGameState:= TGameState.Paused; Mix_PlayChannel(-1, fSounds[ Ord(TSoundKind.sndGamePause) ], 0); end; TGameState.GameOver: StartNewGame; end; end; end; SDL_JOYAXISMOTION : case event.jaxis.axis of //X axis motion 0 : begin fPlayer.Input[Ord(TPlayerInput.Left)] := false; fPlayer.Input[Ord(TPlayerInput.Right)] := false; if event.jaxis.value > 0 then fPlayer.Input[Ord(TPlayerInput.Right)] := true else if event.jaxis.value < 0 then fPlayer.Input[Ord(TPlayerInput.Left)] := true end; end; SDL_JOYBUTTONUP : case event.jbutton.button of 0, 1, 2, 3 : fPlayer.Input[Ord(TPlayerInput.Shot)] := false; 9: // 9 for stard button //http://wiki.gp2x.org/articles/s/d/l/SDL_Joystick_mapping.html begin case fGameState of TGameState.Paused : begin fGameState:= TGameState.Playing; Mix_PlayChannel(-1, fSounds[ Ord(TSoundKind.sndGameResume) ], 0); end; TGameState.Playing :