blocks.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. unit blocks;
  2. {$mode objfpc}
  3. interface
  4. uses gdk,gtk,classes;
  5. type
  6. TBlockList = Class;
  7. TBreakOut = Class;
  8. TGraphicalObject = Class(TObject)
  9. FRect : TGdkRectangle;
  10. Public
  11. Function Contains(X,Y : Integer) : Boolean;
  12. Property Left : SmallInt Read FRect.x Write Frect.x;
  13. Property Top : SmallInt Read FRect.y Write Frect.y;
  14. Property Width : Word Read Frect.Width Write Frect.Width;
  15. Property Height : Word Read Frect.Height Write Frect.Height;
  16. end;
  17. TBlock = Class(TGraphicalObject)
  18. Private
  19. FMaxHits : Integer;
  20. FBlockList : TBlockList;
  21. FGC : PGDKGC;
  22. FColor : PGDKColor;
  23. FNeedRedraw : Boolean;
  24. Procedure CreateGC;
  25. Function DrawingArea : PGtkWidget;
  26. Function PixMap : PgdkPixMap;
  27. Public
  28. Procedure Draw;
  29. Function Hit : Boolean;
  30. Constructor Create (ABlockList : TBlockList);
  31. Property Color : PGDKColor Read FColor Write FColor;
  32. end;
  33. TSprite = Class(TGraphicalObject)
  34. FPreviousTop,
  35. FPreviousLeft : Integer;
  36. FDrawingArea : PGtkWidget;
  37. FDrawPixMap : PgdkPixmap;
  38. FPixMap : PgdkPixMap;
  39. FBitMap : PGdkBitMap;
  40. Protected
  41. Procedure CreateSpriteFromData(SpriteData : PPGchar);
  42. Procedure CreatePixMap; Virtual; Abstract;
  43. Procedure SavePosition;
  44. Public
  45. Constructor Create(DrawingArea: PGtkWidget);
  46. Procedure Draw;
  47. Function GetChangeRect (Var Rect : TGDkRectAngle) : Boolean;
  48. Property PixMap : PgdkPixMap Read FPixMap;
  49. Property BitMap : PGdkBitMap Read FBitMap;
  50. end;
  51. TPad = Class (TSprite)
  52. Private
  53. FSlope,
  54. FSpeed,FCurrentSpeed : Integer;
  55. Protected
  56. Procedure CreatePixMap; override;
  57. Procedure InitialPosition;
  58. Public
  59. Constructor Create(DrawingArea: PGtkWidget);
  60. Procedure Step;
  61. Procedure GoLeft;
  62. Procedure GoRight;
  63. Procedure Stop;
  64. Property CurrentSpeed : Integer Read FCurrentSpeed;
  65. Property Speed : Integer Read FSpeed Write FSpeed;
  66. Property Slope : Integer Read FSlope Write FSlope;
  67. end;
  68. TBall = Class (TSprite)
  69. Private
  70. FBreakOut : TBreakOut;
  71. FCurrentSpeedX,
  72. FCurrentSpeedY : Integer;
  73. FSpeedfactor : Integer;
  74. Protected
  75. Procedure CreatePixMap; override;
  76. Procedure SetSpeed(Value : Integer);
  77. Public
  78. Constructor Create(BreakOut : TBreakOut);
  79. Procedure Step;
  80. Procedure IncSpeed (Value: Integer);
  81. Procedure FlipSpeed (FlipX,FlipY : Boolean);
  82. Property CurrentSpeedX : Integer Read FCurrentSpeedX Write SetSpeed;
  83. Property CurrentSpeedY : Integer Read FCurrentSpeedY;
  84. Property SpeedFactor : INteger Read FSpeedFactor Write FSpeedFactor;
  85. end;
  86. TBlockList = Class (TList)
  87. FTotalRows,FTotalColums,FStartRow,FBlockRows,FSpacing : Byte;
  88. FBreakOut : TBreakOut;
  89. FColor : PGDKColor;
  90. Function DRawingArea : PGTKWidget;
  91. FPixMap : PGDKPixmap;
  92. Public
  93. Constructor Create(BreakOut : TBreakOut);
  94. Destructor Destroy; override;
  95. Procedure CheckCollision (Ball: TBall);
  96. Procedure DrawBlocks;
  97. Procedure DrawBlocks(Const Area : TGdkRectangle);
  98. Procedure CreateBlocks;
  99. Procedure FreeBlocks;
  100. Property TotalRows : Byte Read FTotalRows Write FTotalRows;
  101. Property TotalColumns : Byte Read FTotalColums Write FTotalColums;
  102. Property StartRow : Byte Read FStartRow Write FStartRow;
  103. Property BlockRows : Byte Read FBlockRows Write FBlockRows;
  104. Property BlockSpacing : Byte Read FSpacing Write FSpacing;
  105. Property PixMap : PGDKPixMap Read FPixMap Write FPixMap;
  106. end;
  107. TBreakOut = Class(TObject)
  108. Private
  109. FLevel : Integer;
  110. FBalls : Integer;
  111. FBGGC : PGDKGC;
  112. FBackGroundColor : PGDKColor;
  113. FPad : TPad;
  114. FBall : TBall;
  115. FBlockList : TBlockList;
  116. FDrawingArea : PGTKWidget;
  117. FPixMap : PGDKPixMap;
  118. Procedure DrawBackGround (Area : TGdkrectAngle);
  119. Procedure DrawBoard(Exposed : PGdkEventExpose);
  120. Procedure CreateGC;
  121. Procedure CreatePixMap;
  122. Procedure CopyPixMap(Area : TGdkRectangle);
  123. Procedure CheckCollision;
  124. Procedure FreeBall;
  125. Procedure NextLevel;
  126. Procedure NextBall;
  127. Procedure GameOver;
  128. Procedure LostBall;
  129. Procedure Redrawgame;
  130. Public
  131. Constructor Create (DrawingArea : PGtkWidget);
  132. Procedure Draw(Exposed : PGDKEventExpose);
  133. Procedure Step;
  134. Property BlockList : TBlockList Read FBlockList;
  135. Property Pad : TPad Read FPad;
  136. Property Level : Integer Read Flevel;
  137. Property Balls : Integer Read FBalls Write FBalls;
  138. end;
  139. Const
  140. HitAccelleration = 1;
  141. LevelAccelleration = 2;
  142. FMaxXspeed = 90;
  143. implementation
  144. { ---------------------------------------------------------------------
  145. TGraphicalObject implementation
  146. ---------------------------------------------------------------------}
  147. Function TGraphicalObject.Contains(X,Y : Integer) : Boolean;
  148. begin
  149. Result:=((X>=Left) and (X<Left+Width)) and
  150. ((Y>=top) and (Y<Top+Width));
  151. end;
  152. { ---------------------------------------------------------------------
  153. TBlock implementation
  154. ---------------------------------------------------------------------}
  155. Constructor TBlock.Create (ABlockList : TBlockList);
  156. begin
  157. Inherited Create;
  158. FBlockList:=ABlockList;
  159. FMaxHits:=1;
  160. end;
  161. Function TBlock.DrawingArea : PGtkWidget;
  162. begin
  163. Result:=FBlockList.FBreakout.FDrawingArea;
  164. end;
  165. Function TBlock.PixMap : PgdkPixMap;
  166. begin
  167. Result:=FBlockList.PixMap;
  168. end;
  169. Procedure TBlock.CreateGC;
  170. begin
  171. FGC:=gdk_gc_new(DrawingArea^.Window);
  172. gdk_gc_set_foreground(FGC,FColor);
  173. gdk_gc_set_fill(FGC,GDK_SOLID);
  174. FNeedRedraw:=True;
  175. end;
  176. Procedure TBlock.Draw;
  177. begin
  178. if FGC=Nil then
  179. CreateGC;
  180. if FNeedRedraw Then
  181. begin
  182. gdk_draw_rectangle(PGDKDrawable(Pixmap),FGC,-1,Left,Top,Width,Height);
  183. FNeedRedraw:=False;
  184. end;
  185. end;
  186. Function TBlock.Hit : Boolean;
  187. begin
  188. Dec(FMaxHits);
  189. Result:=FMaxHits=0;
  190. If Result then
  191. begin
  192. FBlockList.FBreakOut.DrawBackground(FRect);
  193. FBlockList.Remove(Self);
  194. Free;
  195. end;
  196. end;
  197. { ---------------------------------------------------------------------
  198. TBlockList implementation
  199. ---------------------------------------------------------------------}
  200. Constructor TBlockList.Create(BreakOut : TBreakOut);
  201. begin
  202. FBreakOut:=BreakOut;
  203. end;
  204. Function TBlockList.DrawingArea : PGtkWidget;
  205. begin
  206. Result:=FBreakOut.FDrawingArea;
  207. end;
  208. Destructor TBlockList.Destroy;
  209. begin
  210. If FColor<>Nil then
  211. FreeMem(FColor);
  212. FreeBlocks;
  213. end;
  214. Procedure TBlockList.DrawBlocks;
  215. Var
  216. I : Longint;
  217. begin
  218. If Count=0 then
  219. CreateBlocks;
  220. For I:=0 to Count-1 do
  221. TBlock(Items[i]).draw;
  222. end;
  223. Procedure TBlockList.DrawBlocks (Const Area : TGdkRectangle);
  224. Var
  225. i : longint;
  226. inters : TgdkRectangle;
  227. begin
  228. For I:=0 to Count-1 do
  229. With TBlock(Items[i]) do
  230. FNeedRedraw:=gdk_rectangle_intersect(@area,@Frect,@inters)<>0;
  231. DrawBlocks;
  232. end;
  233. Function AllocateColor(R,G,B : Integer; Widget : PGtkWidget) : PGdkColor;
  234. begin
  235. Result:=New(PgdkColor);
  236. With Result^ do
  237. begin
  238. Pixel:=0;
  239. Red:=R;
  240. Blue:=B;
  241. Green:=G;
  242. end;
  243. gdk_colormap_alloc_color(gtk_widget_get_colormap(Widget),Result,true,False);
  244. end;
  245. Procedure TBlockList.CreateBlocks;
  246. Var
  247. TotalHeight,TotalWidth,
  248. Cellheight,CellWidth,
  249. I,J : Integer;
  250. Block : TBlock;
  251. Min : Byte;
  252. begin
  253. FColor:=AllocateColor(0,0,$ffff,DrawingArea);
  254. Min:=FSpacing div 2;
  255. If Min<1 then
  256. Min:=1;
  257. TotalWidth:=Drawingarea^.Allocation.Width;
  258. TotalHeight:=DrawingArea^.Allocation.Height;
  259. Cellheight:=TotalHeight Div TotalRows;
  260. CellWidth:=TotalWidth div TotalColumns;
  261. For I:=StartRow to StartRow+BlockRows-1 do
  262. For J:=0 to TotalColumns-1 do
  263. begin
  264. Block:=TBlock.Create(Self);
  265. With Block do
  266. begin
  267. Top:=TotalHeight-(CellHeight*I)+Min;
  268. Left:=(CellWidth*J)+min;
  269. Width:=CellWidth-2*min;
  270. Height:=CellHeight-2*min;
  271. Color:=Self.FColor;
  272. FNeedRedraw:=True;
  273. end;
  274. add(Block);
  275. end;
  276. end;
  277. Procedure TBlockList.FreeBlocks;
  278. Var
  279. I : longint;
  280. begin
  281. For I:=Count-1 downto 0 do
  282. begin
  283. TBlock(Items[i]).Free;
  284. Delete(i);
  285. end;
  286. end;
  287. Procedure TBlockList.CheckCollision (Ball: TBall);
  288. var
  289. brect,ints : tgdkrectangle;
  290. B : TBlock;
  291. i : integer;
  292. flipx,flipy : Boolean;
  293. begin
  294. For I:=Count-1 downto 0 do
  295. begin
  296. B:=TBlock(Items[i]);
  297. BRect:=B.FRect;
  298. if gdk_rectangle_intersect(@Ball.Frect,@BRect,@ints)<>0 then
  299. begin
  300. FlipY:=((Ball.FpreviousTop>=(B.Top+B.Height)) and (Ball.CurrentSpeedY<0)) or
  301. ((Ball.FpreviousTop+Ball.Height<=B.Top) and (Ball.CurrentSpeedY>0));
  302. FlipX:=Not FlipY;
  303. If FlipX then
  304. FlipX:=((Ball.FPreviousLeft>=(B.Left+B.Width)) and (Ball.CurrentSpeedX<0)) or
  305. (((Ball.FPreviousLeft+Ball.Width)<=B.Left) and (Ball.CurrentSpeedX>0));
  306. Ball.FlipSpeed(FlipX,Flipy);
  307. if B.Hit and not (Count=0) then
  308. gtk_widget_draw(DrawingArea,@BRect);
  309. Break;
  310. end;
  311. end;
  312. end;
  313. { ---------------------------------------------------------------------
  314. TSprite implementation
  315. ---------------------------------------------------------------------}
  316. Constructor TSprite.Create(DrawingArea: PGtkWidget);
  317. begin
  318. Inherited Create;
  319. FDrawingArea:=DrawingArea;
  320. end;
  321. Procedure TSprite.CreateSpriteFromData(SpriteData : PPGChar);
  322. begin
  323. FPixMap:=gdk_pixmap_create_from_xpm_d(FDrawingArea^.Window,
  324. @FBitmap,
  325. Nil,
  326. SpriteData);
  327. end;
  328. Procedure TSprite.Draw;
  329. Var
  330. gc : PGDKGc;
  331. begin
  332. if FPixMap=Nil then
  333. CreatePixMap;
  334. gc:=gtk_widget_get_style(FDrawingArea)^.fg_gc[GTK_STATE_NORMAL];
  335. gdk_gc_set_clip_origin(gc,Left,Top);
  336. gdk_gc_set_clip_mask(gc,FBitmap);
  337. if FDrawPixMap<>Nil then
  338. gdk_draw_pixmap(FDrawPixMap,gc,FPixMap,0,0,Left,Top,Width,Height)
  339. else
  340. gdk_draw_pixmap(FDrawPixMap{FDrawingArea^.window},gc,FPixMap,0,0,Left,Top,Width,Height);
  341. gdk_gc_set_clip_mask(gc,Nil);
  342. end;
  343. Function TSprite.GetChangeRect (Var Rect : TGDkRectAngle) : Boolean;
  344. begin
  345. Result:=(FPreviousLeft<>Left) or (FPreviousTop<>Top);
  346. If Result then
  347. With Rect do
  348. begin
  349. x:=FPreviousLeft;
  350. y:=FPreviousTop;
  351. Width:=Abs(Left-FPreviousLeft)+self.Width;
  352. height:=Abs(Top-FPreviousTop)+self.Height;
  353. end;
  354. end;
  355. Procedure TSprite.SavePosition;
  356. begin
  357. FPreviousLeft:=Left;
  358. FPreviousTop:=Top;
  359. end;
  360. { ---------------------------------------------------------------------
  361. TPad implementation
  362. ---------------------------------------------------------------------}
  363. Const
  364. PadHeight = 10;
  365. PadWidth = 40;
  366. PadBitmap : Array[1..13] of pchar = (
  367. '40 10 2 1',
  368. ' c none',
  369. 'x c #ff0000',
  370. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  371. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  372. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  373. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  374. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  375. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  376. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  377. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  378. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  379. 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  380. );
  381. Constructor TPad.Create(DrawingArea: PGtkWidget);
  382. begin
  383. Inherited Create(DrawingArea);
  384. FSpeed:=6;
  385. FSlope:=50;
  386. end;
  387. Procedure TPad.CreatePixMap;
  388. begin
  389. CreateSpriteFromData(@PadBitmap[1]);
  390. Width:=PadWidth;
  391. Height:=PadHeight;
  392. InitialPosition;
  393. end;
  394. Procedure TPad.InitialPosition;
  395. begin
  396. Left:=(FDrawingArea^.Allocation.Width-Width) div 2;
  397. Top:=FDrawingArea^.Allocation.Height-(2*Height);
  398. FCurrentSpeed:=0;
  399. end;
  400. Procedure TPad.Step;
  401. begin
  402. SavePosition;
  403. Left:=Left+FCurrentSpeed;
  404. if Left<=0 then
  405. begin
  406. FCurrentSpeed:=-FCurrentSpeed;
  407. Left:=0;
  408. end
  409. else if Left+Width>=FDrawingArea^.allocation.width then
  410. begin
  411. FCurrentSpeed:=-FCurrentSpeed;
  412. Left:=FDrawingArea^.allocation.width-Width;
  413. end;
  414. end;
  415. Procedure TPad.GoLeft;
  416. begin
  417. FCurrentSpeed:=-FSpeed;
  418. end;
  419. Procedure TPad.GoRight;
  420. begin
  421. FCurrentSpeed:=FSpeed;
  422. end;
  423. Procedure TPad.Stop;
  424. begin
  425. FCurrentSpeed:=0;
  426. end;
  427. { ---------------------------------------------------------------------
  428. TBall implementation
  429. ---------------------------------------------------------------------}
  430. Const
  431. BallHeight = 10;
  432. BallWidth = 10;
  433. BallBitmap : Array[1..13] of pchar = (
  434. '10 10 2 1',
  435. ' c none',
  436. 'x c #ffffff',
  437. ' xx ',
  438. ' xxxxxx ',
  439. ' xxxxxxxx ',
  440. ' xxxxxxxx ',
  441. 'xxxxxxxxxx',
  442. 'xxxxxxxxxx',
  443. ' xxxxxxxx ',
  444. ' xxxxxxxx ',
  445. ' xxxxxx ',
  446. ' xx '
  447. );
  448. Constructor TBall.Create(BreakOut : TBreakOut);
  449. begin
  450. Inherited Create(BreakOut.FDrawingArea);
  451. FBreakOut:=breakout;
  452. FCurrentSpeedY:=-100;
  453. FCurrentSpeedX:=0;
  454. FSpeedFactor:=10;
  455. end;
  456. Procedure TBall.CreatePixMap;
  457. begin
  458. CreateSpriteFromData(@BallBitmap[1]);
  459. Width:=BallWidth;
  460. Height:=BallHeight;
  461. end;
  462. Procedure TBall.Step;
  463. begin
  464. SavePosition;
  465. Left :=Left + Round((FCurrentSpeedX*FSpeedFactor/100));
  466. Top :=Top + Round((FCurrentSpeedY*FSpeedFactor/100));
  467. if Left<=1 then
  468. begin
  469. FlipSpeed(True,False);
  470. Left:=1;
  471. end
  472. else if Left+Width>=FDrawingArea^.allocation.width then
  473. begin
  474. FlipSpeed(True,False);
  475. Left:=FDrawingArea^.allocation.width-Width-1;
  476. end;
  477. if Top<=1 then
  478. begin
  479. FlipSpeed(False,True);
  480. Top:=1;
  481. end
  482. else if Top+Height>=FDrawingArea^.allocation.Height then
  483. FBreakOut.LostBall
  484. end;
  485. Procedure TBall.SetSpeed(Value : Integer);
  486. begin
  487. If Value<-FMaxXspeed then
  488. Value:=-FMaxXSpeed
  489. else if Value>FMaxXspeed then
  490. Value:=FMaxXspeed;
  491. FCurrentSpeedX:=Value;
  492. If FCurrentSpeedY>0 then
  493. FCurrentSpeedY:=100-Abs(FCurrentSpeedX)
  494. else
  495. FCurrentSpeedY:=-100+Abs(FCurrentSpeedX);
  496. end;
  497. Procedure TBall.IncSpeed (Value: Integer);
  498. begin
  499. FSpeedFactor:=FSpeedFactor+Value;
  500. If FSpeedFactor<10 then
  501. FSpeedFactor:=10;
  502. end;
  503. Procedure TBall.FlipSpeed (FlipX,FlipY : Boolean);
  504. begin
  505. If FlipX then
  506. FCurrentSpeedX:=-FCurrentSpeedX;
  507. If FlipY then
  508. FCurrentSpeedY:=-FCurrentSpeedY;
  509. end;
  510. { ---------------------------------------------------------------------
  511. TBreakout implementation
  512. ---------------------------------------------------------------------}
  513. Constructor TBreakOut.Create (DrawingArea : PGtkWidget);
  514. begin
  515. FDrawingArea:=DrawingArea;
  516. FBlockList:=TBlockList.Create (Self);
  517. FPad:=TPad.Create(FDrawingArea);
  518. FBalls:=5;
  519. end;
  520. Procedure TBreakOut.CheckCollision;
  521. Var
  522. Inters :TGdkrectangle;
  523. begin
  524. If Assigned(FBall) then
  525. begin
  526. if gdk_rectangle_intersect(@FBall.FRect,@FPad.Frect,@inters)<>0 then
  527. If (FBall.FPreviousTop<FPad.Top) and (FBall.FCurrentSpeedY>0) then
  528. begin
  529. FBall.FlipSpeed(False,True);
  530. If (FPad.CurrentSpeed<>0) then
  531. if (FBall.FCurrentSpeedX*FPad.CurrentSpeed)>0 then
  532. FBall.IncSpeed(HitAccelleration)
  533. else
  534. FBall.IncSpeed(-HitAccelleration);
  535. FBall.CurrentSpeedX:=FBall.CurrentSpeedX+(Round(((FBall.Left+(FBall.Width div 2)) - (FPad.left+Fpad.Width div 2)) * (FPad.Slope / 100)));
  536. end;
  537. FBlockList.CheckCollision(FBall);
  538. end;
  539. end;
  540. Procedure TBreakOut.Step;
  541. begin
  542. FPad.Step;
  543. If Assigned(FBall) then
  544. FBall.Step;
  545. CheckCollision;
  546. If FBlockList.Count=0 then
  547. NextLevel;
  548. if Not Assigned(FBall) and (FBalls=0) then
  549. GameOver;
  550. end;
  551. Procedure TBreakOut.CreateGC;
  552. begin
  553. FBGGC:=gdk_gc_new(FDrawingArea^.Window);
  554. FBackGroundColor:=AllocateColor(0,0,0,FDrawingArea);
  555. gdk_gc_set_foreground(FBGGC,FBackGroundColor);
  556. gdk_gc_set_fill(FBGGC,GDK_SOLID);
  557. end;
  558. Procedure TBreakOut.DrawBackGround (Area : TGdkrectAngle);
  559. begin
  560. With Area do
  561. begin
  562. gdk_draw_rectangle(PGDKDrawable(FPixMap),FBGGC,-1,x,y,Width+1,Height+1);
  563. end;
  564. end;
  565. Procedure TBreakOut.DrawBoard(Exposed : PGdkEventExpose);
  566. begin
  567. If FBGGC=Nil then
  568. begin
  569. CreateGC;
  570. end;
  571. DrawBackGround(Exposed^.Area);
  572. end;
  573. Procedure TBreakOut.CreatePixMap;
  574. begin
  575. If FPixMap<>Nil then
  576. GDK_pixmap_unref(FPixMap);
  577. With FDrawingArea^ do
  578. FPixMap:=gdk_pixmap_new(Window,Allocation.Width,Allocation.Height,-1);
  579. FBlockList.PixMap:=FPixMap;
  580. FPad.FDrawPixMap:=FPixMap;
  581. If Assigned(FBall) then
  582. FBall.FDrawPixMap:=FPixMap;
  583. end;
  584. Procedure TBreakOut.CopyPixMap(Area : TGdkRectangle);
  585. begin
  586. gdk_draw_pixmap(FDrawingArea^.Window,
  587. gtk_widget_get_style(FDrawingArea)^.fg_gc[GTK_WIDGET_STATE(FDrawingArea)],
  588. FPixMap,
  589. area.x,area.y,
  590. area.x,area.y,
  591. area.width,area.height);
  592. end;
  593. Procedure TBreakOut.Draw(Exposed : PGDKEventExpose);
  594. Var
  595. Rect : TGdkRectangle;
  596. begin
  597. if FPixMap=Nil then
  598. CreatePixMap;
  599. // draw whatever needed on pixmap.
  600. if Exposed<>Nil then
  601. begin
  602. DrawBoard(Exposed);
  603. FBlockList.DrawBlocks(exposed^.area)
  604. end
  605. else
  606. begin
  607. If Assigned(FBall) then
  608. if FBall.GetChangeRect(Rect) then
  609. begin
  610. DrawBackground(Rect);
  611. FBLockList.drawBlocks(Rect);
  612. end;
  613. if FPad.GetChangeRect(Rect) then
  614. DrawBackground(Rect)
  615. end;
  616. FPad.Draw;
  617. if Assigned(FBall) Then
  618. FBall.draw;
  619. If Exposed<>Nil then
  620. CopyPixMap(Exposed^.Area);
  621. If assigned(FBall) then
  622. if FBall.GetChangeRect(Rect) then
  623. CopyPixMap(Rect);
  624. if FPad.GetChangeRect(Rect) then
  625. CopyPixMap(Rect);
  626. IF Assigned(FBall) then
  627. CopyPixMap(FBall.FRect);
  628. CopyPixMap(FPad.FRect);
  629. end;
  630. Procedure TBreakout.Redrawgame;
  631. Var
  632. Rect : TgdkRectangle;
  633. begin
  634. Rect.X:=FDrawingArea^.allocation.x;
  635. Rect.Y:=FDrawingArea^.allocation.y;
  636. Rect.Width:=FDrawingArea^.allocation.Width;
  637. Rect.Height:=FDrawingArea^.allocation.Height;
  638. gtk_Widget_draw(FDrawingArea,@rect)
  639. end;
  640. Procedure TBreakOut.FreeBall;
  641. begin
  642. FBall.Free;
  643. FBall:=Nil;
  644. end;
  645. Procedure TbreakOut.NextBall;
  646. begin
  647. If FBall=Nil then
  648. begin
  649. FBall:=TBall.Create(Self);
  650. FBall.Top:=FPad.Top-1;
  651. FBall.Left:=FPad.Left + (FPad.Width div 2);
  652. FBall.CurrentSpeedX:=FPad.CurrentSpeed*5;
  653. FBall.FPreviousTop:=FBall.Top;
  654. FBall.FPreviousLeft:=FBall.Left;
  655. FBall.FDrawPixMap:=Self.FPixMap;
  656. FBall.Draw;
  657. end;
  658. end;
  659. Procedure TBreakOut.NextLevel;
  660. Var
  661. Area : TGdkRectangle;
  662. begin
  663. If Assigned(FBall) then
  664. FreeBall;
  665. FPad.FSpeed:=FPad.Speed+LevelAccelleration;
  666. FPad.InitialPosition;
  667. RedrawGame;
  668. end;
  669. Procedure TBreakout.LostBall;
  670. begin
  671. Dec(FBalls);
  672. If FBalls=0 then
  673. GameOver;
  674. FreeBall;
  675. Fpad.InitialPosition;
  676. RedrawGame;
  677. end;
  678. Procedure TBreakout.GameOver;
  679. begin
  680. end;
  681. end.