📄 main.pas
字号:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, Menus, MMSystem;
type
TMainForm = class(TForm)
RatTimer: TTimer;
ScoreTimer: TTimer;
RatMenu: TPopupMenu;
cmNewGame: TMenuItem;
cmPauseOrResume: TMenuItem;
cmQuit: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormPaint(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure cmQuitClick(Sender: TObject);
procedure NewClick(Sender: TObject);
procedure RatTimerTimer(Sender: TObject);
procedure ScoreTimerTimer(Sender: TObject);
procedure cmPauseOrResumeClick(Sender: TObject);
procedure CreateParams(var Params: TCreateParams); override;
procedure FormShow(Sender: TObject);
procedure RatMenuPopup(Sender: TObject);
private
{ Private declarations }
procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHitTest;
public
{ Public declarations }
procedure DrawHand;
end;
type
MenuButtonStatus = (btnUP, btnOVER, btnDOWN);
MenuButtonOrder = (btnOrderNEW, btnOrderPAUSE, btnOrderCLOSE, btnOrderHIGHSCORE, btnOrderABOUT);
HandStatus_Type = (Hand_Up, Hand_Down, Hand_Hit);
RatSprRec = record
x, y, w, h, ox, oy : integer;
end;
RatRec = record
x, y, pos, speed : integer;
end;
const
//
MenuButtonImageName: array [btnOrderNEW..btnOrderABOUT, btnUP..btnDOWN] of string =
(
('NEWUP','NEWOVER','NEWDOWN'),('PAUSEUP','PAUSEOVER','PAUSEDOWN'), ('CLOSEUP', 'CLOSEOVER','CLOSEDOWN'),
('HIGHSCOREUP', 'HIGHSCOREOVER','HIGHSCOREDOWN'),('ABOUTUP','ABOUTOVER','ABOUTDOWN')
);
var
MainForm: TMainForm;
//主窗口的素材
BufferBitmap,BackGroundBitmap,SpriteBitmap,MaskBitmap,AboutBitmap,
HighScoreBitmap,CtrlBitmap,OKUPButtonBitmap, OKDOWNButtonBitmap: TBitmap;
//控制窗口的按钮图标
MenuButtonBitmap: array [btnOrderNEW..btnOrderABOUT, btnUP..btnDOWN] of TBitmap;
HandStatus : HandStatus_Type; //锤子的三个状态:松开,击中和敲击
HandXPos, HandYPos : integer; //锤子出现的X,Y坐标
LeftTime, Score : integer; //剩余时间
RatSpr : array [0..15] of RatSprRec; //老鼠出现的位置和速度
Rat : array [0..2, 0..2] of RatRec; //老鼠出现的位置
Frames : LongInt; //随机出现的帧数
GameRunning, GamePause : Boolean; //游戏的运行或暂停判断
implementation
uses Ctrl; //主窗口单元
{$R *.DFM}
procedure LoadRatSpr(i, ox, oy, x, y, w, h : integer);
begin
{老鼠变换的坐标值}
RatSpr[i].ox :=ox;
RatSpr[i].oy :=oy;
RatSpr[i].x :=x;
RatSpr[i].y :=y;
RatSpr[i].w :=w;
RatSpr[i].h :=h;
end;
procedure LoadRat(row, col, x, y : integer);
begin
{老鼠出现的坐标值}
Rat[row, col].x := x;
Rat[row, col].y := y;
Rat[row, col].pos := 0;
Rat[row, col].speed := 0;
end;
procedure InitData;
begin
{老鼠出现的位置}
LoadRat(0, 0, 187, 48);
LoadRat(1, 0, 127, 79);
LoadRat(2, 0, 75, 116);
LoadRat(0, 1, 247, 58);
LoadRat(1, 1, 189, 90);
LoadRat(2, 1, 146, 126);
LoadRat(0, 2, 304, 66);
LoadRat(1, 2, 262, 98);
LoadRat(2, 2, 222, 134);
LoadRatSpr(1, $00, $00, $5E, $36, $3C, $39);
LoadRatSpr(2, $01, $02, $61, $02, $38, $36);
LoadRatSpr(3, $01, $0a, $D8, $4E, $38, $2E);
LoadRatSpr(4, $02, $0E, $D7, $24, $38, $2A);
LoadRatSpr(5, $02, $16, $D8, $00, $38, $22);
LoadRatSpr(6, $02, $1A, $D7, $82, $35, $1E);
LoadRatSpr(7, $02, $1A, $A0, $85, $35, $1E);
LoadRatSpr(8, $02, $1A, $9F, $68, $35, $1E);
LoadRatSpr(9, $02, $1A, $9F, $4B, $35, $1E);
LoadRatSpr(10, $02, $1A, $9E, $2D, $35, $1E);
LoadRatSpr(11, $02, $1D, $9E, $12, $35, $1B);
LoadRatSpr(12, $02, $2A, $9E, $01, $35, $0E);
LoadRatSpr(13, $01, $21, $5E, $70, $3D, $25);
LoadRatSpr(14, $01, $21, $5D, $94, $3D, $1A);
LoadRatSpr(15, $00, $00, $00, $00, $00, $00);
end;
procedure DrawRats(x, y, c : integer);
begin
{绘制老鼠}
if c > 0 then
begin
BitBlt(BufferBitmap.Canvas.Handle, x+RatSpr[c].ox, y+RatSpr[c].oy, RatSpr[c].w, RatSpr[c].h,
MaskBitmap.Canvas.Handle, RatSpr[c].x, RatSpr[c].y, SRCAND);
BitBlt(BufferBitmap.Canvas.Handle, x+RatSpr[c].ox, y+RatSpr[c].oy, RatSpr[c].w, RatSpr[c].h,
SpriteBitmap.Canvas.Handle, RatSpr[c].x, RatSpr[c].y, SRCINVERT);
end;
end;
procedure PopupRats;
var i, j : integer;
begin
{老鼠随机出现}
if Frames mod 5 = 0 then
begin
i := random(3);
j := random(3);
if Rat[i,j].pos = 0 then
begin
Rat[i,j].pos := 12;
Rat[i,j].speed := random(1)+1;
end;
end;
end;
procedure UpdateRats(row, col : integer);
begin
{老鼠位置的更新}
if (Rat[row, col].pos <= 12) and (Rat[row, col].pos > 0) then
begin
if (Frames mod Rat[row, col].speed = 0) then
Rat[row, col].pos := Rat[row, col].pos - 1;
end
else
if Rat[row,col].pos >12 then
begin
if (Frames mod Rat[row, col].speed = 0) then Rat[row, col].pos := Rat[row, col].pos + 1;
if Rat[row, col].pos >= 15 then Rat[row, col].pos := 0;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
var
myRgn : HRGN;
round : integer;
btnOrder : MenuButtonOrder;
begin
{程序运行的初始设置}
GameRunning := FALSE;
GamePause := FALSE;
InitData;
HandStatus := Hand_Up; //锤子松开
BackGroundBitmap := TBitmap.Create;
BackGroundBitmap.LoadFromResourceName(hInstance, 'BACKGROUND');
BufferBitmap := TBitmap.Create;
BufferBitmap.Width := BackGroundBitmap.Width;
BufferBitmap.Height := BackGroundBitmap.Height;
MainForm.ClientWidth := BackGroundBitmap.Width;
MainForm.ClientHeight := BackGroundBitmap.Height;
OKUPButtonBitmap:= TBitmap.Create;
OKUPButtonBitmap.LoadFromResourceName(hInstance, 'OKUP');
OKDOWNButtonBitmap:= TBitmap.Create;
OKDOWNButtonBitmap.LoadFromResourceName(hInstance, 'OKDOWN');
CtrlBitmap := TBitmap.Create;
CtrlBitmap.LoadFromResourceName(hInstance, 'CONTROL');
for btnOrder := btnOrderNEW to btnOrderABOUT do
begin
MenuButtonBitmap[btnOrder, btnUP] := TBitmap.Create;
MenuButtonBitmap[btnOrder, btnUP].LoadFromResourceName(hInstance,MenuButtonImageName[btnOrder, btnUP]);
MenuButtonBitmap[btnOrder, btnOVER] := TBitmap.Create;
MenuButtonBitmap[btnOrder, btnOVER].LoadFromResourceName(hInstance,MenuButtonImageName[btnOrder, btnOVER]);
MenuButtonBitmap[btnOrder, btnDown] := TBitmap.Create;
MenuButtonBitmap[btnOrder, btnDown].LoadFromResourceName(hInstance,MenuButtonImageName[btnOrder, btnDOWN]);
end;
round := 128;
MainForm.Brush.Style:=bsClear;
myRgn := 0;
GetWindowRgn(MainForm.Handle, myRgn);
DeleteObject(myRgn);
myRgn:= CreateroundRectRgn(0,0,MainForm.Width,MainForm.Height, round, round);
SetWindowRgn(MainForm.Handle, myRgn, TRUE);
SpriteBitmap := TBitmap.Create;
SpriteBitmap.LoadFromResourceName(hInstance, 'SPRITE');
MaskBitmap := TBitmap.Create;
MaskBitmap.LoadFromResourceName(hInstance, 'MASK');
BitBlt(BufferBitmap.Canvas.Handle, 0, 0, BufferBitmap.Width, BufferBitmap.Height,
BackGroundBitmap.Canvas.Handle, 0, 0, SRCCOPY);
RatTimer.Enabled := FALSE;
LeftTime := 59;
Score := 0;
Left := (Screen.Width - Width) div 2;
Top := (Screen.Height - Height) div 2;
end;
procedure TMainForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := (Style or WS_POPUP) and (not WS_DLGFRAME)and (not WS_CAPTION) ;
end;
procedure TMainForm.WMNCHitTest(var Msg: TWMNCHitTest);
begin
{拖动无标题窗口的事件}
inherited;
if (Msg.Result = htClient)and((GameRunning = FALSE) or(GamePause = TRUE)) then
Msg.Result := htCaption;
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
btnOrder : MenuButtonOrder;
begin
{窗口关闭的一些处理}
BufferBitmap.Free;
BackGroundBitmap.Free;
SpriteBitmap.Free;
MaskBitmap.Free;
AboutBitmap.Free;
HighScoreBitmap.Free;
CtrlBitmap.Free;
OKUPButtonBitmap.Free;
OKDOWNButtonBitmap.Free;
for btnOrder := btnOrderNEW to btnOrderABOUT do
begin
MenuButtonBitmap[btnOrder, btnUP].Free;
MenuButtonBitmap[btnOrder, btnOVER].Free;
MenuButtonBitmap[btnOrder, btnDown].Free;
end;
end;
procedure TMainForm.FormPaint(Sender: TObject);
var row, col : integer;
begin
{窗口OnPaint事件}
BitBlt(BufferBitmap.Canvas.Handle, 0, 0, BufferBitmap.Width, BufferBitmap.Height,
BackGroundBitmap.Canvas.Handle, 0, 0, SRCCOPY);
for row := 0 to 2 do
begin
for col := 0 to 2 do
begin
DrawRats(Rat[row, col].x, Rat[row, col].y, Rat[row, col].pos);
end;
end;
if RatTimer.Enabled = TRUE then
DrawHand();
MainForm.Canvas.Draw(0, 0, BufferBitmap);
CtrlForm.DrawTime;
end;
procedure TMainForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var index : Cardinal;
begin
{窗口OnMouseMove事件}
HandXPos := X - 15;
HandYPos := Y - 40;
for index := 0 to 4 do
PTImage(Cardinal(@CtrlForm.NewBtnImage) + index*sizeof(PTImage))^.Picture.Bitmap := MenuButtonBitmap[MenuButtonOrder(index), btnUP];
end;
procedure TMainForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
row, col : integer;
sp, d : integer;
begin
{窗口OnMouseUp事件}
if (GameRunning = FALSE) or (GamePause = TRUE) then
exit;
d := 10;
if Button = mbLeft then
HandStatus := Hand_Down; //锤子敲下
for row := 0 to 2 do
begin
for col :=0 to 2 do
begin
sp := Rat[row, col].pos;
if (sp > 0) and (sp <= 12) then
begin
if (X > Rat[row, col].x + RatSpr[sp].ox + d) and
(X < Rat[row, col].x + RatSpr[sp].ox + RatSpr[sp].w - d) and
(Y > Rat[row, col].y + RatSpr[sp].oy ) and
(Y < Rat[row, col].y + RatSpr[sp].oy + RatSpr[sp].h ) then
begin
Rat[row, col].pos := 13;
Rat[row, col].speed := 5;
if Button = mbLeft then
begin
HandStatus := Hand_Hit; //锤子击中老鼠
PlaySound('HIT', hInstance, SND_RESOURCE or SND_ASYNC);
end;
end;
end;
end;
FormPaint(self);
end;
end;
procedure TMainForm.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
{窗口OnMouseUp事件}
if (GameRunning = FALSE) or (GamePause = TRUE) then
exit;
if Button = mbLeft then
HandStatus := Hand_Up; //锤子松开
FormPaint(self);
end;
procedure TMainForm.DrawHand;
begin
{处理敲击老鼠的锤子的一些事件}
case HandStatus of
Hand_Up : begin //锤子松开
BitBlt(BufferBitmap.Canvas.Handle, HandXPos, HandYPos, 97, 54,
MaskBitmap.Canvas.Handle, 0, 0, SRCAND);
BitBlt(BufferBitmap.Canvas.Handle, HandXPos, HandYPos, 97, 54,
SpriteBitmap.Canvas.Handle, 0, 0, SRCINVERT);
end;
Hand_Down : begin //锤子敲下
BitBlt(BufferBitmap.Canvas.Handle, HandXPos, HandYPos - 6, 90, 64,
MaskBitmap.Canvas.Handle, 0, 54, SRCAND);
BitBlt(BufferBitmap.Canvas.Handle, HandXPos, HandYPos - 6, 90, 64,
SpriteBitmap.Canvas.Handle, 0, 54, SRCINVERT);
end;
Hand_Hit : begin //锤子击中老鼠
BitBlt(BufferBitmap.Canvas.Handle, HandXPos, HandYPos, 90, 64,
MaskBitmap.Canvas.Handle, 0, 118, SRCAND);
BitBlt(BufferBitmap.Canvas.Handle, HandXPos, HandYPos, 90, 64,
SpriteBitmap.Canvas.Handle, 0, 118, SRCINVERT);
end;
end;
end;
procedure TMainForm.cmQuitClick(Sender: TObject);
begin
{退出程序的一些基本处理}
RatTimer.Enabled:=False;
ScoreTimer.Enabled:=False;
Close;
end;
procedure TMainForm.NewClick(Sender: TObject);
begin
{开始游戏的一些必要设置}
LeftTime := 59;
RatTimer.Enabled := TRUE;
ScoreTimer.Enabled := TRUE;
GameRunning := TRUE;
GamePause := FALSE;
Cursor := -1;
Frames := 0;
InitData;
Randomize;
FormPaint(self);
end;
procedure TMainForm.RatTimerTimer(Sender: TObject);
var row, col : integer;
begin
{老鼠的显示}
Frames := Frames + 1;
FormPaint(Self);
PopupRats;
for row := 0 to 2 do
begin
for col := 0 to 2 do
begin
UpdateRats(row, col);
end;
end;
if LeftTime <= 0 then
begin
RatTimer.Enabled := FALSE;
Cursor := 0;
GameRunning := FALSE;
GamePause := FALSE;
MainForm.Canvas.Draw(0, 0, BackgroundBitmap);
end;
end;
procedure TMainForm.ScoreTimerTimer(Sender: TObject);
begin
LeftTime := LeftTime - 1; //剩余时间
end;
procedure TMainForm.cmPauseOrResumeClick(Sender: TObject);
begin
//Popup1中"暂停"和"恢复"菜单单击事件
if GameRunning = TRUE then
begin
if GamePause = FALSE then
begin
ScoreTimer.Enabled := FALSE;
RatTimer.Enabled := FALSE;
GamePause := TRUE;
Cursor := 0;
end
else
begin
ScoreTimer.Enabled := TRUE;
RatTimer.Enabled := TRUE;
GamePause := FALSE;
Cursor := -1;
end;
end;
end;
procedure TMainForm.FormShow(Sender: TObject);
begin
//游戏上半部分界面的显示位置
CtrlForm.Left := MainForm.Left + 69;
CtrlForm.Top := MainForm.Top - 100;
CtrlForm.Show;
end;
procedure TMainForm.RatMenuPopup(Sender: TObject);
begin
if GamePause = TRUE then
begin
cmPauseOrResume.Caption := '恢复';
cmPauseOrResume.Enabled := TRUE;
exit;
end;
if GameRunning = TRUE then
begin
cmPauseOrResume.Caption := '暂停';
cmPauseOrResume.Enabled := TRUE;
end
else
begin
cmPauseOrResume.Caption := '暂停';
cmPauseOrResume.Enabled := FALSE;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -