Showing posts with label Sprites. Show all posts
Showing posts with label Sprites. Show all posts

Thursday, October 7, 2010

Much more on sprites

Because the 2d system is build on top of the 3d system, is easy to add special effects like:

  • Transparencies
    • Via Alpha property
  • Scaling
    • Via Zoom property
  • Rotating
    • Via Angle property
  • Filtering
    • Via Filter property, TSurfaceFilter = (sfNone, sfPoint, sfLinear, sfAnisotropic, sfCubic);
  • Effects
    • Via Effect property, TSurfaceEffect = (seNone, seAdd, seSub, seMultiply)
In this screen you can see how the dragon faces the ship (no precalculated angles), this is done changing the Angle property with the angle value between the two sprites (dragon.Angle := dragon.AngleBetween(ship))


Also the missiles send from the boss at the right, are calculated via a Bezier class and then the Angle set according to the difference (as the gem SlapFight did years ago)

In this other screen, the laser beam has the following properties set: 
  • laser.Angle = Angle of parent (bad boss)
  • laser.Effect = Add
  • laser.Zoom = depends on whether or not the laser shrinks
  • laser.CenterFrom(boss) //In order to move with boss


The background file looks like this:


after setting the property Seamless and playing with the X and Y properties via sines and cosines, the background looks nicer.

Another nice property is Z, so you can easily decide which is the sprite priority (default is the latest draw), in the example I 've set three Z, front (life), middle (sprites) and back (background)

If you set the property AttachedSprite to a valid sprite, the current sprite will automatically follow it (X and Y are the delta offsets), this is useful for example when you shot an enemy and you want some sparks drawn, but you want them to follow the enemy, not just be static.

Setting CollisionShape to one of the following values, TCollisionShape = (csNone, csPrecise, csRectangle, csCircle, csTriangle, csRhombus, csColorKey), you are telling the sprite how it should behave when the Collision() method is called.

Setting the Sleep property you ensure that the sprite won't be shown until the time specified elapses, interesting when you don't want the sprite to be shown inmediatly, but after a period of time specified in milliseconds.

Aditionally you have the Timeout property, which tells the sprite how long it should last.

That's all folks.

Wednesday, October 6, 2010

More on maps and sprites

This is a full example on how you can check collisions against a map (look at CheckTiles() and see how easy is to check for collisions):





This silly demo is done with the following code

unit Game;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,
  BB.Screen.Maps, BB.Screen.Interfaces, BB.Screen.Sprites, BB.Screen.Types;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FShip: TAnimationSprite;

    procedure CheckTiles(aLayer: TLayer; aCell: PCell; aTile: ISprite);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  BB.Screen, BB.Screen.D3D, BB.Screen.Engines, BB.Input.Keys, BB.Timer, BB.Colors;

procedure TForm1.CheckTiles(aLayer: TLayer; aCell: PCell; aTile: ISprite);
var
  x, y: integer;
  spurk: TAnimationSprite;

begin
  if FShip.Collision(aTile, x, y) then
  begin
    spurk := TAnimationSprite.Create;
    spurk.CoordinateOrigin := coCenter;
    spurk.Engine := FShip.Engine;
    spurk.AnimationName := 'spurk';
    spurk.X := x;
    spurk.Y := y;
    spurk.AttachedSprite := FShip;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  gd: TGraphicDriver;
  map: TMap;
  e: TSpriteEngine;

begin
  gd := TD3DDriver.Create;
  gd.WindowHandle := WindowHandle;
  gd.Width := Width;
  gd.Height := Height;
  gd.BPP := 32;
  gd.ScreenFlags := [sfClear, sfWait];
  gd.Initialize;

  map := TMap.Create;
  map.FileName := 'space';
  map.LoadFile;
  map[0].OnRenderTile := CheckTiles;
  map[0].GoLeft;
  map[0].SpeedX := 1;

  e := TSpriteEngine.Create;
  e.ScanMethod := smBox;
  e.FileNames.Add('ship.bmp');
  e.LoadFile;

  FShip := TAnimationSprite.Create;
  FShip.Engine := e;
  FShip.CollisionShape := csPrecise;
  FShip.CollisionAccuracy := caLow;
  FShip.AnimationName := 'ship';
  FShip.Layer := map[0];
  FShip.GoCenterY;

  repeat
    if Inkey(VK_P) then
      WaitFor(VK_P);

    if Inkey(VK_LEFT) then
      FShip.MoveLeft(2);
    if Inkey(VK_RIGHT) then
      FShip.MoveRight(2);

    if Inkey(VK_UP) then
      FShip.MoveUp(2);
    if Inkey(VK_DOWN) then
      FShip.MoveDown(2);

    gd.BeginRender;

    map.Render;
    e.Render;

    gd.EndRender;
    Application.ProcessMessages;

  until Inkey(VK_ESCAPE);

  Close;
end;

end.