Einzelnen Beitrag anzeigen

.chicken

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

Re: Pong - Problem bei der Ballkollision

  Alt 10. Dez 2006, 16:06
Ok, also habe nun nochmal komplett von vorne angefangen und erstmal nur mit einem Spielerbrett...

Der Stand der Dinge sieht so aus, dass der Ball von allen Waenden abprallt (bis auf die hinter ihm, dann is das Spiel vorbei) und der Ball einen Drall bekommt, jenachdem auf welcher Seite vom Schlaeger er aufprallt!

Hier der Quelltext:
Delphi-Quellcode:
unit Unit1;

interface

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

const
  Breite = 300;
  Hoehe = 300;
type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    Timer1: TTimer;
    Left: TImage;
    Right: TImage;
    Shape1: TShape;
    procedure Spielfeld_bemalen(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Spielstart;
    procedure Ball_berechnen;
    procedure Tastendruck(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

type TSpieler = record
      X, Y: Integer;
      Bmp: TBitmap;
end;

type TBall = record
      X, Y: Integer;
      Bmp: TBitmap;
      Richtung: TPoint;
end;

var
  Spieler: TSpieler;
  Ball: TBall;

{$R *.dfm}

procedure TForm1.Spielfeld_bemalen(Sender: TObject);
begin
  PaintBox1.Canvas.Brush.Color := clBlack;
  Paintbox1.Canvas.Pen.Color := clBlack;
  PaintBox1.Canvas.Rectangle(0, 0, Breite, Hoehe);

  PaintBox1.Canvas.Draw(Spieler.X, Spieler.Y, Spieler.Bmp);
  Paintbox1.Canvas.Draw(Ball.X, Ball.Y, Ball.Bmp);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //Tastendrücke
  if GetAsyncKeyState(VK_Left) < 0 then
    if Spieler.X > 0 then
      Spieler.X := Spieler.X - 10;
  if GetAsyncKeyState(VK_Right) < 0 then
    if Spieler.X + Spieler.Bmp.Width < Breite then
      Spieler.X := Spieler.X + 10;

  PaintBox1.Invalidate;
  Ball_berechnen;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.DoubleBuffered := True;
  Randomize;
  Timer1.Enabled := False;
end;

procedure TForm1.Spielstart;
begin
  Spieler.Bmp := TBitmap.Create;
  Spieler.Bmp.LoadfromFile('Spieler.bmp');
  Spieler.X := Breite div 2 - (Spieler.Bmp.Width div 2);
  Spieler.Y := 0;

  Ball.Bmp := TBitmap.Create;
  Ball.Bmp.LoadFromFile('Ball.bmp');
  Ball.Bmp.TransparentColor := RGB(255, 0, 216);
  Ball.Bmp.Transparent := True;
  Ball.X := Breite div 2 - Ball.Bmp.Width div 2;
  Ball.Y := Hoehe div 2 - Ball.Bmp.Height div 2;
  Ball.Richtung.X := 0;
  Ball.Richtung.Y := -(Random(9) + 3);
end;


procedure TForm1.Ball_berechnen;
var
R0, R1, R2: TRect;
i: Integer;
begin
  Ball.X := Ball.X + Ball.Richtung.X;
  Ball.Y := Ball.Y + Ball.Richtung.Y;
  R1 := Rect(Ball.X - 1, Ball.Y - 1, Ball.X + Ball.Bmp.Width + 1, Ball.Y + Ball.Bmp.Height + 1);
  R2 := Rect(Spieler.X, Spieler.Y, Spieler.X + Spieler.Bmp.Width, Spieler.Y + Spieler.Bmp.Height);

  //Schläger angestoßen oder gepunktet?
  if Ball.Y <= 0 + Spieler.Bmp.Height then

    //Schläger angestoßen
    if IntersectRect(R0, R1, R2) = True then
    begin
      Ball.Y := Spieler.Bmp.Height;
      i := (Ball.X + (Ball.Bmp.Width div 2)) - (Spieler.X + (Spieler.Bmp.Width div 2));
      Ball.Richtung.X := Ball.Richtung.X + (i div 5);
      Ball.Richtung.Y := -Ball.Richtung.Y;
    end
    else
    //Gepunktet
    begin
      Timer1.Enabled := False;
      Showmessage('ITS OVER!');
    end
  else

  //Wand angestoßen?
  if Ball.X <= 0 then
  begin
    Ball.X := 0;
    Ball.Richtung.X := -Ball.Richtung.X;
  end
  else
  if Ball.X + Ball.Bmp.Width >= Breite then
  begin
    Ball.X := Breite - Ball.Bmp.Width;
    Ball.Richtung.X := - Ball.Richtung.X;
  end
  else
  if Ball.Y + Ball.Bmp.Height >= Hoehe then
  begin
    Ball.Y := Hoehe - Ball.Bmp.Height;
    Ball.Richtung.Y := - Ball.Richtung.Y;
  end;
end;


procedure TForm1.Tastendruck(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
  VK_Return: begin
              Spielstart;
              Timer1.Enabled := True;
             end;
  end;
end;

end.
Wie immer bin ich offen fuer konstruktive Kritik und Vorschlaege =)

Achja und hat noch wer ne Idee wie ich realisieren kann, dass der Ball auch an der rechten und linken Kante vom Schlaeger abprallen kann? Momentan ist es so, dass sobald er hinter der Vorderkante des Schlaegers landet das Spiel zuende ist, weil ich Probleme hatte zu prüfen ob der Ball nun auf die Kante oder Vorne aufgekommen ist (wie auch schon in einem meiner letzten Posts beschrieben).

MfG
  Mit Zitat antworten Zitat