📄 main.pas
字号:
{*******************************************************}
{ Magic Girl }
{ 版权所有 (C) 2002, 2003 Rainstorey Studio }
{ ------------------------------------------ }
{ }
{ }
{ 游戏逻辑实现单元,也是最无聊的代码。 }
{ }
{ }
{ E-Mail:Rainstorey@163.com }
{ WebSite:http://www.Rainstorey.com }
{*******************************************************}
//TODO:更好的方法是分解逻辑和界面代码。
unit Main;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,MMSystem,Controls,Forms,
DXDraws,DXClass,DXSprite,DXInput,GameClasses,DXSounds,DXFonts,DIB,
GameConst,DIBEffect,ExtCtrls;
type
TFMain = class(TDXForm)
DXDraw:TDXDraw;
Image:TDXImageList;
DXTimer1:TDXTimer;
SpriteEngine:TDXSpriteEngine;
Input:TDXInput;
WaveList:TDXWaveList;
Sound:TDXSound;
DXFont:TDXFont;
Timer1:TTimer;
procedure DXDrawInitialize(Sender:TObject);
procedure DXDrawFinalize(Sender:TObject);
procedure FormCreate(Sender:TObject);
procedure DXTimer1Timer(Sender:TObject;LagCount:Integer);
procedure FormKeyDown(Sender:TObject;var Key:Word;
Shift:TShiftState);
procedure FormCloseQuery(Sender:TObject;var CanClose:Boolean);
procedure Timer1Timer(Sender:TObject);
private
procedure BuildMap(const Back:Integer);
procedure MCINOTIFY(var Message:TMessage); message MM_MCINOTIFY;
procedure ShowDiamCount;
procedure GameInit;
public
GameFullScreen:Boolean; //游戏已全屏幕显示
FCount:Cardinal; //以100桢/秒计算,该值要等16个月后才会溢出。
MainPlayer:TMainPlayer;
BackMap:array[0..2] of TBackMap;
Bullet:TBullet;
BackPlayer:array[0..20] of TBackPlayer;
BlueDiam,GreenDiam,YellowDiam:Integer;
BulletOffPoint:TPoint;
TotalScore:Cardinal;
BossFCount:Cardinal;
FSureFace:TDirectDrawSurface;
LogoDIB:TDIBEffect;
GameStatus:TGameStatus;
ApplicationExit:Boolean;
function CreateMainPlayer(const t:Cardinal = 0):Boolean;
procedure GetOnArticle(ArticleType:TArticleType;Sender:TObject);
procedure BuildEnemy;
procedure GamePassAndAddScore;
end;
var
FMain:TFMain;
implementation
uses MainProcess;
{$R *.dfm}
procedure TFMain.DXDrawInitialize(Sender:TObject);
begin
mciSendString('OPEN BGM01.mid TYPE SEQUENCER ALIAS BGM',nil,0,handle);
DXTimer1.Enabled:=True;
Self.Caption:= 'Demo Game';
ShowCursor(False);
GameInit;
//兼容性问题
with DXDraw.Surface.Canvas do
begin
Brush.Style:=bsClear;
Font.Color:=clYellow;
Font.Name:= 'MonoType Corsiva';
Font.Size:=14;
end;
LogoDIB:=TDIBEffect.Create;
LogoDIB.Assign(Image.Items.Find('MMLogo').Picture);
// FSureFace:=TDirectDrawSurface.Create(DXDraw.DDraw);
GameStatus:=Gaming;
DXTimer1.Interval:=0;
GameStatus:=GameLogo;
//WaveList.Items.Find('RainLogo').Play(false);
end;
procedure TFMain.DXDrawFinalize(Sender:TObject);
begin
DXTimer1.Enabled:=False;
mciSendString('STOP BGM',nil,0,handle);
mciSendString('CLOSE ANIMATION',nil,0,handle);
ShowCursor(True);
GameStatus:=GameExit;
ApplicationExit:=True;
// FSureFace.Free;
// FSureFace:=nil;
// aa.Free;
end;
procedure TFMain.FormCreate(Sender:TObject);
begin
Self.Color:=clBlack;
DXDraw.Color:=clBlack;
Randomize;
ApplicationExit:=False;
GameFullScreen:=True;
if GameFullScreen then
begin
Self.BorderStyle:=bsNone;
DXDraw.Display.Height:=600;
DXDraw.Display.Width:=800;
DXDraw.Display.BitCount:=16;
DXDraw.Options:=DXDraw.Options + [doFullScreen];
DXTimer1.Interval:=0;
end;
//打开硬件加速
// DXDraw.Options:=DXDraw.Options+[do3D,doWaitVBlank,doDirectX7Mode,doHardware]-[doSystemMemory];
end;
procedure TFMain.DXTimer1Timer(Sender:TObject;LagCount:Integer);
begin
if not (DXDraw.CanDraw) then Exit;
DXDraw.Surface.Fill(0);
// Image.Items.Find('DirectX').DrawAlpha(DXDraw.Surface,Bounds(0,DXDraw.SurfaceHeight - 100,40,59),0,FCount);
// Image.Items.Find('Delphi').DrawAlpha(DXDraw.Surface,Bounds(0,DXDraw.SurfaceHeight - 41,114,41),0,FCount * 2);
if (GameStatus = Gaming) or (GameStatus = GamePassing) then
begin
SpriteEngine.Move(1);
SpriteEngine.Dead;
SpriteEngine.Draw;
ShowDiamCount;
BuildEnemy;
with DXDraw.Surface.Canvas do
begin
TextOut(30,10, 'FPS:' + IntToStr(DXTimer1.FrameRate));
TextOut(30,30, 'FPSCount:' + IntToStr(FCount));
TextOut(30,50, 'Press "Z" or "Space" key transmit bullet.Press "ESC" exit.');
TextOut(30,70, 'SCORE:' + IntToStr(TotalScore));
TextOut(120,DXDraw.SurfaceHeight - 30, 'RainBlog:http://www.rainstorey.com/blog');
// TextOut(30,50,IntToStr(Trunc(TDebug)));
Release;
end;
// aa.AddMonoNoise(FCount);
// aa.Effect_AddColorNoise(fcount);
// DXDraw.Surface.Draw(0,0,FSureFace.ClientRect,nil,True);
{ if FCount<50 then
begin
aa.Effect_Darkness(fcount);
FSureFace.LoadFromDIB(aa);
DXDraw.Surface.Draw(0,0,FSureFace.ClientRect,FSureFace,True);
end; }
end;
case GameStatus of
GameMenu:
begin
LogoDIB.Assign(Image.Items.Find('MMLogo').Picture);
LogoDIB.Effect_Mosaic(40 - FCount);
DXDraw.Surface.LoadFromDIB(LogoDIB);
DXDraw.Surface.Draw(0,0,DXDraw.Surface.ClientRect,DXDraw.Surface,True);
if FCount = 200 then
begin
LogoDIB.Free;
FCount:=0;
GameStatus:=Gaming;
mciSendString('PLAY BGM NOTIFY',nil,0,handle);
WaveList.Items.Find('Go').Play(False);
end;
end;
GameLogo:
begin
DXDraw.Surface.Fill(clwhite);
Image.Items.Find('RainLogo').DrawAlpha(DXDraw.Surface,Bounds((DXDraw.Width div 2) - 215,(DXDraw.Height div 2) - 45,430,90),0,FCount);
if FCount = 255 then
begin
FCount:=0;
DXTimer1.Interval:=20;
GameStatus:=GameMenu;
end;
end;
GamePassing:GamePassAndAddScore;
GamePass:
begin
LogoDIB.Emboss;
DXDraw.Surface.LoadFromDIB(LogoDIB);
DXDraw.Surface.Draw(0,0,DXDraw.Surface.ClientRect,DXDraw.Surface,True);
DXTimer1.Enabled:=False;
Timer1.Enabled:=True;
end;
end;
DXDraw.Flip;
Inc(FCount);
end;
procedure TFMain.FormKeyDown(Sender:TObject;var Key:Word;
Shift:TShiftState);
begin
if Key = VK_ESCAPE then Close;
end;
procedure TFMain.BuildMap(const Back:Integer);
var
i,j:Integer;
begin
case Back of
0:
begin
for i:=0 to BackMap[Back].MapWidth - 1 do
for j:=0 to BackMap[Back].MapHeight - 1 do
begin
BackMap[Back].Chips[i,j]:=Random(10);
end;
end;
1:
begin
for i:=0 to BackMap[Back].MapWidth - 1 do
for j:=0 to BackMap[Back].MapHeight - 1 do
begin
BackMap[Back].Chips[i,j]:=Random(300);
end;
end;
2:
begin
for i:=0 to BackMap[Back].MapWidth - 1 do
for j:=0 to BackMap[Back].MapHeight - 1 do
begin
BackMap[Back].Chips[i,j]:=Random(300);
end;
end;
end;
end;
procedure TFMain.MCINOTIFY(var Message:TMessage);
begin
mciSendString('SEEK BGM TO START',nil,0,handle);
mciSendString('PLAY BGM NOTIFY',nil,0,handle);
end;
procedure TFMain.ShowDiamCount;
begin
with DXDraw.Surface.Canvas do
begin
TextOut(DXDraw.SurfaceWidth - 75,6, 'X' + IntToStr(GreenDiam));
TextOut(DXDraw.SurfaceWidth - 175,6, 'X' + IntToStr(BlueDiam));
TextOut(DXDraw.SurfaceWidth - 275,6, 'X' + IntToStr(YellowDiam));
Release;
end;
// DXFont.TextOut(DXDraw.Surface,0,52, 'SCORE:' + IntToStr(TotalScore));
end;
procedure TFMain.GameInit;
var
i:Integer;
begin
Image.Items.MakeColorTable;
DXDraw.ColorTable:=Image.Items.ColorTable;
DXDraw.DefColorTable:=Image.Items.ColorTable;
DXDraw.UpdatePalette;
//定义所有Sprite坐标系原点
SpriteEngine.Engine.X:=0;
SpriteEngine.Engine.Y:=0;
//
CreateMainPlayer;
//--------------------------------
BackMap[0]:=TBackMap.Create(SpriteEngine.Engine);
BackMap[0].Image:=Image.Items.Find('Back0');
BackMap[0].SetMapSize(300,DXDraw.SurfaceWidth);
BackMap[0].Tile:=True;
BackMap[0].Z:= -10;
BackMap[0].Speed:=0.5;
BackMap[0].Y:=Random(10);
BuildMap(0);
BackMap[1]:=TBackMap.Create(SpriteEngine.Engine);
BackMap[1].Image:=Image.Items.Find('Back1');
BackMap[1].SetMapSize(300,DXDraw.SurfaceWidth);
BackMap[1].Tile:=True;
BackMap[1].Z:= -9;
BackMap[1].Speed:=10;
BackMap[1].Inclined:=1;
BackMap[1].Y:=Random(25);
BuildMap(1);
BackMap[2]:=TBackMap.Create(SpriteEngine.Engine);
BackMap[2].Image:=Image.Items.Find('Back2');
BackMap[2].SetMapSize(300,DXDraw.SurfaceWidth);
BackMap[2].Tile:=True;
BackMap[2].Z:= -8;
BackMap[2].Speed:=5;
BackMap[2].Inclined:= -2;
BackMap[2].Y:=Random(25);
BuildMap(2);
for i:=0 to 5 do
begin
BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[i] do
begin
Image:=FMain.Image.Items.Find('Back3');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Speed:=Random(25) + 1;
X:=Random(DXDraw.SurfaceWidth);
Z:=1;
end;
end;
for i:=6 to 8 do
begin
BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[i] do
begin
Image:=FMain.Image.Items.Find('Back4');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Speed:=Random(20) + 1;
X:=Random(DXDraw.SurfaceWidth);
Z:=1;
end;
end;
for i:=9 to 11 do
begin
BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[i] do
begin
Image:=FMain.Image.Items.Find('Back5');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Speed:=Random(20) + 1;
X:=Random(DXDraw.SurfaceWidth);
Z:=1;
end;
end;
for i:=12 to 15 do
begin
BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[i] do
begin
Image:=FMain.Image.Items.Find('Back6');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Speed:=Random(20) + 1;
X:=Random(DXDraw.SurfaceWidth);
Z:=1;
end;
end;
for i:=16 to 17 do
begin
BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[i] do
begin
Image:=FMain.Image.Items.Find('Back7');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Speed:=Random(20) + 1;
X:=Random(DXDraw.SurfaceWidth);
Z:=1;
end;
end;
BackPlayer[18]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[18] do
begin
Image:=FMain.Image.Items.Find('BlueDiamond');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Quiescence:=True;
X:=DXDraw.SurfaceWidth - 200;
Y:=0;
Z:=10;
end;
BackPlayer[19]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[19] do
begin
Image:=FMain.Image.Items.Find('YellowDiamond');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Quiescence:=True;
X:=DXDraw.SurfaceWidth - 300;
Y:=0;
Z:=10;
end;
BackPlayer[20]:=TBackPlayer.Create(SpriteEngine.Engine);
with BackPlayer[20] do
begin
Image:=FMain.Image.Items.Find('GreenDiamond');
Width:=Image.Width;
Height:=Image.Height;
AnimCount:=Image.PatternCount - 1;
Quiescence:=True;
X:=DXDraw.SurfaceWidth - 100;
Y:=0;
Z:=10;
end;
BulletOffPoint.X:=20;
BulletOffPoint.Y:=0;
end;
//这是一个不好的设计,因该重新考虑其它方案来取代这冗长无聊的代码!!!
procedure TFMain.BuildEnemy;
var
i:Integer;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -