Bin nun soweit, dass ich ein "Spielfeld gezeichnet habe, eine Art Netz aus gestrichelten Linien in der Mittel des Spielfeldes.
Nun habe ich das Problem, dass wenn jemand ein Punkt macht, das Netz einfach verschwindet und nicht erhalten bleibt, vielleicht kann jemand mal über den Code drüberschauen und eventuell den Fehler finden.
Die Prozedure dafür lautet "DrawCourt"
Code: Alles auswählen
unit FMain;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
tmrMoveBall: TTimer;
procedure FormCreate (Sender: TObject); {Gestaltung}
procedure FormDestroy (Sender: TObject);
procedure FormKeyPress (Sender: TObject; var Key: char); {Steuerung}
procedure tmrMoveBallTimer (Sender: TObject); {KI (Bewegung) des Balls}
private
FBallX : integer; //F = Form / integer = Reelle zahl folgt
FBallY : integer;
FDirection : integer;
FSpeed : integer;
FBatRightY : integer;
FBatLeftY : integer;
FScreenCenterX : integer;
FScreenCenterY : integer;
FBatRightX : integer;
FBatLeftX : integer;
FBatY : integer;
FScoreLeft : integer;
FScoreRight : integer;
FSavedBackground : TbitMap;
procedure DrawBall (const AXNew, AYNew: integer);
procedure DrawBatLeft (const AYNew: integer);
procedure DrawBatRight (const AYNew: integer);
procedure BounceBallonXAxis;
procedure BounceBallonYAxis;
procedure StartGame;
procedure Serve;
procedure DisplayScore;
procedure AnnounceWinner;
procedure DrawCourt;
procedure RestoreBackground (const AX, AY: integer);
procedure SaveBackground (const AX, AY: integer);
procedure PlaySoundBounce;
procedure PlaySoundMissLeft;
procedure PlaySoundMissRight;
procedure playsoundpingpong;
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
uses
LCLType, MMSystem;
{$R *.lfm}
{ TForm1 }
const
CHoehe = 600; //C=Constante - Name frei wählbar
CBreite = 1024;
CBallGeschwindigkeit = 40;
CServedAngel = 15;
CSchlaegerHoehe = 80;
CBallGroesse = 15;
CMaxPunktzahl = 10;
procedure TForm1.FormCreate(Sender: TObject); {Gestaltung/Formen}
begin
Color := clWhite;
Height := CHoehe;
Width := CBreite;
Position := poScreenCenter;
BorderStyle := bsNone;
FBallX := 0;
FBallY := 0;
FDirection := CServedAngel;
FSpeed := CBallGeschwindigkeit;
FScreenCenterX := ClientWidth div 2;
FScreenCenterY := ClientHeight div 2;
FBatRightX := ClientWidth - 30 - CBallGroesse;
FBatLeftX := 30;
FBatY := 300;
FSavedBackground:= TBitMap.Create;
FSavedBackground.SetSize(CBallGroesse, CBallGroesse);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FSavedBackground.Free;
end;
procedure TForm1.FormKeyPress (Sender: TObject; var Key: char); {Steuerung}
begin
if Ord(Key) = VK_ESCAPE then //ESC - Schließen
Close;
if Ord(Key) = VK_SPACE then //SPACE - Procedure "Start Game"
StartGame;
if Key in ['k', 'K'] then //Steuerung - Verschiebung Schläger in "Y +/-"
DrawBatRight(FBatRightY + 20);
if Key in ['i', 'I'] then
DrawBatRight(FBatRightY - 20);
if Key in ['s', 'S'] then
DrawBatLeft(FBatLeftY + 20);
if Key in ['w', 'W'] then
DrawBatLeft(FBatLeftY - 20);
end;
procedure TForm1.tmrMoveBallTimer(Sender: TObject); {Selbstbewegung
des Balles durch Timer/
Richtungsänderung}
var
LXChange : integer;
LYCHange : integer;
begin
LXChange:= trunc(cos(Pi / 180 * FDirection) * FSpeed);
LYChange:= trunc(sin(Pi / 180 * FDirection) * FSpeed);
DrawBall(FBallX + LXChange, FBallY + LYChange);
if (FBallX <= 0) then
begin
PlaySoundMissLeft;
inc(FScoreRight);
Serve;
end
else if (FBallX >= ClientWidth - CBallGroesse) then
begin
PlaySoundMissRight;
inc(FScoreLeft);
Serve;
end
else if (FBallY <= 0) or (FBallY >= ClientHeight - CBallGroesse)
then
BounceBallonYAxis
else if (FBallX + CBallGroesse>= FBatRightX) and {Bounce Schläger}
(FBallY >= FBatRightY) and
(FBallY + CBallGroesse<= FBatRightY + CSchlaegerHoehe)
then
BounceBallonXAxis
else if (FBallX<= FBatLeftX + CBallGroesse) and
(FBallY >= FBatLeftY) and
(FBallY + CBallGroesse<= FBatLeftY + CSchlaegerHoehe)
then
BounceBallonXAxis
end;
procedure TForm1.DrawBall(const AXNew, AYNew: integer); {Ball/Größe}
begin
RestoreBackground(FBallX, FBallY);
SaveBackground(AXNew, AYNew);
Canvas.Brush.Color := ClBlack;
Canvas.Pen.Style := psClear;
Canvas.Rectangle(AXNew, AYNew, AXNew + CBallGroesse, AYNew + CBallGroesse);
FBallX := AXNew;
FBallY := AYNew;
end;
procedure TForm1.DrawBatLeft(const AYNew: integer);
begin
if (AYNew <= 0) or (AYNew + CSchlaegerHoehe >= ClientHeight) then
Exit;
Canvas.Pen.Style := psClear;
Canvas.Brush.Color := ClWhite;
Canvas.Rectangle(FBatLeftX, FBatLeftY, FBatLeftX + CBallGroesse, FBatLeftY + CSchlaegerHoehe);
Canvas.Brush.Color := ClBlack;
Canvas.Rectangle(FBatLeftX, AYNew, FBatLeftX + CBallGroesse, AYNew + CSchlaegerHoehe);
FBatLeftY := AYNew;
end;
procedure TForm1.DrawBatRight (const AYNew: integer); {Rechter Schläger}
begin
if (AYNew <= 0) or (AYNew + CSchlaegerHoehe >= ClientHeight) then
Exit;
Canvas.Pen.Style := psClear;
Canvas.Brush.Color := ClWhite;
Canvas.Rectangle(FBatRightX, FBatRightY, FBatRightX + CBallGroesse, FBatRightY + CSchlaegerHoehe);
Canvas.Brush.Color := ClBlack;
Canvas.Rectangle(FBatRightX, AYNew, FBatRightX + CBallGroesse, AYNew + CSchlaegerHoehe);
FBatRightY := AYNew;
end;
procedure TForm1.BounceBallonXAxis; {Bounce X-Achse}
begin
FDirection:= FDirection + (90 - FDirection) * 2;
PlaySoundBounce;
end;
procedure TForm1.BounceBallonYAxis; {Bounce Y-Achse}
begin
FDirection:= FDirection + (180 - FDirection) * 2 ;
PlaySoundBounce;
end;
procedure TForm1.StartGame;
begin
FScoreLeft := 0;
FScoreRight := 0;
Serve;
end;
procedure TForm1.Serve;
begin
tmrMoveBall.Enabled := false;
DrawCourt;
DisplayScore;
//Wenn jemand gewonnen hat, dann..
if (FScoreLeft >=10) or (FScoreRight >=10) then
AnnounceWinner
//Ansonsten weiterspielen
else begin
DrawBall(FScreenCenterX, FScreenCenterY);
DisplayScore;
Sleep(1000);
tmrMoveBall.Enabled:= True;
end;
end;
procedure TForm1.DisplayScore;
var
LScore: string;
LX: integer;
begin
Canvas.Font.Name := 'Courier New';
Canvas.Font.Size := 32;
Canvas.Font.Style := [fsBold];
Canvas.Font.Color := clBlack;
Canvas.Brush.Color := clWhite;
LScore := IntToStr(FScoreLeft);
LX := FScreenCenterX - 50 - Canvas.TextWidth(LScore);
Canvas.Textout(LX, 30, LScore);
Canvas.Textout(FScreenCenterX + 50,30, IntToStr(FScoreRight));
DrawBatRight(FScreenCenterY);
DrawBatLeft(FScreenCenterY);
end;
procedure TForm1.AnnounceWinner;
var
LX: integer;
const
CGewinnerText = 'Win';
begin
playsoundpingpong;
Canvas.Font.Name := 'Courier New';
Canvas.Font.Size := 32;
Canvas.Font.Style := [fsBold];
Canvas.Font.Color := clBlack;
Canvas.Brush.Color := clWhite;
if FScoreRight <= CMaxPunktzahl then
LX:= FScreenCenterX + 50
else
LX:= FScreenCenterX - 50 - Canvas.TextWidth(CGewinnerText);
Canvas.TextOut(LX, 100, CGewinnerText);
end;
procedure TForm1.PlaySoundBounce; {Sounds}
begin
PlaySound('bounce.wav', 0, SND_ASYNC);
end;
procedure TForm1.PlaySoundMissLeft;
begin
PlaySound('miss-left.wav', 0, SND_ASYNC);
end;
procedure TForm1.PlaySoundMissRight;
begin
PlaySound('miss-right.wav', 0, SND_ASYNC);
end;
procedure TForm1.playsoundpingpong;
begin
PlaySound('ping-pong.wav', 0, SND_ASYNC);
end;
procedure TForm1.DrawCourt;
var
LY: integer;
begin
Canvas.Brush.Color:=clWhite;
Canvas.Rectangle(
0, 0, ClientWidth, ClientHeight);
Canvas.Pen.Color:= clBlack;
LY:= 0;
while LY <= ClientHeight do
begin
Canvas.Line(
FScreenCenterX,
LY,
FScreenCenterX,
LY + 20);
Inc(LY, 40);
end;
Canvas.Pen.Color:=clBlack;
end;
procedure TForm1.RestoreBackground(const AX, AY: integer);
begin
Canvas.Draw(AX, AY, FSavedBackground);
end;
procedure TForm1.SaveBackground(const AX, AY: integer);
begin
FSavedBackground.Canvas.CopyRect(
Rect(0, 0, CBallGroesse, CBallGroesse),
Canvas,
Rect(AX, AY, AX + CBallGroesse, AY + CBallGroesse));
end;
end.