This is another example creating a three layer space game with a few lines of code:
unit Game;
interface
uses
BB.Screen, BB.Screen.Sprites, BB.Input, BB.Screen.Engines, BB.Game,
BB.Screen.Interfaces, BB.Screen.Types, BB.Colors, BB.Sound;
type
TWave = class(T2DGame)
private
FBack1,
FBack2,
FBack3: TBackground;
FShip: TAnimationSprite;
FExplosion: ISound;
procedure HandleShip;
procedure HandleEnemies;
procedure Fire;
protected
procedure Update(aEllapsedTime: Int64); override;
procedure Draw(aEllapsedTime: Int64); override;
procedure Initialize; override;
procedure Uninitialize; override;
end;
TGameSprite = class(TAnimationSprite)
protected
function Game: IGame;
end;
TEnemy1 = class(TGameSprite)
end;
TShoot = class(TGameSprite)
public
function Render: integer; override;
end;
THero = class(TGameSprite)
public
function Render: integer; override;
end;
implementation
{ TShoot }
function TShoot.Render: integer;
var
i, x, y: integer;
explosion: TGameSprite;
Enemy1: ISprite;
begin
result := inherited Render;
for i := 0 to Engine.Count - 1 do
begin
enemy1 := Engine[i];
if (enemy1 is TEnemy1) and (Collision(enemy1, x, y)) then
begin
Game.CreateThreadedSound('explosion').Run;
explosion := TGameSprite.Create;
explosion.Engine := Engine;
explosion.AnimationName := 'explosion';
explosion.CenterFrom(TSimpleSprite(Enemy1));
Die;
Enemy1.Die;
end;
end;
end;
{ THero }
function THero.Render: integer;
var
enemy1: ISprite;
x, y, i: integer;
explosion: TGameSprite;
begin
result := inherited;
for i := 0 to Engine.Count - 1 do
begin
enemy1 := Engine[i];
if (enemy1 is TEnemy1) and (Collision(enemy1, x, y)) then
begin
Game.CreateThreadedSound('explosion').Run;
explosion := TGameSprite.Create;
explosion.Engine := Engine;
explosion.AnimationName := 'explosion';
explosion.CenterFrom(TSimpleSprite(Enemy1));
Enemy1.Die;
end;
end;
end;
{ TWave }
procedure TWave.Draw(aEllapsedTime: Int64);
begin
FBack3.Render;
FBack2.Render;
FBack1.Render;
inherited;
end;
procedure TWave.HandleEnemies;
const
ENEMY1_SPEED = 3;
ENEMY1_ALIVE = 2;
var
enemy1: TAnimationSprite;
i: integer;
begin
if Random(100) = 73 then
begin
for i := 1 to 10 do
begin
enemy1 := TEnemy1.Create;
enemy1.Engine := Engines[0];
enemy1.AnimationName := 'enemy1';
enemy1.VerticalSpeed := ENEMY1_SPEED;
enemy1.X := GraphicsInfo.GetWidth div 10 * i;
enemy1.Y := -enemy1.Height;
enemy1.TimeOut := GraphicsInfo.GetMaxFPS * ENEMY1_ALIVE;
enemy1.CollisionShape := csAuto;
if Random(2) = 1 then
enemy1.AngleSpeed := 0.5
else
enemy1.AngleSpeed := -0.5;
end;
end;
end;
procedure TWave.HandleShip;
const
SHIP_SPEED = 2; //Seconds
begin
FShip.AnimationName := 'main';
if Input.Keyboard[DIK_LEFT] then
begin
FShip.AnimationName := 'main_left';
FShip.MoveLeft(SHIP_SPEED, True);
end;
if Input.Keyboard[DIK_RIGHT] then
begin
FShip.AnimationName := 'main_right';
FShip.MoveRight(SHIP_SPEED, True);
end;
if Input.Keyboard[DIK_UP] then
FShip.MoveUp(SHIP_SPEED, True);
if Input.Keyboard[DIK_DOWN] then
FShip.MoveDown(SHIP_SPEED, True);
if (Input.Keyboard[DIK_Z]) and (GraphicsInfo.GetTotalFrames mod 7 = 0) then
Fire;
if Input.Keyboard[DIK_ESCAPE] then
Stop;
end;
procedure TWave.Initialize;
begin
inherited;
InputDevices := [idKeyboard];
GraphicsInfo.SetMaxFPS(100);
GraphicsInfo.SetScreenFlags([]);
Engines.Add;
Engines[0].FileNames.Add('ship.bmp');
Engines[0].FileNames.Add('shoot.bmp');
Engines[0].FileNames.Add('enemy1.bmp');
Engines[0].FileNames.Add('explosion.bmp');
Engines[0].LoadFile;
FBack1 := TBackground.Create;
FBack1.FileName := 'layer1.bmp';
FBack1.LoadFile(TRGB.Create(255, 0, 255).ToInt(32));
FBack1.Zoom := Round(GraphicsInfo.GetWidth / FBack1.Width * 100);
FBack1.Seamless := True;
FBack1.Filter := sfPoint;
FBack2 := TBackground.Create;
FBack2.FileName := 'layer2.bmp';
FBack2.LoadFile(TRGB.Create(255, 0, 255).ToInt(32));
FBack2.Zoom := Round(GraphicsInfo.GetWidth / FBack2.Width * 100);
FBack2.Seamless := True;
FBack2.Filter := sfPoint;
FBack3 := TBackground.Create;
FBack3.FileName := 'layer3.bmp';
FBack3.LoadFile(TRGB.Create(255, 0, 255).ToInt(32));
FBack3.Zoom := Round(GraphicsInfo.GetWidth / FBack3.Width * 100);
FBack3.Seamless := True;
FBack3.Filter := sfPoint;
FShip := THero.Create;
FShip.Engine := Engines[0];
FShip.AnimationName := 'main';
FShip.GoCenterX;
FShip.Y := GraphicsInfo.GetHeight - FShip.Height;
FShip.CollisionShape := csAuto;
FShip.Registrator := self;
FExplosion := LoadSound('explosion');
end;
procedure TWave.Uninitialize;
begin
FBack1.Free;
FBack2.Free;
FBack3.Free;
inherited;
end;
procedure TWave.Fire;
const
SHOOT_SPEED = 4;
SHOOT_ALIVE = 2;
var
shoot: TAnimationSprite;
begin
shoot := TShoot.Create;
shoot.Engine := Engines[0];
shoot.AnimationName := 'shoot';
shoot.VerticalSpeed := -SHOOT_SPEED;
shoot.X := FShip.X;
shoot.Y := FShip.Y;
shoot.TimeOut := GraphicsInfo.GetMaxFPS * SHOOT_ALIVE;
shoot.Registrator := self;
shoot := TShoot.Create;
shoot.Engine := Engines[0];
shoot.AnimationName := 'shoot';
shoot.VerticalSpeed := -SHOOT_SPEED;
shoot.X := FShip.Right - shoot.Width;
shoot.Y := FShip.Y;
shoot.TimeOut := GraphicsInfo.GetMaxFPS * SHOOT_ALIVE;
shoot.Registrator := self;
end;
procedure TWave.Update(aEllapsedTime: Int64);
begin
inherited;
HandleShip;
HandleEnemies;
FBack3.MoveDown(2);
FBack2.MoveDown(1);
FBack1.MoveDown(0.5);
end;
{ TGameSprite }
function TGameSprite.Game: IGame;
begin
result := TWave(Registrator.AsObject);
end;
end.
The overview is:
- Loading the necessary stuff in Initialize()
- Draw the backgrounds in Draw(), the bitmaps are automatically draw via Engine class
- Handling the logic in Update()
- Move ship (using the keyboard)
- Move enemies
- Move background
- Unloading all suff in Uninitialize()
No comments:
Post a Comment