Skip to content

Commit

Permalink
update in collision system
Browse files Browse the repository at this point in the history
  • Loading branch information
BitingStorm committed Mar 4, 2025
1 parent e4427ae commit f7c8e84
Show file tree
Hide file tree
Showing 41 changed files with 765 additions and 126 deletions.
Binary file removed QQ20250130-105855.jpg
Binary file not shown.
Binary file removed QQ20250130-105947.jpg
Binary file not shown.
Binary file removed QQ20250131-002024.jpg
Binary file not shown.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ VS2022 + EasyX_20240601 

菜单“CHANGE THEME”可以在怀旧和最新场景间来回切换,游戏中 WASD 控制上下左右,按住 Space 空格疾跑,J 攻击,K 跳跃(按住时间越久跳得越高,跳跃到平台边沿会自动攀爬),F 冲刺(地面小冲刺,空中大冲刺),L 闪避,Q 飞镖(飞镖可互动,向下攻击用作垫脚石),E 治疗,I 近战技能,地面使用 O 为远程技能,空中使用 O 发射钩锁斜向上移动,特别的,长按 W/S 向上/下看,W+J 向上攻击,S+J 斜向下攻击,座位旁按 W 坐下,坐下以后按 S 起立。


### 游戏执行效果

![输入图片说明](QQ20250131-002024.jpg)
![输入图片说明](QQ20250130-105855.jpg)
![输入图片说明](QQ20250130-105947.jpg)
![](https://codebus.cn/f/a/0/0/734/QQ20250130-105746.png)

![](https://codebus.cn/f/a/0/0/734/QQ20250130-105855.png)

![](https://codebus.cn/f/a/0/0/734/QQ20250130-105947.png)


演示视频:[【Easyx】空洞骑士,但是Easyx](https://www.bilibili.com/video/BV1U8fSYkEsC/?share_source=copy_web&vd_source=a59fee9f89e8975f2e92a9b950cce6c5)
11 changes: 7 additions & 4 deletions SilkSong/SilkSong.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Source\Engine\Core\Ray2D.h" />
<ClInclude Include="Source\Engine\Math\Polygon.h" />
<ClInclude Include="Source\Engine\Physics\Collisions2D.h" />
<ClInclude Include="Source\Engine\Math\Ray2D.h" />
<ClInclude Include="Source\Project\DefaultDamageStrategy.h" />
<ClInclude Include="Source\Engine\Core\Box2D.h" />
<ClInclude Include="Source\Engine\Core\Transform.h" />
<ClInclude Include="Source\Engine\Core\Vector2D.h" />
<ClInclude Include="Source\Engine\Math\Box2D.h" />
<ClInclude Include="Source\Engine\Math\Transform.h" />
<ClInclude Include="Source\Engine\Math\Vector2D.h" />
<ClInclude Include="Source\Engine\Objects\Level.h" />
<ClInclude Include="Source\Project\Damagable.h" />
<ClInclude Include="Source\Project\DamageResponseComponent.h" />
Expand Down Expand Up @@ -104,6 +106,7 @@
<ItemGroup>
<ClCompile Include="Source\Engine\Core\Object.cpp" />
<ClCompile Include="Source\Engine\Objects\Level.cpp" />
<ClCompile Include="Source\Engine\Physics\Collisions2D.cpp" />
<ClCompile Include="Source\Project\DamageResponseComponent.cpp" />
<ClCompile Include="Source\Project\DamageSystem.cpp" />
<ClCompile Include="Source\Project\DefaultDamageStrategy.cpp" />
Expand Down
39 changes: 27 additions & 12 deletions SilkSong/SilkSong.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@
<Filter Include="Project\Menu">
<UniqueIdentifier>{1f40607f-32e2-44a8-9e4f-f6bf9acbf927}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\Physics2D">
<UniqueIdentifier>{23ce5839-e770-4efd-841e-ca3581534c66}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\Math">
<UniqueIdentifier>{1b0d8621-dd40-4054-87c3-decd5627676c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Source\Engine\Components\ActorComponent.h">
Expand Down Expand Up @@ -243,18 +249,9 @@
<ClInclude Include="Source\Engine\Core\Delegate.h">
<Filter>Engine\Core</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Core\Vector2D.h">
<Filter>Engine\Core</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Core\Box2D.h">
<Filter>Engine\Core</Filter>
</ClInclude>
<ClInclude Include="Source\Project\Damagable.h">
<Filter>Project\Interfaces</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Core\Transform.h">
<Filter>Engine\Core</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Objects\Level.h">
<Filter>Engine\Objects</Filter>
</ClInclude>
Expand Down Expand Up @@ -306,15 +303,30 @@
<ClInclude Include="Source\Project\FragmentParticle.h">
<Filter>Project\Items</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Core\Ray2D.h">
<Filter>Engine\Core</Filter>
</ClInclude>
<ClInclude Include="Source\Project\RuinHouseLevel.h">
<Filter>Project\Levels</Filter>
</ClInclude>
<ClInclude Include="Source\Project\LevelTransformer.h">
<Filter>Project\Levels</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Physics\Collisions2D.h">
<Filter>Engine\Physics2D</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Math\Box2D.h">
<Filter>Engine\Math</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Math\Ray2D.h">
<Filter>Engine\Math</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Math\Vector2D.h">
<Filter>Engine\Math</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Math\Transform.h">
<Filter>Engine\Math</Filter>
</ClInclude>
<ClInclude Include="Source\Engine\Math\Polygon.h">
<Filter>Engine\Math</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Source\Engine\Components\ActorComponent.cpp">
Expand Down Expand Up @@ -530,5 +542,8 @@
<ClCompile Include="Source\Project\LevelTransformer.cpp">
<Filter>Project\Levels</Filter>
</ClCompile>
<ClCompile Include="Source\Engine\Physics\Collisions2D.cpp">
<Filter>Engine\Physics2D</Filter>
</ClCompile>
</ItemGroup>
</Project>
92 changes: 65 additions & 27 deletions SilkSong/Source/Engine/Components/Collider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
bool (*Collider::collisionJudgeMap[3])(Collider*, Collider*) =
{ &Collider::collisionJudgeCircleToCircle,Collider::collisionJudgeCircleToBox,Collider::collisionJudgeBoxToBox };

HitResult(*Collider::collisionHitMap[3])(Collider*, Collider*) =
FHitResult(*Collider::collisionHitMap[3])(Collider*, Collider*) =
{ &Collider::collisionHitCircleToCircle,Collider::collisionHitCircleToBox,Collider::collisionHitBoxToBox };

void (*Collider::collisionAdjustMap[3])(Collider*, Collider*, const HitResult&) =
void (*Collider::collisionAdjustMap[3])(Collider*, Collider*, const FHitResult&) =
{ &Collider::collisionAdjustCircleToCircle,Collider::collisionAdjustCircleToBox,Collider::collisionAdjustBoxToBox };


Expand Down Expand Up @@ -45,26 +45,17 @@ void Collider::Update(float deltaTime)
{
if (another->mode == CollisionMode::Collision && this->mode == CollisionMode::Collision)
{
HitResult hitResult = this->CollisionHit(another);
FHitResult hitResult = this->CollisionHit(another);
OnComponentStay.BroadCast(this, another, another->pOwner, -hitResult.ImpactNormal, hitResult);
another->OnComponentStay.BroadCast(another, this, pOwner, hitResult.ImpactNormal, { hitResult.ImpactPoint,-hitResult.ImpactNormal,pOwner,this });
CollisionAdjust(another, hitResult);
}
else
{
OnComponentOverlap.BroadCast(this, another, another->pOwner); another->OnComponentOverlap.BroadCast(another, this, pOwner);
}
}

FVector2D pos = GetRect().min;
FIntVector2 newPoint(FMath::Clamp(int(pos.x + 2000) / 400, 0, 9), FMath::Clamp(int(pos.y) / 200, 0, 5));
pos = GetRect().max;
FIntVector2 newPoint_1(FMath::Clamp(int(pos.x + 2000) / 400, 0, 9), FMath::Clamp(int(pos.y) / 200, 0, 5));
if (newPoint == point && newPoint_1 == point_1)return;

//ÅöײÇø¿éÐÅÏ¢¸üÐÂ
if (point != FIntVector2(-1, -1))for (int i = point.x; i <= point_1.x; ++i)for (int j = point.y; j <= point_1.y; ++j)mainWorld.ColliderZones[i][j].erase(this);
point = newPoint, point_1 = newPoint_1;
for (int i = point.x; i <= point_1.x; ++i)for (int j = point.y; j <= point_1.y; ++j)mainWorld.ColliderZones[i][j].insert(this);
ColliderZoneTick();
}

void Collider::Deactivate()
Expand Down Expand Up @@ -101,6 +92,22 @@ void Collider::RegisterDontDestroy()
mainWorld.OverallColliders.insert(this);
}

void Collider::ColliderZoneTick()
{
if (mode == CollisionMode::None || !bIsEnabled)return;

FVector2D pos = GetRect().min;
FIntVector2 newPoint(FMath::Clamp(int(pos.x + 2000) / 400, 0, 9), FMath::Clamp(int(pos.y) / 200, 0, 5));
pos = GetRect().max;
FIntVector2 newPoint_1(FMath::Clamp(int(pos.x + 2000) / 400, 0, 9), FMath::Clamp(int(pos.y) / 200, 0, 5));
if (newPoint == point && newPoint_1 == point_1)return;

//ÅöײÇø¿éÐÅÏ¢¸üÐÂ
if (point != FIntVector2(-1, -1))for (int i = point.x; i <= point_1.x; ++i)for (int j = point.y; j <= point_1.y; ++j)mainWorld.ColliderZones[i][j].erase(this);
point = newPoint, point_1 = newPoint_1;
for (int i = point.x; i <= point_1.x; ++i)for (int j = point.y; j <= point_1.y; ++j)mainWorld.ColliderZones[i][j].insert(this);
}

void Collider::Clear()
{
for (auto& another : collisions)
Expand All @@ -124,7 +131,7 @@ void Collider::Insert(Collider* another)
collisions.insert(another); another->collisions.insert(this);
if (another->mode == CollisionMode::Collision && this->mode == CollisionMode::Collision)
{
HitResult hitResult = CollisionHit(another);
FHitResult hitResult = CollisionHit(another);
OnComponentHit.BroadCast(this, another, another->pOwner, -hitResult.ImpactNormal, hitResult);
another->OnComponentHit.BroadCast(another, this, pOwner, hitResult.ImpactNormal, { hitResult.ImpactPoint,-hitResult.ImpactNormal,pOwner,this });
if (rigidAttached)
Expand Down Expand Up @@ -212,20 +219,20 @@ bool Collider::collisionJudgeBoxToBox(Collider* c1, Collider* c2)
return c1->GetRect().Intersects(c2->GetRect());
}

HitResult Collider::CollisionHit(Collider* another)
FHitResult Collider::CollisionHit(Collider* another)
{
int shape1 = int(this->shape), shape2 = int(another->shape);
return collisionHitMap[shape1 * shape1 + shape2 * shape2](this, another);
}

HitResult Collider::collisionHitCircleToCircle(Collider* c1, Collider* c2)
FHitResult Collider::collisionHitCircleToCircle(Collider* c1, Collider* c2)
{
FVector2D impactNormal = (c2->GetWorldPosition() - c1->GetWorldPosition()).GetSafeNormal();
FVector2D impactPoint = c1->GetWorldPosition() + impactNormal * c1->GetRect().GetHalf().x;
return HitResult(impactPoint, impactNormal, c2->pOwner, c2);
return FHitResult(impactPoint, impactNormal, c2->pOwner, c2);
}

HitResult Collider::collisionHitCircleToBox(Collider* c1, Collider* c2)
FHitResult Collider::collisionHitCircleToBox(Collider* c1, Collider* c2)
{
Collider* circle; Collider* box;
if (c1->GetShape() == ColliderShape::Circle)
Expand Down Expand Up @@ -268,10 +275,10 @@ HitResult Collider::collisionHitCircleToBox(Collider* c1, Collider* c2)
else { impactPoint = { pos.x,rect.min.y }; impactNormal = { 0,1 }; }
}
}
return HitResult(impactPoint, impactNormal * (c1 == circle ? 1.f : -1.f), c2->pOwner, c2);
return FHitResult(impactPoint, impactNormal * (c1 == circle ? 1.f : -1.f), c2->pOwner, c2);
}

HitResult Collider::collisionHitBoxToBox(Collider* c1, Collider* c2)
FHitResult Collider::collisionHitBoxToBox(Collider* c1, Collider* c2)
{
FRect overlapRect = c1->GetRect().Overlaps(c2->GetRect());
FVector2D impactNormal;
Expand All @@ -283,29 +290,34 @@ HitResult Collider::collisionHitBoxToBox(Collider* c1, Collider* c2)
{
c1->GetWorldPosition().x - c2->GetWorldPosition().x > 0 ? impactNormal = { -1,0 } : impactNormal = { 1,0 };
}
return HitResult(overlapRect.GetCenter(), impactNormal, c2->pOwner, c2);
return FHitResult(overlapRect.GetCenter(), impactNormal, c2->pOwner, c2);
}

void Collider::CollisionAdjust(Collider* another, const HitResult& hitResult)
void Collider::CollisionAdjust(Collider* another, const FHitResult& hitResult)
{
int shape1 = int(this->shape), shape2 = int(another->shape);
return collisionAdjustMap[shape1 * shape1 + shape2 * shape2](this, another, hitResult);
}

void Collider::collisionAdjustCircleToCircle(Collider* c1, Collider* c2, const HitResult& hitResult)
void Collider::collisionAdjustCircleToCircle(Collider* c1, Collider* c2, const FHitResult& hitResult)
{
}

void Collider::collisionAdjustCircleToBox(Collider* c1, Collider* c2, const HitResult& hitResult)
void Collider::collisionAdjustCircleToBox(Collider* c1, Collider* c2, const FHitResult& hitResult)
{
}

void Collider::collisionAdjustBoxToBox(Collider* c1, Collider* c2, const HitResult& hitResult)
void Collider::collisionAdjustBoxToBox(Collider* c1, Collider* c2, const FHitResult& hitResult)
{
FRect overlapRect = c1->GetRect().Overlaps(c2->GetRect());
FVector2D impactNormal = hitResult.ImpactNormal;

float separationDistance = overlapRect.GetSize().x * FMath::Abs(impactNormal.x) + overlapRect.GetSize().y * FMath::Abs(impactNormal.y);
separationDistance = separationDistance - AE_KINDA_SMALL_NUMBER;
if (separationDistance <= 0)
{
return;
}

if (c1->rigidAttached && c2->rigidAttached)
{
Expand Down Expand Up @@ -388,7 +400,7 @@ void BoxCollider::DrawDebugLine()

bool BoxCollider::IsMouseOver()
{
return rect.IsInside(GameplayStatics::GetController()->GetCursorPosition());
return GetRect().IsInside(GameplayStatics::GetController()->GetCursorPosition());
}

void BoxCollider::SetSize(FVector2D size)
Expand All @@ -401,3 +413,29 @@ void BoxCollider::SetSize(FVector2D size)
size.MakeAbs();
rect = FRect(GetWorldPosition(), size.x, size.y);
}






void PolygonCollider::Update(float deltaTime)
{
Collider::Update(deltaTime);
}

void PolygonCollider::DrawDebugLine()
{
if (GetCollisonMode() == CollisionMode::None || !polygon.bIsValid)return;
setlinecolor(GREEN);
int n = polygon.vertices.size();
/*for (int i = 0, j = n - 1; i < n; j = i++)
{
line(polygon.vertices[i].x, polygon.vertices[i].y, polygon.vertices[j].x, polygon.vertices[j].y);
}*/
}

bool PolygonCollider::IsMouseOver()
{
return polygon.IsInside(GameplayStatics::GetController()->GetCursorPosition());
}
Loading

0 comments on commit f7c8e84

Please sign in to comment.