AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Multiplikation

Ein Thema von Pfusch · begonnen am 12. Aug 2013 · letzter Beitrag vom 13. Aug 2013
Antwort Antwort
Seite 2 von 4     12 34      
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#11

AW: Problem mit Multiplikation

  Alt 12. Aug 2013, 23:19
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;
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#12

AW: Problem mit Multiplikation

  Alt 12. Aug 2013, 23:19
Liegt es am Single das es nicht funktioniert, weil ich nämlich einen Float Wert bräuchte, deswegen ist es mit Integer nicht möglich.
Es geht doch aber offensichtlich um Bildschirm-Koordinaten, und dafür benötigt man keine Float-, sondern Integer-Werte. Dennoch, bei mir funktioniert das einwandfrei:

Delphi-Quellcode:
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;
Wieso funktioniert dein Beispiel nicht?
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#13

AW: Problem mit Multiplikation

  Alt 12. Aug 2013, 23:33
@Bjoerk
Weiß zwar nicht von welchem Buch du redest aber der Quellcode ist nur von mir selbst^^.
Ok, Sorry, wollte dich nicht vollquatschen, hatte das nur vermutet.

In deinem Code muß es aber heißen:

 Ball := TBall.Create(0,-1);
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#14

AW: Problem mit Multiplikation

  Alt 12. Aug 2013, 23:48
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:
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;
Ist Kosmetik, reduziert aber Arbeit bei Änderungen
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Pfusch

Registriert seit: 12. Aug 2013
7 Beiträge
 
#15

AW: Problem mit Multiplikation

  Alt 13. Aug 2013, 00:39
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.
  Mit Zitat antworten Zitat
Volker Z.

Registriert seit: 3. Dez 2012
Ort: Augsburg, Bayern, Süddeutschland
419 Beiträge
 
Delphi XE4 Ultimate
 
#16

AW: Problem mit Multiplikation

  Alt 13. Aug 2013, 01:53
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:
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;
Dann steht da auch irgendwann eine 1 - anstatt einer -1.

Gruß
Volker Zeller
  Mit Zitat antworten Zitat
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#17

AW: Problem mit Multiplikation

  Alt 13. Aug 2013, 09:03
Ich bin mir nicht sicher, hab grad keine IDE zum testen da, aber das da sieht für mich aus wie Durchfall:

Delphi-Quellcode:
  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;
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.
Oder gabs das in Delphi garnicht?
Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#18

AW: Problem mit Multiplikation

  Alt 13. Aug 2013, 09:07
Nope, das ist schon richtig so.
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.487 Beiträge
 
Delphi 7 Enterprise
 
#19

AW: Problem mit Multiplikation

  Alt 13. Aug 2013, 09:09
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.
Oder gabs das in Delphi garnicht?
Delphi-Referenz durchsuchencase stellt eine Lookuptabelle dar. Es wird nur eine Zeile ausgeführt und bereits der Compiler weigert sich zu kompilieren (Doppeltes case-Label) falls es Duplikate oder Überschneidungen gibt:
Delphi-Quellcode:
case x of
0..2 : y := -1;
1..3 : y := +1;
end;
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#20

AW: Problem mit Multiplikation

  Alt 13. Aug 2013, 09:17
Oder gabs das in Delphi garnicht?
Zum Glück nicht!

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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 4     12 34      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz