📄 gameclasses.pas
字号:
{*******************************************************}
{ Magic Girl }
{ 版权所有 (C) 2002, 2003 Rainstorey Studio }
{ ----------------------------------------- }
{ CopyRight(?)Rainstorey Soft by 2006-2008 }
{ Power DelphiX for Delphi }
{ This Code License for GPL }
{ Magic Girl Classes Definition some Classes for}
{ GameSprite in Game. }
{ v0.40 }
{ Last Modification 2006-1-6 14:51:22 }
{ E-Mail:Rainstorey@163.com }
{ Blog:http://www.rainstorey.com/blog }
{ WebSite:http://www.Rainstorey.com }
{*******************************************************}
//TODO:魔法效果未实现,某些代码有更优方案。
unit GameClasses;
interface
uses Windows,SysUtils,Classes,
DXDraws,DXSprite,DXInput,DXSounds;
function SleepEx(const t:Cardinal):Boolean;
var
TDebug:Double; //调试变量
//
type
TEnemyActivityLine = (TALLine,TALALine,TALCLine,TALC1Line,TALILine,TALJLine,TALLLine,TALL1Line,TALMLine,TALNLine,TALOLine,TALSLine,TALULine,TALVLine,TALV1Line,TALWLine,TALXLine,TALZLine,TALZ1Line,TALRandLine);
TTransmitType = (TTRand,TTLine,TTCircle,TTRadian);
TAccuracy = (ACLow,ACStandard,ACHigh);
TBulletType = (BTStandard,BTFire,BTLaser,BTWave,BTMoon,BTCircle);
TArticleType = (ArtNone,Artsupper,ArtMoon,ArtCircle,ArtWave,ArtFire,ARTLaser,ArtPointA,ArtPointB,DiamondA,DiamondB,DiamondC);
TOnGetArticle = procedure(ArticleType:TArticleType;Sender:TObject) of object;
TDeadSound = (BomNone,EnemyBom,PlayerBom,ArtBom,Fire,Drip,Gun,LaserGun,Bom8,Bom9);
// TDeadAnim = (Anim1,Anim2,Anim3,Anim4,Anim5,Anim6,Anim7,Anim8,Anim9);
TDeadSprite = class;
TGameSprite = class(TImageSpriteEx)
protected
FQuiescence:Boolean;
FSpeed:Integer;
FShowSound:string;
FDeadSound:TDeadSound;
FDeadAnimSpeed:Double;
FDeadImage:string;
FDeadOffRect:TPoint;
FDeadTimes:Integer;
procedure Hit; virtual;
//
public
class procedure PalleteAnim(DX:TDXDraw;Col:TRGBQuad;Time:Integer);
constructor Create(AParent:TSprite); override;
destructor Destroy; override;
procedure DoMove(MoveCount:Integer); override;
property Speed:Integer read FSpeed write FSpeed;
property ShowSound:string read FShowSound write FShowSound;
property DeadSound:TDeadSound read FDeadSound write FDeadSound;
property DeadImage:string read FDeadImage write FDeadImage;
property DeadOffRect:TPoint read FDeadOffRect write FDeadOffRect;
property DeadTimes:Integer read FDeadTimes write FDeadTimes;
property Quiescence:Boolean read FQuiescence write FQuiescence;
end;
TDeadSprite = class(TGameSprite)
private
FDeadSpeed:Integer;
FDeadTimeCount:Integer;
FDeadTime:Double;
public
constructor Create(AParent:TSprite); override;
property DeadSpeed:Integer read FDeadSpeed write FDeadSpeed;
procedure DoMove(MoveCount:Integer); override;
end;
TBossDead = class(TDeadSprite)
private
tempx:Double;
public
procedure DoMove(MoveCount:Integer); override;
end;
TBackPlayer = class(TGameSprite)
private
FStop:Boolean;
public
property Stop:Boolean read FStop write FStop;
procedure DoMove(MoveCount:Integer); override;
end;
TEnemy = class(TGameSprite)
protected
FHP:Integer;
FBullet:string;
FTransmitProbability:Integer; //百分比
FBulletSpeed:Integer;
FProbability:Integer; //0为最高精确度
FBuildArt:TArticleType;
FTransmitType:TTransmitType;
FScore:Integer;
FLineType:TEnemyActivityLine;
tempx,tempy:Double;
FisHit:Boolean;
procedure Transmit; virtual;
property isHit:Boolean read FisHit write FisHit;
public
property Bulletspeed:Integer read FBulletSpeed write FBulletSpeed;
property TransmitProbability:Integer read FTransmitProbability write FTransmitProbability;
property Bullet:string read FBullet write FBullet;
procedure DoMove(MoveCount:Integer); override;
procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
property Hp:Integer read FHP write FHP;
constructor Create(AParent:TSprite); override;
destructor Destroy; override;
property Probability:Integer read FProbability write FProbability;
property BuildArt:TArticleType read FBuildArt write FBuildArt;
property TransmitType:TTransmitType read FTransmitType write FTransmitType;
property Score:Integer read FScore write FScore;
property LineType:TEnemyActivityLine read FLineType write FLineType;
end;
{ TBoss }
TBoss = class(TEnemy)
private
FBossBomb:TDeadSound;
tempcount:Cardinal;
tempcount1:Cardinal;
FShootSound:TDeadSound;
protected
procedure Transmit; override;
public
property ShootSound:TDeadSound read FShootSound write FShootSound;
procedure DoMove(MoveCount:Integer); override;
constructor Create(AParent:TSprite); override;
destructor Destroy; override;
end;
TMainPlayer = class(TGameSprite)
private
FSupperTime,FSupperTotalTime:Cardinal;
FSupper:Boolean;
FBulletType:TBulletType;
FBulletCounts:Integer;
FNCanControl:Boolean;
FShootSound:TDeadSound;
procedure SetBulletType(const Value:TBulletType);
protected
procedure SetFSupper(const Value:Boolean);
public
property ShootSound:TDeadSound read FShootSound write FShootSound;
property NCanControl:Boolean read FNCanControl write FNCanControl;
property BulletType:TBulletType read FBulletType write SetBulletType;
property SupperTotalTime:Cardinal read FSupperTotalTime write FSupperTotalTime;
property Supper:Boolean read FSupper write SetFSupper;
procedure DoMove(MoveCount:Integer); override;
procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
destructor Destroy; override;
constructor Create(AParent:TSprite); override;
end;
{$WARNINGS OFF}
TBullet = class(TGameSprite)
private
FPower:Integer;
public
constructor Create(AParent:TSprite); override;
destructor Destroy; override;
property Power:Integer read FPower write FPower;
procedure DoMove(MoveCount:Integer); override;
procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
end;
TMagicBullet=class(TBullet);
TEnemyBullet = class(TGameSprite)
private
FAccuracy:TAccuracy;
FDirectionOff:Boolean;
FPorY:Double;
FTransmitType:TTransmitType;
protected
XX,YY:Shortint;
FCircleAngle,FCircleCenter:Double;
public
// property MainX:Double read FMainX write FMainY;
// property MainY:Double read FMainY write FMainY;
// property EnemyX:Double read FEnemyX write FEnemyX;
// property EnemyY:Double read FEnemyY write FEnemyY;
property Accuracy:TAccuracy read FAccuracy write FAccuracy;
procedure DoMove(MoveCount:Integer); override;
procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
constructor Create(AParent:TSprite;FEnemy:TEnemy); virtual;
end;
{$WARNINGS ON}
//-----------------------------------------------------------------------//
TArticle = class(TGameSprite)
private
FOnGetArticle:TOnGetArticle;
FArticleType:TArticleType;
procedure SetArticleType(const Value:TArticleType);
public
property ArticleType:TArticleType read FArticleType write SetArticleType;
property OnArticle:TOnGetArticle read FOnGetArticle write FOnGetArticle;
procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
procedure DoMove(MoveCount:Integer); override;
end;
//------------------------------------------------------------------------------
TBackMap = class(TBackgroundSprite)
private
FInclined:Double;
FSpeed:Double;
public
property Speed:Double read FSpeed write FSpeed;
property Inclined:Double read FInclined write FInclined;
procedure DoMove(MoveCount:Integer); override;
end;
//-------------------------------------------------------------------------//
implementation
uses Main,GameConst;
const
BulletPower:array[0..5] of Integer = (1,5,8,4,3,2);
BulletName:array[0..5] of string = ('Bullet', 'Bullet1', 'Bullet2', 'Bullet3', 'Bullet4', 'Bullet5');
BulletCount:array[0..5] of Integer = (99,4,2,6,99,3);
ArticleName:array[0..11] of string = ('', 'ArtSupper', 'ArtMoon', 'ArtCircle', 'ArtWave', 'ArtFire', 'ArtLaser', 'ArtPointA', 'ArtPointB', 'BlueDiamond', 'YellowDiamond', 'GreenDiamond');
DeadSoundName:array[0..7] of string = ('', 'EnemyBom', 'PlayerDead', 'ArtHide', 'Fire', 'Drip', 'Gun', 'LaserGun');
//BombTypeName
RadianRange:Integer = 100;
var
BulletCounts:Integer;
GameTick1,GameTick2:Cardinal;
{ TMainPlayer }
function SleepEx(const t:Cardinal):Boolean;
begin
GameTick2:=FMain.FCount;
if GameTick2 - GameTick1 > t then
begin
GameTick1:=GameTick2;
Result:=True;
Exit;
end
else
Result:=False;
end;
constructor TMainPlayer.Create(AParent:TSprite);
begin
inherited Create(AParent);
FShootSound:=Fire;
end;
destructor TMainPlayer.Destroy;
begin
if not (FMain.GameStatus = GameExit) //Fixed GameApplication can't exit at 2006-1-10 20:33:03
then FMain.CreateMainPlayer;
inherited Destroy;
end;
procedure TMainPlayer.DoCollision(Sprite:TSprite;var Done:Boolean);
var
tempx,tempy:Double;
begin
//Magic Girl主动去撞其他精灵则发生该事件。
Done:=False;
if not (FSupper) then
begin
tempx:=Abs(Sprite.X - Self.X);
tempy:=Abs(Sprite.Y - Self.Y);
if (Sprite is TEnemy) or ((Sprite is TEnemyBullet) and (32 > tempx) and (tempx > 16) and (27 > tempy) and (tempy > 11)) then
Hit;
end;
if (Sprite is TArticle) then
begin
// FMain.WaveList.Items.Find(DeadSoundName[Ord(TArticle(Sprite).DeadSound)]).Play(False);
with Sprite as TArticle do
begin
if Assigned(FOnGetArticle) then
FOnGetArticle(FArticleType,Self);
Hit;
end;
end;
end;
procedure TMainPlayer.DoMove(MoveCount:Integer);
begin
inherited DoMove(MoveCount);
if not (FNCanControl) then
with FMain.Input do
begin
Update;
if isup in Keyboard.States then Y:=Y - FSpeed;
if isdown in Keyboard.States then Y:=Y + FSpeed;
if isleft in Keyboard.States then X:=X - FSpeed;
if isright in Keyboard.States then X:=X + FSpeed;
if (isButton1 in Keyboard.States) and (BulletCounts < FBulletCounts) and SleepEx(3) then
begin
with TBullet.Create(FMain.SpriteEngine.Engine) do
begin
Image:=FMain.Image.Items.Find(BulletName[Ord(FBulletType)]);
Width:=Image.Width;
Height:=Image.Height;
Power:=BulletPower[Ord(FBulletType)];
X:=Self.X + Self.Image.PatternWidth;
Y:=Abs(Image.PatternHeight div 2 - Self.Y) + 15;
DeadSound:=BomNone;
AnimCount:=Image.PatternCount - 1;
AnimSpeed:=0.1;
DeadImage:= 'Hit';
DeadTimes:=10;
DeadOffRect:=FMain.BulletOffPoint;
FMain.WaveList.Items.Find(DeadSoundName[Ord(FShootSound)]).Play(False);
end;
end;
if (FSupper) and (FMain.FCount - FSupperTime = FSupperTotalTime) then
Supper:=False;
if X < 0 then X:=0;
if X > FMain.DXDraw.Width - 48 then X:=FMain.DXDraw.Width - 48;
if Y < 0 then Y:=0;
if Y > FMain.DXDraw.Height - 48 then Y:=FMain.DXDraw.Height - 48;
end;
end;
procedure TMainPlayer.SetBulletType(const Value:TBulletType);
begin
FBulletType:=Value;
FBulletCounts:=BulletCount[Ord(FBulletType)];
end;
procedure TMainPlayer.SetFSupper(const Value:Boolean);
begin
FSupper:=Value;
if FSupper then
begin
AnimCount:=AnimCount + 1;
FSupperTime:=FMain.FCount;
if FSupperTotalTime = 0 then FSupperTotalTime:=300;
end
else
AnimCount:=Image.PatternCount - 1;
end;
{ TBackMap }
procedure TBackMap.DoMove(MoveCount:Integer);
begin
inherited DoMove(MoveCount);
X:=X - FSpeed;
Y:=Y + FInclined;
end;
{ TBullet }
constructor TBullet.Create(AParent:TSprite);
begin
inherited Create(AParent);
Inc(BulletCounts);
end;
destructor TBullet.Destroy;
begin
Dec(BulletCounts);
inherited Destroy;
end;
procedure TBullet.DoCollision(Sprite:TSprite;var Done:Boolean);
begin
Done:=False;
if (Sprite is TEnemy) then
begin
if not (Self.Image.Name = 'Bullet2') then Hit;
if (TEnemy(Sprite).Hp - FPower) <= 0 then
begin
TEnemy(Sprite).isHit:=True; //敌方被击中时才计分
TEnemy(Sprite).Hit;
end
else
begin
FMain.WaveList.Items.Find('Water').Play(False);
TEnemy(Sprite).Hp:=TEnemy(Sprite).Hp - FPower; //减血
end;
end;
end;
procedure TBullet.DoMove(MoveCount:Integer);
begin
inherited DoMove(MoveCount);
X:=X + 24;
if X >= FMain.DXDraw.Width then Dead;
end;
{ TEnemy }
constructor TEnemy.Create(AParent:TSprite);
begin
inherited Create(AParent);
//所有需要初始化的对象写在这。
FScore:=100;
FBulletSpeed:=2;
FBuildArt:=DiamondB;
end;
destructor TEnemy.Destroy;
begin
if FMain.GameStatus <> GameExit then //Bug is Fixed;
begin
if FisHit then
Inc(FMain.TotalScore,FScore);
if (Ord(BuildArt) <> 0) then
with TArticle.Create(FMain.SpriteEngine.Engine) do
begin
ArticleType:=BuildArt;
Speed:=1;
X:=Self.X + Self.Image.PatternWidth div 2;
Y:=Self.Y + Self.Image.PatternHeight div 2;
OnArticle:=FMain.GetOnArticle;
DeadImage:= '';
DeadSound:=ArtBom;
end;
end;
inherited Destroy;
end;
procedure TEnemy.DoCollision(Sprite:TSprite;var Done:Boolean);
begin
if (Sprite is TMainPlayer) then
TMainPlayer(Sprite).DoCollision(Sprite,Done);
if Sprite is TBullet then TBullet(Sprite).DoCollision(Self,Done);
end;
procedure TEnemy.DoMove(MoveCount:Integer);
begin
//mess design
inherited DoMove(MoveCount);
//对列,以左手坐标系为准。起点已右边为起点,左边为终点。
case FLineType of
//直线
TALLine:
X:=X - FSpeed;
//C子型
TALCLine:
begin
tempx:=tempx + 1;
X:=X + Round(16 * Cos(tempx / 16 * Pi));
Y:=Y + Round(16 * Sin(tempx / 16 * Pi));
if tempx = 18 then tempx:=0;
X:=X - FSpeed;
end;
TALC1Line:
begin
tempx:=tempx + 1;
X:=X + Round(16 * Cos(tempx / 16 * Pi));
Y:=Y - Round(16 * Sin(tempx / 16 * Pi));
if tempx = 27 then tempx:=0;
X:=X - FSpeed;
end;
//L型
TALILine:Y:=Y + FSpeed;
TALJLine:
begin
alpha:=Trunc(tempy);
if (X >= FMain.DXDraw.Width - Image.Height * 6) then
begin
tempx:=tempx + 1;
X:=X + Round(16 * Cos(tempx / 16 * Pi));
Y:=Y + Round(16 * Sin(tempx / 16 * Pi));
// if tempx = 36 then FSpeed:= -FSpeed;
end;
X:=X - FSpeed;
tempy:=tempy * 2 + 1;
if tempy > 255 then tempy:=255;
end;
TALLLine:
begin
if Y >= FMain.DXDraw.Height - Image.Height then
X:=X - FSpeed
else
Y:=Y + FSpeed;
end;
TALL1Line:
begin
if Y <= 0 then
X:=X - FSpeed
else
Y:=Y - FSpeed;
end;
TALMLine:;
TALNLine:;
TALOLine:
begin
tempx:=tempx + 1;
X:=X + Round(16 * Cos(tempx / 16 * Pi));
Y:=Y + Round(16 * Sin(tempx / 16 * Pi));
end;
TALSLine:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -