当玩家按下UP键时,我想做一个形状跳跃,所以我能想到的最好的是这个,但我使用的方法很糟糕且有问题:
(形状坐标:shape1.top:=432;)
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case key of
vk_up: shape1.top:=shape1.top-40 //so that it jumps to 392
end;
end;
Run Code Online (Sandbox Code Playgroud)
现在这个计时器:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
timer1.interval:=300
if shape1.Top<400 then //if shape1.top=392 < 400
begin
shape1.Top:=432; //move back to 432
end;
end;
Run Code Online (Sandbox Code Playgroud)
问题是玩家可以不断按下UP键,这是我不想要的.我知道这种方法很糟糕,所以我希望你有比这更好的东西,如果你能和我分享,我将不胜感激.
这是一个在恒定力场中弹跳的球(例如,靠近地球表面的重力场).侧壁和地板是弹跳表面.您可以使用箭头键添加其他力:
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TRealVect = record
X, Y: real;
end;
const
ZeroVect: TRealVect = (X: 0; Y: 0);
type
TForm5 = class(TForm)
Timer1: TTimer;
procedure FormPaint(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
private
{ Private declarations }
function ACC: TRealVect;
const
RADIUS = 16;
DAMPING = 0.8;
DT = 0.2;
GRAVITY: TRealVect = (X: 0; Y: 10);
var
FForce: TRealVect;
FPos: TRealVect;
FVel: TRealVect;
public
{ Public declarations }
end;
var
Form5: TForm5;
implementation
{$R *.dfm}
function RealVect(X, Y: real): TRealVect;
begin
result.X := X;
result.Y := Y;
end;
function Add(A, B: TRealVect): TRealVect;
begin
result.X := A.X + B.X;
result.Y := A.Y + B.Y;
end;
function Scale(A: TRealVect; C: real): TRealVect;
begin
result.X := C*A.X;
result.Y := C*A.Y;
end;
function TForm5.ACC: TRealVect;
begin
result := Add(GRAVITY, FForce);
end;
procedure TForm5.FormCreate(Sender: TObject);
begin
FPos := RealVect(Width div 2, 10);
FVel := RealVect(0, 0);
end;
procedure TForm5.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_UP:
FForce := RealVect(0, -20);
VK_DOWN:
FForce := RealVect(0, 10);
VK_RIGHT:
FForce := RealVect(10, 0);
VK_LEFT:
FForce := RealVect(-10, 0);
end;
end;
procedure TForm5.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
FForce := ZeroVect;
end;
procedure TForm5.FormPaint(Sender: TObject);
begin
Canvas.Brush.Color := clRed;
Canvas.Ellipse(round(FPos.X - RADIUS), round(FPos.Y - RADIUS),
round(FPos.X + RADIUS), round(FPos.Y + RADIUS));
end;
procedure TForm5.Timer1Timer(Sender: TObject);
begin
FVel := Add(FVel, Scale(ACC, DT));
FPos := Add(FPos, Scale(FVel, DT));
if FPos.Y + RADIUS >= ClientHeight then
begin
FVel.Y := -DAMPING*FVel.Y;
FPos.Y := ClientHeight - RADIUS - 1;
end;
if FPos.X - RADIUS <= 0 then
begin
FVel.X := -DAMPING*FVel.X;
FPos.X := RADIUS + 1;
end;
if FPos.X + RADIUS >= ClientWidth then
begin
FVel.X := -DAMPING*FVel.X;
FPos.X := ClientWidth - RADIUS - 1;
end;
Invalidate;
end;
end.
Run Code Online (Sandbox Code Playgroud)
将计时器的间隔设置30为"通常".
| 归档时间: |
|
| 查看次数: |
2094 次 |
| 最近记录: |