From 383cfdc18235ac38c064bcee9ab3861197c4e421 Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Tue, 24 Jan 2023 22:22:10 -0800 Subject: [PATCH] Apply physics calculations using map rects --- component/player.go | 6 ++++ game/game.go | 71 +++++++++++++++++++++++++++++++++++++-------- system/map.go | 4 +-- world/world.go | 5 ++-- 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/component/player.go b/component/player.go index 0122b96..21c0f4a 100644 --- a/component/player.go +++ b/component/player.go @@ -40,6 +40,12 @@ const ( PlayerWidth = 16 ) +func RectTouches(r1 image.Rectangle, r2 image.Rectangle) bool { + return !r1.Empty() && !r2.Empty() && + r1.Min.X <= r2.Max.X && r2.Min.X <= r1.Max.X && + r1.Min.Y <= r2.Max.Y && r2.Min.Y <= r1.Max.Y +} + // stdHit returns FrameData using a standard hitbox and the provided sprite. func stdHit(sprite *ebiten.Image) FrameData { return FrameData{ diff --git a/game/game.go b/game/game.go index 20b7861..d793c3b 100644 --- a/game/game.go +++ b/game/game.go @@ -2,6 +2,7 @@ package game import ( "crypto/sha1" + "image" "image/color" "log" "math" @@ -204,6 +205,10 @@ func (g *Game) ReadInputs() InputBits { return in } +var physicsRects = []image.Rectangle{ + image.Rect(-world.GroundWidth/2, 0, world.GroundWidth/2, -world.GroundHeight), +} + func (g *Game) applyPhysics() { for i := 0; i < 2; i++ { opp := 0 @@ -213,21 +218,68 @@ func (g *Game) applyPhysics() { p := &g.Players[i] o := &g.Players[opp] - // Apply gravity. - if p.VY > -world.Gravity { + playerRect := world.FloatRect(g.Players[i].X, g.Players[i].Y, g.Players[i].X+float64(component.PlayerSize), g.Players[i].Y+float64(component.PlayerSize)) + oppRect := world.FloatRect(g.Players[opp].X, g.Players[opp].Y, g.Players[opp].X+float64(component.PlayerSize), g.Players[opp].Y+float64(component.PlayerSize)) + + isGrounded := func() (r image.Rectangle, ok bool) { + for _, physRect := range physicsRects { + if component.RectTouches(playerRect, physRect) { + return physRect, true + } + } + return image.Rectangle{}, false + } + + // Apply velocity. + p.X, p.Y = p.X+p.VX, p.Y+p.VY + + // Apply ground collision. + groundRect, grounded := isGrounded() + if grounded { + // Min is left, Max is right + collideX := p.X+component.PlayerWidth >= float64(groundRect.Min.X) && p.X <= float64(groundRect.Max.X) + + // Min is bottom, Max is top + collideY := p.Y-component.PlayerHeight >= float64(groundRect.Min.Y) && p.Y <= float64(groundRect.Max.Y) + + log.Println(world.CurrentPlayer, collideX, collideY) + if collideY { + /*if collideX { + if p.X+component.PlayerWidth >= float64(groundRect.Min.X) { + p.X = float64(groundRect.Min.X) - component.PlayerWidth + } else { + p.X = float64(groundRect.Max.X) + } + }*/ + if collideY { + topDist := p.Y - float64(groundRect.Max.Y) + bottomDist := p.Y - component.PlayerHeight - float64(groundRect.Min.Y) + + if math.Abs(topDist) < math.Abs(bottomDist) { // Closer to top. + p.Y = float64(groundRect.Max.Y) + } else { // Closer to bottom. + p.Y = float64(groundRect.Min.Y) + component.PlayerHeight + } + p.VY = 0 + } + } + } else if p.VY > -world.Gravity { // Apply gravity. p.VY -= math.Max(math.Abs(p.VY/2.5), 0.1) if p.VY < -world.Gravity { p.VY = -world.Gravity } } - // Apply velocity. - p.X, p.Y = p.X+p.VX, p.Y+p.VY + if p.VY != 0 { + log.Println("VY", world.CurrentPlayer, p.VY) + } - // Apply player collision. - playerRect := world.FloatRect(g.Players[i].X, g.Players[i].Y, g.Players[i].X+float64(component.PlayerSize), g.Players[i].Y+float64(component.PlayerSize)) - oppRect := world.FloatRect(g.Players[opp].X, g.Players[opp].Y, g.Players[opp].X+float64(component.PlayerSize), g.Players[opp].Y+float64(component.PlayerSize)) + /*if grounded { + log.Println("grounded") + p.VY = 0 // TODO + }*/ + // Apply player collision. if playerRect.Overlaps(oppRect) { if playerRect.Min.X < oppRect.Min.X { p.X = o.X - component.PlayerSize @@ -235,11 +287,6 @@ func (g *Game) applyPhysics() { p.X = o.X + component.PlayerSize } } - - // Apply ground collision. - if p.Y < 0 { - p.Y = 0 - } } } diff --git a/system/map.go b/system/map.go index ecac063..b4330e5 100644 --- a/system/map.go +++ b/system/map.go @@ -41,13 +41,13 @@ func (s *MapSystem) Draw(e gohan.Entity, screen *ebiten.Image) error { groundColor := color.RGBA{50, 50, 50, 255} - r := image.Rect(-world.ScreenWidth*2, -world.ScreenHeight, world.ScreenWidth*2, 0) + r := image.Rect(-world.GroundWidth/2, -world.ScreenHeight, world.GroundWidth/2, 0) screen.SubImage(world.GameRectToScreen(r)).(*ebiten.Image).Fill(groundColor) const groundTopHeight = 10 groundTopColor := color.RGBA{100, 100, 100, 255} - r = image.Rect(-world.ScreenWidth*2, -groundTopHeight, world.ScreenWidth*2, 0) + r = image.Rect(-world.GroundWidth/2, -groundTopHeight, world.GroundWidth/2, 0) screen.SubImage(world.GameRectToScreen(r)).(*ebiten.Image).Fill(groundTopColor) return nil diff --git a/world/world.go b/world/world.go index 1797b46..1dfbbed 100644 --- a/world/world.go +++ b/world/world.go @@ -19,11 +19,12 @@ const ( JumpVelocity = 30 - GroundHeight = 100 - MaxDebug = 2 FloatValueThreshold = 0.00000001 + + GroundWidth = 600 + GroundHeight = 100 ) var (