Einzelnen Beitrag anzeigen

.chicken

Registriert seit: 5. Dez 2006
459 Beiträge
 
#1

Pong - Problem bei der Ballkollision

  Alt 7. Dez 2006, 20:59
Also ich weiss das Thema Pong wurde hier schon oft behandelt, aber ich habe zu meinem Problem nichts gefunden!

Hier erstmal mein Code:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

const
  Breite = 600;
  Hoehe = 400;
type
  TForm1 = class(TForm)
    Spielfeld: TPaintBox;
    Button1: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Spielfeld_bemalen;
    procedure Tastendruck(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Timer1Timer(Sender: TObject);
    procedure Ball_berechnen;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Spielerposition: Array [1..2] of TPoint;
  Ballposition, Ballrichtung: TPoint;
  Spieler, Ball: TBitmap;

implementation

{$R *.dfm}


//----------------------------------
//FORM CREATE
//----------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.DoubleBuffered := True;
  Randomize;
end;
//----------------------------------


//----------------------------------
//FUNKTION ZUFALLSRICHTUNG
//----------------------------------
function Zufallsrichtung (i: Integer; j: Integer): TPoint;
var
x, y: Integer;
begin
  x := (Random(i - 1) + 1) * 5;
  y := Random(j) * 5;

  case Random(2) of
    0: x := x;
    1: x := -x;
  end;

  case Random(2) of
    0: y := y;
    1: y := -y;
  end;

  Result := Point(x, y);
end;
//----------------------------------


//----------------------------------
//SPIELFELD VORBEREITEN
//----------------------------------
procedure Spielfeld_vorbereiten;
begin
  //Bilder laden
  Spieler := TBitmap.Create;
  Spieler.LoadFromFile('Spieler.bmp');
  Ball := TBitmap.Create;
  Ball.LoadFromFile('Ball.bmp');
  Ball.TransparentColor := RGB(255, 255, 255);
  Ball.TransparentMode := tmFixed;
  Ball.Transparent := True;

  //Startpositionen festgelegt
  Spielerposition[1] := Point(10, (Hoehe div 2 - 30));
  Spielerposition[2] := Point((Breite - 10 - Spieler.Width), (Hoehe div 2 - 30));
  Ballposition := Point((Breite div 2 - (Ball.Width div 2)), (Hoehe div 2 - (Ball.Height div 2)));
  Ballrichtung := Zufallsrichtung(5, 5);
end;
//----------------------------------


//----------------------------------
//SPIELFELD BEMALEN
//----------------------------------
procedure TForm1.Spielfeld_bemalen;
var
i, x: Integer;
begin
  //Spielfeld wird gelöscht
  Spielfeld.Canvas.Brush.Color := clGray;
  Spielfeld.Canvas.FillRect(rect(0, 0, Breite, Hoehe));

  //Mittellinie
  Spielfeld.Canvas.Brush.Color := clBlack;
  x := 0;
  for i := 0 to Hoehe do begin
    Spielfeld.Canvas.FillRect(rect((Breite div 2 - 1), x, (Breite div 2 + 1), (x+2)));
    x := x + 6;
  end;

  //Spieler und Ball werden gezeichnet
  Spielfeld.Canvas.Draw(Spielerposition[1].X, Spielerposition[1].Y, Spieler);
  Spielfeld.Canvas.Draw(Spielerposition[2].X, Spielerposition[2].Y, Spieler);
  Spielfeld.Canvas.Draw(Ballposition.X, Ballposition.Y, Ball);
end;
//----------------------------------


//----------------------------------
//BUTTONKLICK
//----------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
  Spielfeld_vorbereiten;
  Timer1.Enabled := True;
  Button1.Enabled := False;
end;
//----------------------------------


//----------------------------------
//TASTENDRUCK
//----------------------------------
procedure TForm1.Tastendruck(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_Up: if (Spielerposition[1].Y - 10) > 0 then
            Spielerposition[1].Y := Spielerposition[1].Y - 10;
    VK_Down: if (Spielerposition[1].Y + 10 + Spieler.Height) < Hoehe then
              Spielerposition[1].Y := Spielerposition[1].Y + 10;
    VK_Left: if (Spielerposition[2].Y - 10) > 0 then
            Spielerposition[2].Y := Spielerposition[2].Y - 10;
    VK_Right: if (Spielerposition[2].Y + 10 + Spieler.Height) < Hoehe then
              Spielerposition[2].Y := Spielerposition[2].Y + 10;
  end;
end;
//----------------------------------


//----------------------------------
//TIMER
//----------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Ball_berechnen;
  Spielfeld_bemalen;
end;
//----------------------------------


//----------------------------------
//BALL BERECHNEN
//----------------------------------
procedure TForm1.Ball_berechnen;
begin
  //Wand angestoßen?
  if Ballposition.Y <= 0 then
    Ballrichtung.Y := -Ballrichtung.Y;
  if Ballposition.Y >= Hoehe then
    Ballrichtung.Y := -Ballrichtung.Y;

  //Spieler angestoßen?
  if ((Ballposition.X <= Spielerposition[1].X + Spieler.Width) AND (Ballposition.Y + Ball.Height >= Spielerposition[1].Y) AND (Ballposition.Y <= Spielerposition[1].Y + Spieler.Height)) OR
     ((Ballposition.X + Ball.Width >= Spielerposition[2].X) AND (Ballposition.Y + Ball.Height >= Spielerposition[2].Y) AND (Ballposition.Y <= Spielerposition[2].Y + Spieler.Height)) then
          Ballrichtung.X := -Ballrichtung.X;

  //Gepunktet?
  //Sp1
  if Ballposition.X <= 0 then
    Timer1.Enabled := False;
    Button1.Enabled := True;
  //Sp2
  if Ballposition.X + Ball.Width >= Breite then
    Timer1.Enabled := False;
    Button1.Enabled := True;


  Ballposition := Point(Ballposition.X + Ballrichtung.X, Ballposition.Y + Ballrichtung.Y);
end;
//----------------------------------

end.
Also erstmal: das ist natuerlich alles noch nicht fertig!!!

Aber bei mir ist nun das Problem aufgetreten, dass der Ball bevor er die Richtung aendert oft schon auf dem Balken oder halb außerhalb des Spielfeldes ist, weil ich ja Pro Timer den Ball um zwischen 1 und 5 verschiebe!

Hoffe ihr versteht was ich meine...wie wuerdet ihr das lösen?

Und was habt ihr fuer Verbesserungsvorschlaege zu meinem Quelltext??
Bin noch nich solange am Arbeiten mit Delpih, machen es jetzt in der Schule aber unsern Lehrer kann man in der Pfeife rauchen also bring ichs mir selber bei...

Dazu danke dann erstmal an dieses (wirklich hilfreiche) Forum!


MfG, chicken!
  Mit Zitat antworten Zitat