⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hgespriteengine.pas

📁 完整的Delphi游戏开发控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
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 + -