我一直在制作一款有趣的小游戏。在游戏中,你是一个小型宇宙飞船(一个图像),在物体(面板)上射出激光束(形状)。此时你只能一次发射一个激光束,因为只有一个激光束(形状)并且只有一个物体(面板)可以射击。因此,通过编码,我想知道如何添加更多激光光束和物体,尤其是激光光束,因为我不想重复每个激光光束和每个面板的程序。
这是代码。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, jpeg;
type
TForm1 = class(TForm)
Panel1: TPanel;
Timer1: TTimer;
Timer2: TTimer;
Button1: TButton;
Shape1: TShape;
Timer3: TTimer;
Image1: TImage;
procedure Timer2Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure Timer3Timer(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
procedure StartPanelAnimation1;
procedure DoPanelAnimationStep1;
function PanelAnimationComplete1: Boolean;
procedure Startlazeranimation1;
procedure DolazeranimationStep1;
{ Public declarations }
end;
var
Form1: TForm1;
implementation
var key : char;
{$R *.dfm}
{ TForm1 }
{ TForm1 }
procedure TForm1.DoPanelAnimationStep1;
begin
Panel1.Top := Panel1.Top+1;
end;
function TForm1.PanelAnimationComplete1: Boolean;
begin
Result := Panel1.Top=512;
end;
procedure TForm1.StartPanelAnimation1;
begin
Panel1.Top := 0;
Timer1.Interval := 1;
Timer1.Enabled := True;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
DoPanelAnimationStep1;
if PanelAnimationComplete1 then
StartPanelAnimation1;
if (shape1.Top < panel1.Top) and (shape1.Left < panel1.Left+104) and (shape1.Left > panel1.Left) then
begin
startpanelanimation1;
sleep(10);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
button1.Hide;
key := 'a';
timer2.Enabled := true;
StartPanelAnimation1;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
shape1.Visible := false;
timer3.Enabled := false;
timer2.Enabled := false;
end;
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
image1.Left := image1.Left-10;
end;
procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
image1.Left := image1.Left+10;
end;
procedure TForm1.DolazeranimationStep1;
begin
shape1.Top := shape1.Top-10;
end;
procedure TForm1.Startlazeranimation1;
begin
shape1.Top := image1.Top;
shape1.Left := image1.Left+55;
shape1.Visible := true;
Timer3.Interval := 1;
Timer3.Enabled := True;
end;
procedure TForm1.Timer3Timer(Sender: TObject);
var k : integer;
begin
DolazeranimationStep1;
if (shape1.Top < panel1.Top) and (shape1.Left < panel1.Left+104) and (shape1.Left > panel1.Left) or (shape1.Top=clientheight) then
begin
timer3.Enabled := false;
shape1.Visible := false;
for k := 1 to 5 do
sleep(1);
begin
application.ProcessMessages;
end;
shape1.Top := 0;
shape1.Left := 0;
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
shape1.Show;
startlazeranimation1;
end;
end.
(以上是旧代码)
我已经成功完成了Stijn Sanders的建议。但现在在这个
if (Shape1.top < panel1.Top) and (shape1.Left < panel1.Left+104) and (shape1.Left > panel1.Left) then
永远不会测试true,因为shape1从不传递panel1它,只有在点击时创建的形状才会传递面板。
还有另一种测试形状是否在pnael的方法。
答案 0 :(得分:5)
并非所有组件都需要在设计时创建。在运行时,例如使用TTimer及其事件,您可以调用TShape.Create(Self);
以获得额外的形状。在方便的地方保持对结果值的引用,例如(动态)数组,并记住设置MyShape.Parent:=Self;
或MyShape.Parent:=Panel1;
,以便系统知道显示此新控件的时间和位置。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
const
MaxRays=100;
RayStep=8;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
Rays:array[0..MaxRays-1] of TShape;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
for i:=0 to MaxRays-1 do Rays[i]:=nil;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i:integer;
begin
i:=0;
while (i<MaxRays) and (Rays[i]<>nil) do inc(i);
if i<MaxRays then
begin
Rays[i]:=TShape.Create(Self);
Rays[i].Shape:=stEllipse;
Rays[i].Pen.Color:=clRed;
Rays[i].Pen.Style:=psSolid;
Rays[i].Brush.Color:=clYellow;
Rays[i].Brush.Style:=bsSolid;
Rays[i].SetBounds(X-4,Y-20,9,41);
Rays[i].Parent:=Self;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i:integer;
begin
for i:=0 to MaxRays-1 do
if Rays[i]<>nil then
begin
Rays[i].Top:=Rays[i].Top-RayStep;
if Rays[i].Top<0 then FreeAndNil(Rays[i]);
end;
end;
end.
答案 1 :(得分:1)
在运行时动态创建对象并在列表中跟踪它们,然后您可以在需要时循环遍历列表,例如:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, jpeg;
type
TForm1 = class(TForm)
PanelTimer: TTimer;
Button1: TButton;
LazerTimer: TTimer;
Image1: TImage;
procedure PanelTimerTimer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
procedure LazerTimerTimer(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
Lazers: TList;
Panels: TList;
procedure StartPanelAnimation;
procedure StartLazerAnimation;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.StartPanelAnimation;
var
Panel: TPanel;
begin
Panel := TPanel.Create(Self);
Panel.Parent := Self;
Panel.Top := 0;
// set other Panel properties as needed...
Panel.Visible := True;
Panels.Add(Panel);
if not PanelTimer.Enabled then
begin
PanelTimer.Interval := 1;
PanelTimer.Enabled := True;
end;
end;
procedure TForm1.PanelTimerTimer(Sender: TObject);
var
k: Integer;
Panel: TPanel;
begin
for k := 0 to Panels.Count-1 do
begin
Panel := TPanel(Panels[k]);
Panel.Top := Panel.Top + 1;
if Panel.Top = 512 then
Panel.Top := 0;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
StartPanelAnimation1;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Lazers := TList.Create;
Panels := TList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Lazers.Free;
Panels.Free;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
PanelTimer.Enabled := False;
LazerTimer.Enabled := False;
end;
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
Image1.Left := Image1.Left - 10;
end;
procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
Image1.Left := Image1.Left + 10;
end;
procedure TForm1.StartLazerAnimation;
var
Lazer: TShape;
begin
Lazer := TShape.Create(Self);
Lazer.Parent := Self;
// set Lazer properties as needed...
Lazer.Top := Image1.Top;
Lazer.Left := Image1.Left + 55;
Lazer.Visible := True;
Lazers.Add(Lazer);
if not Lazer.Enabled then
begin
Lazer.Interval := 1;
Lazer.Enabled := True;
end;
end;
procedure TForm1.LazerTimerTimer(Sender: TObject);
var
k, m : integer;
Lazer: TShape;
Panel: TPanel;
PanelHit: Boolean;
begin
k := 0;
while k < Lazers.Count do
begin
Lazer := TShape(Lazers[k]);
Lazer.Top := Lazer.Top - 10;
for m := 0 to Panels.Count-1 do
begin
Panel := TPanel(Panels[m]);
PanelHit := (Lazer.Top > (Panel.Top+Panel.Height)) and (Lazer.Left > Panel.Left) and (Lazer.Left < (Panel.Left+Panel.Width));
if PanelHit then
begin
Panels.Remove(Panel);
Panel.Free;
if Panels.Count = 0 then
PanelTimer.Enabled := False;
Break;
end;
end;
if PanelHit or (Lazer.Top = 0) then
begin
Lazers.Remove(Lazer);
Lazer.Free;
if Lazers.Count = 0 then
LazerTimer.Enabled := False;
end else
Inc(k);
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
StartLazerAnimation;
end;
end.