From 62f10e0877f06ee0b83be2259bee7608e2e2dff6 Mon Sep 17 00:00:00 2001 From: genxium Date: Wed, 19 Oct 2022 08:32:20 +0800 Subject: [PATCH] Added collision test in collider visualizer. --- battle_srv/models/room.go | 4 +-- collider_visualizer/main.go | 5 ++- collider_visualizer/worldColliderDisplay.go | 34 ++++++++++++++++----- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go index 5b0b0a6..bc26f5f 100644 --- a/battle_srv/models/room.go +++ b/battle_srv/models/room.go @@ -1203,8 +1203,8 @@ func (pR *Room) refreshColliders() { minStep := int(3) // the approx minimum distance a player can move per frame space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled for _, player := range pR.Players { - playerCollider := resolv.NewObject(player.X+spaceOffsetX, player.Y+spaceOffsetY, playerColliderRadius*2, playerColliderRadius*2) - playerColliderShape := resolv.NewCircle(0, 0, playerColliderRadius*2) + playerCollider := resolv.NewObject(player.X-playerColliderRadius+spaceOffsetX, player.Y-playerColliderRadius+spaceOffsetY, playerColliderRadius*2, playerColliderRadius*2) + playerColliderShape := resolv.NewCircle(+playerColliderRadius, +playerColliderRadius, playerColliderRadius) playerCollider.SetShape(playerColliderShape) space.Add(playerCollider) // Keep track of the collider in "pR.CollisionSysMap" diff --git a/collider_visualizer/main.go b/collider_visualizer/main.go index 516d45a..c57b61f 100644 --- a/collider_visualizer/main.go +++ b/collider_visualizer/main.go @@ -85,8 +85,8 @@ type Game struct { func NewGame() *Game { - // stageName := "simple" // Use this for calibration - stageName := "richsoil" + stageName := "simple" // Use this for calibration + // stageName := "richsoil" stageDiscreteW, stageDiscreteH, stageTileW, stageTileH, playerPosMap, barrierMap, err := parseStage(stageName) if nil != err { panic(err) @@ -160,7 +160,6 @@ func (g *Game) DebugDraw(screen *ebiten.Image, space *resolv.Space) { ebitenutil.DrawLine(screen, cx, cy+ch, cx, cy, drawColor) } } - } func (g *Game) Layout(w, h int) (int, int) { diff --git a/collider_visualizer/worldColliderDisplay.go b/collider_visualizer/worldColliderDisplay.go index b6f0b84..f4d0466 100644 --- a/collider_visualizer/worldColliderDisplay.go +++ b/collider_visualizer/worldColliderDisplay.go @@ -4,7 +4,6 @@ import ( . "dnmshared" "fmt" "github.com/hajimehoshi/ebiten/v2" - "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/solarlune/resolv" "go.uber.org/zap" "image/color" @@ -36,12 +35,15 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi spaceOffsetY := float64(spaceH) * 0.5 // TODO: Move collider y-axis transformation to a "dnmshared" - playerColliderRadius := float64(12) // hardcoded + playerColliderRadius := float64(32) + playerColliders := make([]*resolv.Object, len(playerList)) space := resolv.NewSpace(int(spaceW), int(spaceH), 16, 16) - for _, player := range playerList { - playerCollider := resolv.NewObject(player.X+spaceOffsetX, player.Y+spaceOffsetY, playerColliderRadius*2, playerColliderRadius*2, "Player") - playerColliderShape := resolv.NewCircle(0, 0, playerColliderRadius*2) + for i, player := range playerList { + playerCollider := resolv.NewObject(player.X-playerColliderRadius+spaceOffsetX, player.Y-playerColliderRadius+spaceOffsetY, playerColliderRadius*2, playerColliderRadius*2, "Player") + playerColliderShape := resolv.NewRectangle(0, 0, playerColliderRadius*2, playerColliderRadius*2) // [WARNING] Deliberately not using a circle because "resolv v0.5.1" doesn't yet align circle center with space cell center, regardless of the "specified within-object offset" playerCollider.SetShape(playerColliderShape) + Logger.Info(fmt.Sprintf("Player Collider#%d: player.X=%v, player.Y=%v, radius=%v, spaceOffsetX=%v, spaceOffsetY=%v, shape=%v; calibrationCheckX=player.X-radius+spaceOffsetX=%v", i, player.X, player.Y, playerColliderRadius, spaceOffsetX, spaceOffsetY, playerCollider.Shape, player.X-playerColliderRadius+spaceOffsetX)) + playerColliders[i] = playerCollider space.Add(playerCollider) } @@ -76,11 +78,28 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi barrierCollider.SetShape(barrierColliderShape) space.Add(barrierCollider) - + Logger.Info(fmt.Sprintf("Added barrier: shape=%v", barrierCollider.Shape)) barrierLocalId++ } world.Space = space + + toTestPlayerCollider := playerColliders[0] + oldDx := 0.0 + oldDy := 180.0 + if collision := toTestPlayerCollider.Check(oldDx, oldDy, "Barrier"); collision != nil { + toCheckBarrier := collision.Objects[0].Shape + if intersection := toTestPlayerCollider.Shape.Intersection(oldDx, oldDy, toCheckBarrier); nil != intersection { + Logger.Info(fmt.Sprintf("Collided: shape=%v, oldDx=%v, oldDy=%v, intersection.MTV=%v", toTestPlayerCollider.Shape, oldDx, oldDy, intersection.MTV)) + } else { + Logger.Info(fmt.Sprintf("Collided: shape=%v, oldDx=%v, oldDy=%v, toCheckBarrier=%v, no intersecting points", toTestPlayerCollider.Shape, oldDx, oldDy, toCheckBarrier)) + } + } else { + Logger.Info(fmt.Sprintf("Collision Test: shape=%v, oldDx=%v, oldDy=%v, not colliding with any Barrier", toTestPlayerCollider.Shape, oldDx, oldDy)) + } + + toTestPlayerCollider.Update() + return world } @@ -92,9 +111,8 @@ func (world *WorldColliderDisplay) Draw(screen *ebiten.Image) { for _, o := range world.Space.Objects() { if o.HasTags("Player") { - circle := o.Shape.(*resolv.Circle) drawColor := color.RGBA{0, 255, 0, 255} - ebitenutil.DrawCircle(screen, circle.X, circle.Y, circle.Radius, drawColor) + DrawPolygon(screen, o.Shape.(*resolv.ConvexPolygon), drawColor) } else { drawColor := color.RGBA{60, 60, 60, 255} DrawPolygon(screen, o.Shape.(*resolv.ConvexPolygon), drawColor)