outros.Implementar a primeira condicao e facil. Vamos criar uma variavel privada em TEnemy para armazenar o tempo que o ultimo teste de probabilidade foi realizado e, dentro do metodo update, utilizaremos este valor para saber quando podemos "jogar os dados" e verificar se o inimigo ira atirar.Chamaremos esta variavel de fLastShotIteration e a inicializaremos com 0 em TEnemy.InitFields.Veja como ficou a versao final do metodo.procedure TEnemy.Update(const deltaTime : real);const OFFSET_X = 3 * DEBUG_CELL_SIZE; OFFSET_Y = DEBUG_CELL_SIZE div 2;var currTicks : UInt32; deltaX : real; limitX : real; deltaY : real; limitY : real; procedure CalcXParams( aDirection : TEnemyMoveDirection ); inline; begin deltaX := Abs(Position.X - fMovementOrigin.X); case aDirection of TEnemyMoveDirection.Right : limitX := fMovementOrigin.X + OFFSET_X; TEnemyMoveDirection.Left : limitX := fMovementOrigin.X - OFFSET_X; end; end; procedure CalcYParams; inline; begin deltaY := Abs(Position.Y - fMovementOrigin.Y); limitY := fMovementOrigin.Y + OFFSET_Y; end; procedure ChangeDirection( aDirection : TEnemyMoveDirection ); inline; begin fOldMoveDirection := fMoveDirection; fMoveDirection:= aDirection; end;begin if Assigned( Sprite ) then Sprite.Update(deltaTime); if fCanShot and Alive then begin currTicks:= SDL_GetTicks; if (currTicks - fLastShotIteration >= SHOT_DELAY) then begin if Random(100) <= 10 then begin if Assigned(fOnShot) then fOnShot(Self); end; fLastShotIteration:= currTicks; end; end; if ( fMoveDirection <> TEnemyMoveDirection.None ) then begin case fMoveDirection of TEnemyMoveDirection.Left : begin CalcXParams( TEnemyMoveDirection.Left ); Position.X -= fSpeed * deltaTime; if ( Position.X < limitX ) then Position.X := limitX; if ( deltaX = OFFSET_X ) then begin fMovementOrigin := Position; ChangeDirection( TEnemyMoveDirection.Down ); end; end; TEnemyMoveDirection.Right : begin CalcXParams( TEnemyMoveDirection.Right ); Position.X += fSpeed * deltaTime; if ( Position.X > limitX ) then Position.X := limitX; if ( deltaX = OFFSET_X ) then begin fMovementOrigin := Position; ChangeDirection( TEnemyMoveDirection.Down ); end; end; TEnemyMoveDirection.Down : begin CalcYParams; Position.Y += fSpeed * deltaTime; if ( Position.Y > limitY ) then Position.Y := limitY; if ( deltaY = OFFSET_Y ) then begin fMovementOrigin := Position; if ( fOldMoveDirection = TEnemyMoveDirection.Left ) then ChangeDirection( TEnemyMoveDirection.Right ) else ChangeDirection( TEnemyMoveDirection.Left ); end; end; end; end;end;A cada intervalo de tempo definida em SHOT_DELAY, verificamos se o inimigo pode atirar atraves de fCanShot e, se puder, testamos um numero aleatorio num range de 100 numeros e verificamos, em seguida, se ele e menor ou igual a 10. Isto nos diz que ha 10% de chance de um inimigo vivo disparar o evento OnShot a cada SHOT_DELAYms.Otimo, mas como vimos acima, somente os inimigos que nao possuem nenhum alienigena abaixo de si podem atirar para nao correr o risco de criar fogo amigo. Como a classe TEnemy nao sabe nada sobre outros inimigos, o melhor lugar para implementarmos esta logica e em TEnemyList que mantem uma lista muito bem organizada de todos os inimigos do jogo.procedure TEnemyList.Update(const deltaTime: real);var i: integer; enemy : TEnemy; linha: integer;begin inherited Update(deltaTime); //so pode atirar se nao houver nenhum outro inimigo na linha de tiro for i:=0 to Pred(Self.Count) do begin enemy:= TEnemy(Self.Items[i]); linha := i div 20; enemy.CanShot := linha = 5; if linha < 5 then case linha of 0: enemy.CanShot := (not TEnemy(Self.Items[i+20]).Alive) and (not TEnemy(Self.Items[i+40]).Alive) and (not TEnemy(Self.Items[i+60]).Alive) and (not TEnemy(Self.Items[i+80]).Alive) and (not TEnemy(Self.Items[i+100]).Alive); 1: