📄 hgespriteengine.pas
字号:
end;
function TSprite.GetPatternWidth: Integer;
begin
if FEngine.FImages <> nil then
Result := FEngine.Images.Image[FImageName].PatternWidth
else
Result := 0
end;
function TSprite.GetPatternHeight: Integer;
begin
if FEngine.FImages <> nil then
Result := FEngine.Images.Image[FImageName].PatternHeight
else
Result := 0;
end;
function TSprite.GetPatternCount: Integer;
begin
Result := FEngine.FImages.Image[FImageName].PatternCount;
end;
procedure TSprite.DoDraw;
begin
if not FVisible then Exit;
if FEngine.FImages = nil then Exit;
case FTruncMove of
True:
FEngine.FCanvas.Draw(FEngine.FImages.Image[FImageName],
FPatternIndex,
Trunc(FX + FWorldX - FEngine.FWorldX),
Trunc(FY + FWorldY - FEngine.FWorldY),
FBlendMode);
False:
FEngine.FCanvas.Draw(FEngine.FImages.Image[FImageName],
FPatternIndex,
FX + FWorldX - FEngine.FWorldX,
FY + FWorldY - FEngine.FWorldY,
FBlendMode);
end;
end;
procedure TSprite.SetPos(X, Y: Single);
begin
FX := X;
FY := Y;
end;
procedure TSprite.SetPos(X, Y: Single; Z: Integer);
begin
FX := X;
FY := Y;
FZ := Z;
end;
procedure TSprite.SetName(const Value: string);
begin
Self.FName := Value;
end;
procedure TSprite.SetPatternIndex(const Value: Integer);
begin
Self.FPatternIndex := Value;
if FImageName = ' ' then Exit;
end;
procedure TSprite.SetImageName(const Value: string);
begin
// Self.FImageName := Value;
if CompareText(FImageName, Value) <> 0 then
begin
FImageName := Value;
// if FEngine <> nil then
// FImageName := FEngine.FImages.Image[FImageName];
end;
end;
procedure TSprite.SetX(const Value: Single);
begin
Self.FX := Value;
end;
procedure TSprite.SetY(const Value: Single);
begin
Self.FY := Value;
end;
procedure TSprite.SetZ(const Value: Integer);
begin
if FZ <> Value then
begin
FZ := Value;
if Parent <> nil then
begin
// optimize load time
if FZSet then
Parent.FDrawList.Remove(Self);
Parent.AddDrawList(Self);
FZSet := True;
end;
end;
end;
procedure TSprite.Collision(const Other: TSprite);
var
Delta: Real;
IsCollide: Boolean;
begin
IsCollide := False;
if (FCollisioned) and (Other.FCollisioned) and (not FDeaded) and (not Other.FDeaded) then
begin
case FCollideMode of
cmCircle:
begin
Delta := Sqrt(Sqr(Self.FCollidePos.X - Other.FCollidePos.X) +
Sqr(Self.FCollidePos.Y - Other.FCollidePos.Y));
IsCollide := (Delta < (Self.FCollideRadius + Other.FCollideRadius));
end;
cmRect:
begin
IsCollide := OverlapRect(Self.FCollideRect, Other.FCollideRect);
end;
cmQuadrangle:
begin
IsCollide := OverlapQuadrangle(Self.FCollideQuadrangle, Other.FCollideQuadrangle);
end;
cmPolygon:
begin
IsCollide := OverlapPolygon(Self.FCollidePolygon, Other.FCollidePolygon);
end;
end;
if IsCollide then
begin
DoCollision(Other);
Other.DoCollision(Self);
end;
end;
end;
procedure TSprite.Collision;
var
i: Integer;
begin
if (FEngine <> nil) and (not FDeaded) and (Collisioned) then
begin
for i := 0 to Engine.Count - 1 do
Self.Collision(Engine.Items[i]);
end;
end;
procedure TSprite.DoCollision(const Sprite: TSprite);
begin
end;
{TSpriteEx}
constructor TSpriteEx.Create(const AParent: TSprite);
begin
inherited;
FGroupNumber := -1;
FImageType := itSpriteSheet;
FColor1 := $FFFFFFFF;
FColor2 := $FFFFFFFF;
FColor3 := $FFFFFFFF;
FColor4 := $FFFFFFFF;
FCenterX := 0;
FCenterY := 0;
FX1 := 0;
FY1 := 0;
FX2 := 10;
FY2 := 0;
FX3 := 10;
FY3 := 10;
FX4 := 0;
FY4 := 10;
FRed := 255;
FGreen := 255;
FBlue := 255;
FAlpha := 255;
FAngle := 0;
FScaleX := 1;
FScaleY := 1;
FDoCenter := False;
FOffsetX := 0;
FOffsetY := 0;
FMirrorX := False;
FMirrorY := False;
FDrawMode := 0;
FMouseEnterFlag := False;
FMouseDownFlag:= False;
FPositionListX := TList.Create;
FPositionListY := TList.Create;
FAttachTo := nil;
end;
destructor TSpriteEx.Destroy;
begin
GroupNumber := -1;
Selected := False;
FPositionListX.Free;
FPositionListY.Free;
inherited Destroy;
end;
procedure TSpriteEx.Assign(const Value: TSprite);
begin
FImageType := TSpriteEx(Value).ImageType;
FX1 := TSpriteEx(Value).X1;
FY1 := TSpriteEx(Value).Y1;
FX2 := TSpriteEx(Value).X2;
FY2 := TSpriteEx(Value).Y2;
FX3 := TSpriteEx(Value).X3;
FY3 := TSpriteEx(Value).Y3;
FX4 := TSpriteEx(Value).X4;
FY4 := TSpriteEx(Value).Y4;
FOffsetX := TSpriteEx(Value).OffsetX;
FOffsetY := TSpriteEx(Value).OffsetY;
FCenterX := TSpriteEx(Value).CenterX;
FCenterY := TSpriteEx(Value).CenterY;
FMirrorX := TSpriteEx(Value).MirrorX;
FMirrorY := TSpriteEx(Value).MirrorY;
FScaleX := TSpriteEx(Value).ScaleX;
FScaleY := TSpriteEx(Value).ScaleY;
FDoCenter := TSpriteEx(Value).DoCenter;
FRed := TSpriteEx(Value).Red;
FGreen := TSpriteEx(Value).Green;
FBlue := TSpriteEx(Value).Blue;
FAlpha := TSpriteEx(Value).Alpha;
FColor1 := TSpriteEx(Value).Color1;
FColor2 := TSpriteEx(Value).Color2;
FColor3 := TSpriteEx(Value).Color3;
FColor4 := TSpriteEx(Value).Color4;
Angle := TSpriteEx(Value).Angle;
FDrawMode := TSpriteEx(Value).DrawMode;
end;
function TSpriteEx.GetSpriteAt(X, Y: Integer): TSprite;
procedure Collision_GetSpriteAt(X, Y: Double; Sprite: TSpriteEx);
var
i,SWidth,SHeight: Integer;
X1,Y1: Double;
X2,Y2: Double;
IsCollision:Boolean;
begin
if (Sprite.Parent<>nil) and not Sprite.Parent.visible then Exit;
Sprite.Collisioned:=false;
if Sprite.CanCollision then
begin
SWidth:=Round(Sprite.PatternWidth*Sprite.ScaleX);
SHeight:=Round(Sprite.PatternHeight*Sprite.ScaleY);
if Sprite.DrawMode=1 then
begin
X1 := X-Sprite.X-Sprite.Parent.X;
Y1 := Y-Sprite.Y-Sprite.Parent.Y;
end
else
if Sprite.DoCenter then
begin
X1 := X-Sprite.X-Sprite.Parent.X-Sprite.PatternWidth/2;
Y1 := Y-Sprite.Y-Sprite.Parent.Y-Sprite.PatternHeight/2;
end
else
begin
X1 := X-Sprite.X-Sprite.Parent.X-SWidth/2;
Y1 := Y-Sprite.Y-Sprite.Parent.Y-SHeight/2;
end;
X2 := Y1 * sin(Sprite.Angle) + X1 * cos(Sprite.Angle);
Y2 := Y1 * cos(Sprite.Angle) - X1 * sin(Sprite.Angle);
IsCollision:=Sprite.Visible and PointInRect(
Point(Round(X2), Round(Y2)),
Bounds(-SWidth div 2,-SHeight div 2,SWidth, SHeight));
if IsCollision then
begin
if (Result=nil) or (Sprite.Z>Result.Z) then
Result := Sprite;
end;
end;
for i:=0 to Sprite.Count-1 do
Collision_GetSpriteAt(X, Y, TSpriteex(Sprite.Items[i]));
end;
var
i: Integer;
begin
Result := nil;
if self.FEngine <> nil then
Collision_GetSpriteAt(X, Y, TSpriteEx(Self));
for i:=0 to Count-1 do
Collision_GetSpriteAt(X, Y, TSpriteEx(Items[i]));
if Result<>nil then
begin
Result.Collisioned := True;
Result.DoCollision(Result);
end;
end;
function GetAngle360(X, Y: Integer): Real;
begin
Result := (Arctan2(X, Y) * -57.4) + 180;
end;
procedure TSpriteEx.LookAt(TargetX, TargetY: Integer);
begin
// Angle360 := Trunc(
// GetAngle360(TargetX - Trunc(Self.X) + Trunc(Engine.WorldX),
// TargetY - Trunc(Self.Y) + Trunc(Engine.WorldY ) )
//);
Angle:=Angle256(TargetX-Trunc(X) ,TargetY-Trunc(Y) )/40.3 ;
end;
procedure TSpriteEx.TowardToAngle(Angle: Integer; Speed: Single; DoLookAt: Boolean);
begin
if DoLookAt then FAngle := Angle / 40;
X := X + (Sin256(Angle) * Speed);
Y := Y - (Cos256(Angle) * Speed);
end;
procedure TSpriteEx.TowardToPos(TargetX, TargetY: Integer; Speed: Single; DoLookAt: Boolean);
var
Direction: Integer;
begin
if DoLookAt then LookAt(TargetX, TargetY);
Direction:=Trunc(
Angle256(TargetX - Trunc(Self.X), TargetY - Trunc(Self.Y))
);
if (not SameValue(X, TargetX, Speed + 1)) or
(not SameValue(Y, TargetY, Speed + 1)) then
begin
X := X + (Sin256(Direction) * Speed);
Y := Y - (Cos256(Direction) * Speed);
end
else
begin
// make sure it gets to final pos
X := TargetX;
Y := TargetY;
end;
end;
//toward(rotate self angle automation)(straight) move direction
//and move by rotation speed(to destination angle)
procedure TSpriteEx.RotateToAngle(Angle: Integer; RotateSpeed, MoveSpeed: Single );
begin
FDestAngle := Angle;
if not SameValue(FSrcAngle, FDestAngle, RotateSpeed + 1) then
begin
if AngleDiff(FSrcAngle, FDestAngle) > 0 then
FSrcAngle := FSrcAngle + RotateSpeed;
if AngleDiff(FSrcAngle, FDestAngle) < 0 then
FSrcAngle := FSrcAngle - RotateSpeed;
end;
if FSrcAngle > 255 then FSrcAngle := FSrcAngle - 255;
if FSrcAngle < 0 then FSrcAngle := 255 + FSrcAngle;
FAngle := FSrcAngle / 40;
X := X + (Sin256(Trunc(FSrcAngle))* MoveSpeed);
Y := Y - (Cos256(Trunc(FSrcAngle))* MoveSpeed);
end;
//toward(rotate self angle automation)(straight) move direction
//and move by rotation speed(to destination position)
procedure TSpriteEx.RotateToPos(DestX, DestY: Integer; RotateSpeed, MoveSpeed: Single );
begin
FDestAngle:= Trunc(
Angle256(DestX - Trunc(X), DestY - Trunc(Y) )
);
if not SameValue(FSrcAngle, FDestAngle, RotateSpeed + 1) then
begin
if AngleDiff(FSrcAngle, FDestAngle) > 0 then
FSrcAngle := FSrcAngle + RotateSpeed;
if AngleDiff(FSrcAngle, FDestAngle) < 0 then
FSrcAngle := FSrcAngle - RotateSpeed;
end;
if FSrcAngle > 255 then FSrcAngle := FSrcAngle - 255;
if FSrcAngle < 0 then FSrcAngle := 255 + FSrcAngle;
FAngle := FSrcAngle / 40;
X := X + (Sin256(Trunc(FSrcAngle))* MoveSpeed);
Y := Y - (Cos256(Trunc(FSrcAngle))* MoveSpeed);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -