From 9025859facc55b53654954dbba0fbef6e964c2de Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 18 Jul 2024 17:21:25 +0800 Subject: [PATCH] :sparkles: Slide and collide! --- pkg/internal/entities/player.go | 33 +++++++++++++++++++++- pkg/internal/land/object.go | 2 +- pkg/internal/land/object_collision.go | 18 ++++++++++++ pkg/internal/land/object_movable.go | 6 ++++ pkg/internal/land/prof.go | 2 +- pkg/internal/land/root.go | 20 +++++++++++++- pkg/internal/land/vector2d.go | 4 +++ pkg/internal/tiles/tile.go | 40 +++++++++++++++++++++++++++ pkg/main.go | 5 ++++ 9 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 pkg/internal/land/object_collision.go create mode 100644 pkg/internal/land/object_movable.go create mode 100644 pkg/internal/tiles/tile.go diff --git a/pkg/internal/entities/player.go b/pkg/internal/entities/player.go index ea100e4..1dff2e1 100644 --- a/pkg/internal/entities/player.go +++ b/pkg/internal/entities/player.go @@ -19,6 +19,10 @@ type Player struct { } func (p *Player) Update() { + if !p.Velocity.IsZero() { + p.SlideByVelocity() + } + keys := sdl.GetKeyboardState() if keys[sdl.SCANCODE_UP] == 1 || keys[sdl.SCANCODE_W] == 1 { p.Move(0, -1) @@ -33,14 +37,15 @@ func (p *Player) Update() { p.Move(1, 0) } - p.Move(0, 0) p.BaseObject.Update() } func (p *Player) Move(deltaX, deltaY float64) { p.Velocity.X += deltaX * Acceleration p.Velocity.Y += deltaY * Acceleration +} +func (p *Player) SlideByVelocity() { p.Position.X += p.Velocity.X p.Position.Y += p.Velocity.Y @@ -63,3 +68,29 @@ func (p *Player) Draw(pen *sdl.Renderer) { } } } + +func (p *Player) GetPosition() land.Vector2D { + return p.Position +} + +func (p *Player) GetSize() land.Vector2D { + return p.Size +} + +func (p *Player) OnCollide(other land.CollidableObject) { + if p.Position.X < other.GetPosition().X { + p.Position.X = other.GetPosition().X - p.Size.X + p.Velocity.X = 0 + } else if p.Position.X > other.GetPosition().X { + p.Position.X = other.GetPosition().X + other.GetSize().X + p.Velocity.X = 0 + } + + if p.Position.Y < other.GetPosition().Y { + p.Position.Y = other.GetPosition().Y - p.Size.Y + p.Velocity.Y = 0 + } else if p.Position.Y > other.GetPosition().Y { + p.Position.Y = other.GetPosition().Y + other.GetSize().Y + p.Velocity.Y = 0 + } +} diff --git a/pkg/internal/land/object.go b/pkg/internal/land/object.go index 9bebab0..9f79f3d 100644 --- a/pkg/internal/land/object.go +++ b/pkg/internal/land/object.go @@ -8,7 +8,7 @@ type Object interface { } type DrawableObject interface { - Draw(*sdl.Renderer) + Draw(pen *sdl.Renderer) } type BaseObject struct { diff --git a/pkg/internal/land/object_collision.go b/pkg/internal/land/object_collision.go new file mode 100644 index 0000000..71d49ee --- /dev/null +++ b/pkg/internal/land/object_collision.go @@ -0,0 +1,18 @@ +package land + +type CollidableObject interface { + GetPosition() Vector2D + GetSize() Vector2D + OnCollide(other CollidableObject) +} + +func checkCollisionBetweenObject(a, b CollidableObject) bool { + aPos := a.GetPosition() + aSize := a.GetSize() + bPos := b.GetPosition() + bSize := b.GetSize() + return aPos.X < bPos.X+bSize.X && + aPos.X+aSize.X > bPos.X && + aPos.Y < bPos.Y+bSize.Y && + aPos.Y+aSize.Y > bPos.Y +} diff --git a/pkg/internal/land/object_movable.go b/pkg/internal/land/object_movable.go new file mode 100644 index 0000000..1b19c28 --- /dev/null +++ b/pkg/internal/land/object_movable.go @@ -0,0 +1,6 @@ +package land + +type MoveableObject interface { + Move(deltaX int64, deltaY int64) + SlideByVelocity() +} diff --git a/pkg/internal/land/prof.go b/pkg/internal/land/prof.go index 8177b59..d03ec89 100644 --- a/pkg/internal/land/prof.go +++ b/pkg/internal/land/prof.go @@ -19,7 +19,7 @@ func (p *PerformanceAnalyzer) Draw() { atomic.AddInt64(&p.drawCount, 1) } -func (p *PerformanceAnalyzer) KeepResetting(duration time.Duration) { +func (p *PerformanceAnalyzer) RunResetter(duration time.Duration) { ticker := time.NewTicker(duration) defer ticker.Stop() for { diff --git a/pkg/internal/land/root.go b/pkg/internal/land/root.go index 4f4a854..d21196a 100644 --- a/pkg/internal/land/root.go +++ b/pkg/internal/land/root.go @@ -16,7 +16,7 @@ func NewRootObject() *RootObject { Analyzer: &PerformanceAnalyzer{}, } - go in.Analyzer.KeepResetting(1 * time.Second) + go in.Analyzer.RunResetter(1 * time.Second) return in } @@ -38,6 +38,24 @@ func (p *RootObject) RunEventLoop(tickDuration time.Duration) { func (p *RootObject) Update() { p.BaseObject.Update() + // Check collision + for _, child := range p.Children { + for _, other := range p.Children { + collidableChild, ok := child.(CollidableObject) + if !ok { + continue + } + collidableOther, ok := other.(CollidableObject) + if !ok { + continue + } + if child != other && checkCollisionBetweenObject(collidableChild, collidableOther) { + collidableChild.OnCollide(collidableOther) + collidableOther.OnCollide(collidableChild) + } + } + } + p.Analyzer.Tick() } diff --git a/pkg/internal/land/vector2d.go b/pkg/internal/land/vector2d.go index 0eecfb7..459f826 100644 --- a/pkg/internal/land/vector2d.go +++ b/pkg/internal/land/vector2d.go @@ -3,3 +3,7 @@ package land type Vector2D struct { X, Y float64 } + +func (p Vector2D) IsZero() bool { + return p.X == 0 && p.Y == 0 +} diff --git a/pkg/internal/tiles/tile.go b/pkg/internal/tiles/tile.go new file mode 100644 index 0000000..a18e316 --- /dev/null +++ b/pkg/internal/tiles/tile.go @@ -0,0 +1,40 @@ +package tiles + +import ( + "git.solsynth.dev/highland/codingland/pkg/internal/land" + "github.com/veandco/go-sdl2/sdl" +) + +type Tile struct { + land.BaseObject + + Position land.Vector2D + Size land.Vector2D +} + +func (p *Tile) Draw(pen *sdl.Renderer) { + pen.SetDrawColor(255, 255, 255, 255) + pen.FillRect(&sdl.Rect{ + X: int32(p.Position.X), + Y: int32(p.Position.Y), + W: int32(p.Size.X), + H: int32(p.Size.Y), + }) + + for _, child := range p.Children { + if drawableChild, ok := child.(land.DrawableObject); ok { + drawableChild.Draw(pen) + } + } +} + +func (p *Tile) GetPosition() land.Vector2D { + return p.Position +} + +func (p *Tile) GetSize() land.Vector2D { + return p.Size +} + +func (p *Tile) OnCollide(other land.CollidableObject) { +} diff --git a/pkg/main.go b/pkg/main.go index 68af000..2a6a1b6 100644 --- a/pkg/main.go +++ b/pkg/main.go @@ -3,6 +3,7 @@ package main import ( "git.solsynth.dev/highland/codingland/pkg/internal/entities" "git.solsynth.dev/highland/codingland/pkg/internal/land" + "git.solsynth.dev/highland/codingland/pkg/internal/tiles" "log" "runtime" "time" @@ -42,6 +43,10 @@ func main() { Position: land.Vector2D{X: windowWidth/2 - 25, Y: windowHeight/2 - 25}, Size: land.Vector2D{X: 50, Y: 50}, }) + root.AddChild(&tiles.Tile{ + Position: land.Vector2D{X: 25, Y: 25}, + Size: land.Vector2D{X: 50, Y: 50}, + }) // 10ms delay use be 100tps average go root.RunEventLoop(10 * time.Millisecond)