From aa19109f91d7b3816da357e6d7b019c91fb48441 Mon Sep 17 00:00:00 2001 From: skalogryz Date: Mon, 25 Jan 2010 21:32:47 +0000 Subject: [PATCH] iphonelazext: improve iArkanoid example, fixing ball bouncing bugs git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1141 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../examples/iArkanoid/gameengine.pas | 156 ++++++++++++++++-- 1 file changed, 138 insertions(+), 18 deletions(-) diff --git a/components/iphonelazext/examples/iArkanoid/gameengine.pas b/components/iphonelazext/examples/iArkanoid/gameengine.pas index 7258bbe35..b55cdbc10 100644 --- a/components/iphonelazext/examples/iArkanoid/gameengine.pas +++ b/components/iphonelazext/examples/iArkanoid/gameengine.pas @@ -15,7 +15,7 @@ unit gameengine; interface uses - Types, Classes, SysUtils; + Classes, SysUtils; const ballVelocity = 18; @@ -43,7 +43,6 @@ type protected procedure BoundsBack(const HitRect: TRect; var dx, dy: single); procedure BallMove(var move: TGameItem; atime: single); - procedure SetPaddleX(AValue: Integer); procedure ResetPaddle; public bricks : array [0..99] of TBrick; @@ -64,6 +63,21 @@ type property PaddleX: single read fPaddleX write SetPaddleX; end; +type + TMoveRecord = packed record + sx, sy : single; + dx, dy : single; + k : single; // y = kx + b + divk : single; + b : single; + end; + + THitSide = (hs_LeftRight, hs_TopBottom); + THitSides = set of THitSide; + +procedure InitMoveRecord(sx, sy, dx, dy: single; var r: TMoveRecord); +function HitRect(const r: TRect; const mr: TMoveRecord; var hitpoint: TPoint; var HitSides: THitSides): Boolean; + implementation { TArkanoid } @@ -81,7 +95,6 @@ begin fPaddleX := AValue; end; -// hacky test procedure TArkanoid.BoundsBack(const HitRect: TRect; var dx, dy: single); var my : Integer; @@ -91,6 +104,92 @@ begin else dx := -dx; end; +procedure InitMoveRecord(sx, sy, dx, dy: single; var r: TMoveRecord); +var + diff : single; +begin + r.sx:=sx; + r.sy:=sy; + r.dx:=dx; + r.dy:=dy; + diff:=dx-sx; + + //todo: + if diff<>0 then begin + r.k:=(dy-sy) / diff; + if r.k<>0 then r.divk:=1/r.k + else r.divk:=0; + end else begin + r.k:=0; + r.divk:=0; + end; + r.b:=sy-sx*r.k; +end; + +function InRange(p, r1,r2: Integer): Boolean; overload; inline; +begin + if r1=r1) and (p=r2) and (p=r1) and (p=r2) and (p= Top) and (ch < Bottom); + if hitside then begin + hitpoint:=Point(c, ch); + Include(HitSides, hs_LeftRight) + end; + + if sy<=dy then begin + c:=Top + end else begin + c:=Bottom; + end; + + if k <> 0 then + ch:=Round((c-b)/k) + else + ch:=Round(sx); + + hittop:=inRange(c, sy, dy) and (ch>=Left) and (ch 0) and PtInRect(bricks[i].hitRect, p) then begin - BoundsBack(bricks[i].bounds, dx, dy); - bricks[i].flash:=2; - dec(bricks[i].health); + hitidx:=-1; + hitlen:=0; + for i := 0 to brickCount - 1 do begin + if (bricks[i].health > 0) and HitRect(bricks[i].bounds, mr, hpnt, hsides) then begin + hlen:=SqrLen(hpnt, p); + if (hitidx<0) or (hlen=0 then begin + if hs_TopBottom in hitsides then move.dy:=-move.dy; + if hs_LeftRight in hitsides then move.dx:=-move.dx; + bricks[hitidx].flash:=2; + cx:=hitpnt.x; + cy:=hitpnt.y; + dec(bricks[hitidx].health); + end; if (cy >= PaddleY-5) and (cx >= PaddleX) and (cx <= PaddleX + PaddleW) and (dy>0) then begin t := (cx - PaddleX - PaddleW/2) / (PaddleW/2); @@ -152,10 +276,6 @@ begin end; end; -procedure TArkanoid.SetPaddleX(AValue: Integer); -begin - -end; procedure TArkanoid.ResetPaddle; var @@ -168,12 +288,12 @@ begin ballcount := 1; for i := 0 to ballcount - 1 do with Balls[i] do begin - {x := random(height-40)+20; - y := random(width-40)+20;} x := PaddleX+PaddleW/2; y := PaddleY-5; - a := random*pi/4 + (pi/2 - pi/8); - if cos(a)*5 < 0.1 then a := a + pi/5; + //a := random*pi/4 + (pi/2 - pi/8); + //if cos(a)*5 < 0.1 then a := a + pi/5; + //a:=5*pi/4; + a:=3*pi/2; dx := ballVelocity*cos(a); dy := ballVelocity*sin(a); sticked:=true;