Так выглядит наша игра. Цель игры собирать группы шариков одного цвета, меняя местами рядом стоящие. Как только в группе набирается 4 или больше шаров. они лопаются, за каждый шар прибавляются очки, а место лопнувших шаров занимают новые. На обдумывание хода изначально даётся 1 минута, каждый результативный ход прибавляет 10 секунд. Помощь компьютера отнимает 20 секунд времени, в случае если компьютеру удастся найти результативный ход, в противном случае вы получаете бонус 20 секунд и убираются 5 случайных шаров. После 2 минут игры шары начинают хаотично двигаться внутри своих клеток, что несколько усложняет игру. В режиме паузы шары обесцвечиваются, что предотвращает обдумывание очередного хода во время паузы.
Программа написана на Delphi без использования сторонних модулей. Демонстрирует примитивные методы работы с графикой. Будет полезна новичкам при освоении приёмов работы с графикой. Итак начнём. Раздел INTERFACE выглядит следующим образом:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Menus,DrawProc, DateUtils, StdCtrls, ExtCtrls;
type
TGameMode = (gmPlay,gmPause,gmScore,gmInput,gmHint,gmNull);
TForm1 = class(TForm)
pbMap: TPaintBox;
MainMenu1: TMainMenu;
File1: TMenuItem;
Timer1: TTimer;
Timer2: TTimer;
N1: TMenuItem;
N2: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N6: TMenuItem;
N9: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure pbMapMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Timer2Timer(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure pbMapMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure HelpComp;
procedure N4Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N9Click(Sender: TObject);
procedure N6Click(Sender: TObject);
private
{ Private declarations }
BitMap : TBitMap;
BallMap,BallMapGray : TBitmap;
DescMap : TBitMap;
GameMode : TGameMode;
procedure NewGame;
procedure ProcessGame(Mode : TGameMode);
public
{ Public declarations }
end;
var
Form1: TForm1;
Map : TArrayMap;
MapXY,ActiveBall : TPoint;
Spark : TArraySparks;
Rotate : byte;
Score : Integer;
SaveToScore,LockScore,GameProcess,GamePause,HelpHint : Boolean;
GameTime,TotalTime: TDateTime;
idTime:byte;
ShowHint:Boolean;
PathToScore:String;
ScoreList : TScore;
DescTopIndex,PauseIndex,ExitIndex,FarIndex,NewIndex,PauseBlend:byte;
List : TScore;
Как видно используется минимум компонентов: два таймера, главное меню и компонент пэйнтбокс. Этого вполне достаточно, весь остальной функционал реализуется ручками. Весь функционал игры находится в событии 1-го таймера, интервал срабатывания которого выставлен 25мс
procedure TForm1.Timer1Timer(Sender: TObject);
var Place,i : byte;
begin
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++base thread}
ProcessGame(GameMode);
case GameMode of
gmHint : if not HelpHint then begin
DrawHint(BitMap);
DrawButton(BitMap,DescMap,FarIndex,3,Point(FarX,FarY));
end else begin
HelpHint:=true;
GameMode:=gmPlay;
HelpComp;
end;
gmPlay : begin
Inc(idTime,1);
if idTime>39 then begin
idTime:=0;
TotalTime:=IncSecond(TotalTime);
if MinuteOf(TotalTime)>1 then GameLevel:=3;
GameTime:=IncSecond(GameTime,-1);
if (SecondOf(GameTime)=0)and (MinuteOf(GameTime)=0) then GameMode:=gmInput;
end;
end;
gmInput : begin
GameMode:=gmNull;
LoadFromFile(List,PathToScore);
Place:=11;
for i:=1 to 10 do
If (List.Score[i]<Score)and(I<Place) then
Place:=I;
if Place<10 then
for i:=9 downto Place do begin
List.Score[i+1]:=List.score[i];
List.List[i+1]:=List.List[i];
List.Time[i+1]:=List.Time[i];
end;
if Place<11 then begin
List.Score[Place]:=Score;
List.Time[Place]:=TotalTime;
List.List[Place]:=Copy(InputBox('Поздравляю!','Введите ваше имя',''),1,25);
SaveToFile(List,PathToScore);
end;
GameMode:=gmScore;
end;
gmScore : begin
DrawTable(BitMap,List);
DrawButton(BitMap,DescMap,FarIndex,3,Point(FarX,FarY));
end;
gmPause : begin
Inc(idTime,1);
if idTime mod 10=0 then begin
if PauseBlend=1 then PauseBlend:=0
else PauseBlend:=1;
idTime:=0;
end;
end;
end;
BitBlt(pbMap.Canvas.Handle,0,0,pbMap.Width,pbMap.Height,BitMap.Canvas.Handle,0,0,srcCopy);
If Check(Map,Point(0,0),Point(0,0)) Then begin
CreateSparks(Map,Spark);
if not LockScore then begin
Score:=Score+DeleteChecked(Map);
end else begin
LockScore:=false;
DeleteChecked(Map);
end;
end;
end;
За отрисовку основного поля отвечает процедура ProcessGame, которая в качестве параметра принимает переменную Mode. В зависимости от значения параметра отрисовываются цветные или серые шарики.
procedure TForm1.ProcessGame(Mode : TGameMode);
begin
DrawFon(BitMap);
CalcPosBall(Map);
CalcSpark(Spark);
DrawSparks(BitMap,BallMap,Spark);
if Mode=gmPause then
DrawBall(BitMap,BallMapGray,Map,Rotate)
else begin
DrawBall(BitMap,BallMap,Map,Rotate);
PauseBlend:=0;
end;
DrawScore(BitMap,BallMap,Score);
if Rotate>0 then DrawRotate(Rotate,BitMap,BallMap,Map,ActiveBall,MapXY);
DrawTime(BitMap,BallMap,GameTime);
DrawButton(BitMap,DescMap,DescTopIndex,0,Point(DescTopX,DescTopY));
if PauseIndex=1 then
DrawButton(BitMap,DescMap,PauseIndex,1,Point(PauseX,PauseY))
else
DrawButton(BitMap,DescMap,PauseBlend,1,Point(PauseX,PauseY));
DrawButton(BitMap,DescMap,ExitIndex,2,Point(ExitX,ExitY));
DrawButton(BitMap,DescMap,NewIndex,4,Point(NewX,NewY));
if Rotate>0 then Inc(Rotate,3);
If Rotate>30 then begin
Rotate:=0;
ClearActive(Map);
ActiveBall:=Point(0,0);
end;
end;
продолжение следует...
Скачать исходник игры + ресурсы + EXE файл MovingBall.zip 10.26MB