![]() |
AW: Problem mit Multiplikation
Sei doch so gut und setze deinen Code in Delphi Tags, damit die Formatierung (sofern eine vorhanden) beibehalten bleibt. Das ist der Delphi-Helm in der Mitte von den Editor-Symbolen.
Dan sieht dein Quellcode nämlich so aus:
Delphi-Quellcode:
procedure TForm1.Testprocedure;
begin ShowMessage('Delphi TagsTest'); end; |
AW: Problem mit Multiplikation
Zitat:
Delphi-Quellcode:
Wieso funktioniert dein Beispiel nicht?
procedure TForm1.Button1Click(Sender: TObject);
Var Zahl : Single; S : String; begin S := Label1.Caption; Zahl := StrToFloat(S); Zahl := Zahl * -1; S := FloatToStr(Zahl); Label1.Caption := S; end; |
AW: Problem mit Multiplikation
Zitat:
In deinem Code muß es aber heißen:
Delphi-Quellcode:
Ball := TBall.Create(0,-1);
|
AW: Problem mit Multiplikation
Ob nun Integer oder Float macht doch hier überhaupt keinen Unterschied. Es wird ja nirgends ein Vergleich mit Konstanten gemacht, sondern nur gerechnet. Leider ist das noch immer ein wenig wenig Code. Es ist z.B. nicht ersichtlich, in welchem Scope sich die Variable "Ball" befindet, und beim fehlenden "end;" der Klassendeklaration hoffe ich, dass es wirklich einfach nur nicht mit kopiert wurde. Ich denke Bjoerk liegt schon mal ganz gut, seltsam ist jedoch, dass es bei dir dann keine Zugriffsfehler hagelt. Fazit: Die Erzeugung ist definitiv schon mal ein Fehler, aber leider immer noch zu wenig Kontext.
Zum Schluss noch ein kleiner Tipp. Man kann in case-Statements ganz nett Dinge zusammenfassen:
Delphi-Quellcode:
Ist Kosmetik, reduziert aber Arbeit bei Änderungen :)
procedure TBrick.onCollision(Edge: Integer; Ball: TBall);
begin case Edge of 1, 2: Ball.YSpeed := Ball.YSpeed * -1; 3, 4: Ball.XSpeed := Ball.XSpeed * -1; end; end; |
AW: Problem mit Multiplikation
So habe jetzt einige Umschichtungen bei meinem Code vorgenommen, das hat das Problem aber leider nicht gelöst, aber dafür ist er jetzt etwas übersichtlicher. Habe jetzt mal meine ganzen Units bis auf ein paar unwichtige Kommentare etc. reinkopiert. Wenn ich ein Integer statt Single verwende funktioniert es übrigens auch nicht.
Nochmal vielen Dank für die bisherigen Vorschläge.
Delphi-Quellcode:
unit ufrmBreakout;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, uCoords, uBrick, UPaddle, UBall; type TfrmBreakout = class(TForm) lblTime: TLabel; lblScore: TLabel; ptbGame: TPaintBox; TmrGame: TTimer; procedure FormCreate(Sender: TObject); procedure TimerTick(Sender: TObject); private bricks : TList; paddle : TPaddle; balls : TList; end; const BrickColumn = 8; BrickRows = 5; PaddleStartX = 192; PaddleStartY = 380; BallStartAngle = 90; var frmBreakout: TfrmBreakout; implementation {$R *.dfm} procedure TfrmBreakout.FormCreate(Sender: TObject); var Coords: TCoords; Brick: TBrick; x,y: Integer; xBall, yBall : Integer; begin //create the bricks bricks := TList.Create; for x := 0 to (BrickColumn-1) do begin for y := 0 to (BrickRows-1) do begin Coords := TCoords.Create(x*uBrick.BrickWidth,y*uBrick.BrickHeight); Brick := TBrick.Create(Coords); bricks.Add(Brick); end; end; //create the paddle Coords := TCoords.Create(PaddleStartX,PaddleStartY); paddle := TPaddle.Create(Coords); //create the ball xBall := PaddleStartX + (uPaddle.PaddleWidth div 2); yBall := PaddleStartY - UBall.BallRadius; Coords := TCoords.Create(xBall,yBall); balls := TList.Create; balls.Add(TBall.Create(Coords,BallStartAngle,0,-1)); end; procedure TfrmBreakout.TimerTick(Sender: TObject); var i, j : Integer; Ball: TBall; Brick: TBrick; begin for i := 0 to balls.Count-1 do begin Ball := balls[i]; for j := 0 to bricks.Count-1 do begin Brick := bricks[j]; Brick.Collide(Ball); end; Ball.Coords.X := Ball.Coords.X+round(Ball.XSpeed); Ball.Coords.Y := Ball.Coords.Y+round(Ball.YSpeed); lblScore.Caption := 'y: ' + FloatToStr(Ball.YSpeed); end; end; end.
Delphi-Quellcode:
unit uBrick;
interface uses uCoords, uBall; const BrickHeight = 32; BrickWidth = 64; type TBrick = Class private fCoords : TCoords; public Constructor Create(coords: TCoords); Destructor Destroy(); override; property Coords: TCoords read fCoords; procedure Collide(Ball: TBall); procedure onCollision(Edge: Integer; Ball: TBall); function RightX : Integer; function BottomY : Integer; end; implementation constructor TBrick.Create(coords: TCoords); begin self.fCoords := coords; end; destructor TBrick.Destroy; begin fCoords.Destroy(); inherited; end; function TBrick.RightX() : Integer; begin Result := (self.fCoords.X + BrickWidth); end; function TBrick.BottomY() : Integer; begin Result := (self.fCoords.Y + BrickHeight); end; procedure TBrick.Collide(Ball: TBall); begin if (Ball.Coords.X <= self.RightX()) and (Ball.Coords.X >= self.fCoords.X) and (Ball.Coords.Y = self.BottomY()) then begin OnCollision(1,Ball); end else if (Ball.Coords.X <= self.RightX()) and (Ball.Coords.X >= self.fCoords.X) and (Ball.Coords.Y = self.fCoords.Y) then begin OnCollision(2,Ball); end else if (Ball.Coords.Y <= self.BottomY()) and (Ball.Coords.Y >= self.fCoords.Y) and (Ball.Coords.X = self.fCoords.X) then begin OnCollision(3,Ball); end else if (Ball.Coords.Y <= self.BottomY()) and (Ball.Coords.Y >= self.fCoords.Y) and (Ball.Coords.X = self.RightX()) then begin OnCollision(4,Ball); end; end; procedure TBrick.onCollision(Edge : Integer; Ball : TBall); begin case Edge of 1: Ball.YSpeed := Ball.YSpeed * (-1); 2: Ball.YSpeed := Ball.YSpeed * (-1); 3: Ball.XSpeed := Ball.XSpeed * (-1); 4: Ball.XSpeed := Ball.XSpeed * (-1); end; end; end.
Delphi-Quellcode:
unit uBall;
interface uses uCoords, uCalculate; const BallRadius = 8; type TBall = Class private fCoords : TCoords; fDestCoords : TCoords; fAngle : Integer; fXSpeed : Single; fYSpeed : Single; public Constructor Create(coords: TCoords; angle: Integer; xspeed, yspeed : Single); Destructor Destroy(); override; property Coords: TCoords read fCoords; property DestCoords: TCoords read fDestCoords; property XSpeed: Single read fXSpeed write fXSpeed; property YSpeed: Single read fYSpeed write fYSpeed; end; implementation constructor TBall.Create(coords: TCoords; angle : Integer; xspeed, yspeed : Single); begin self.fCoords := coords; self.fAngle := angle; self.fXSpeed := xspeed; self.fYSpeed := yspeed; end; destructor TBall.Destroy; begin fCoords.Destroy(); inherited; end; end.
Delphi-Quellcode:
unit uCoords;
interface type TCoords = Class private fx : Integer; fy : Integer; public Constructor Create(x,y: Integer); Destructor Destroy(); override; property X: Integer read fx write fx; property Y: Integer read fy write fy; end; implementation constructor TCoords.Create(x,y: Integer); begin self.fx := x; self.fy := y; end; destructor TCoords.Destroy; begin inherited; end; end. |
AW: Problem mit Multiplikation
Hallo,
Dein Problem ist sicher nicht die Multiplikation; die arbeitet - wie schon gezeigt - korrekt. Das kannst Du auch leicht sehen, dazu musst Du nur Deinen Timercode etwas abändern:
Delphi-Quellcode:
Dann steht da auch irgendwann eine 1 - anstatt einer -1.
procedure TfrmBreakout.TimerTick(Sender: TObject);
var i, j : Integer; Ball: TBall; Brick: TBrick; begin for i := 0 to balls.Count-1 do begin Ball := balls[i]; for j := 0 to bricks.Count-1 do begin Brick := bricks[j]; Brick.Collide(Ball); lblScore.Caption := 'y: ' + FloatToStr(Ball.YSpeed); Application.ProcessMessages end; Ball.Coords.X := Ball.Coords.X+round(Ball.XSpeed); Ball.Coords.Y := Ball.Coords.Y+round(Ball.YSpeed); end; end; Gruß |
AW: Problem mit Multiplikation
Ich bin mir nicht sicher, hab grad keine IDE zum testen da, aber das da sieht für mich aus wie Durchfall:
Delphi-Quellcode:
Also in Java zumindest wird ohne ein break zwischendrin 1: und 2: (und 3: und 4: ) ausgeführt, was dann zur Folge hätte, dass es wieder das selbe Ergebnis wie davor ist.
procedure TBrick.onCollision(Edge : Integer; Ball : TBall);
begin case Edge of 1: Ball.YSpeed := Ball.YSpeed * (-1); 2: Ball.YSpeed := Ball.YSpeed * (-1); 3: Ball.XSpeed := Ball.XSpeed * (-1); 4: Ball.XSpeed := Ball.XSpeed * (-1); end; end; Oder gabs das in Delphi garnicht? |
AW: Problem mit Multiplikation
Nope, das ist schon richtig so.
|
AW: Problem mit Multiplikation
Zitat:
![]()
Delphi-Quellcode:
case x of
0..2 : y := -1; 1..3 : y := +1; end; |
AW: Problem mit Multiplikation
Zitat:
Das ist einer der größten Designfehler in C/C++/Java/PHP meiner Meinung nach... Wann braucht man das Fallthrough schon mal? Einmal in hundert Jahren? Und wie oft vergisst man auf der anderen Seite einfach ein break und hat einen schwer zu findenden Bug? Aber die Vermutung, dass der Code irgendwie doppelt ausgeführt wird, ist naheliegend. Ich habe in der Vergangenheit auch die Erfahrung gemacht, dass es keine gute Kollisionsbehandlungs-Strategie ist, einfach blind die Geschwindigkeit zu negieren... nicht immer hebt sich die Negation auf wie hier, aber manchmal passiert es auch, dass ein Objekt an einer Kante kleben bleibt, weil ein Simulationsschritt nicht ausreicht, dass es das Objekt, mit dem es kollidiert, wieder verlässt, und so kehrt sich mit jedem Frame das Vorzeichen um und es bewegt sich effektiv gar nicht mehr. Problematisch sind auch Kollisionen mit mehreren Objekten gleichzeitig (könnt hier auch die Ursache sein). Setz mal einen Breakpoint auf deine Kollisionsbehandlung, dann siehst du wahrscheinlich, was Sache ist. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz