Added proper taggins for gravity

This commit is contained in:
2025-11-26 00:27:28 -07:00
parent a9b2a3b7ff
commit c70f85abe5
4 changed files with 118 additions and 24 deletions

View File

@@ -13,10 +13,10 @@ const (
// Physics
const (
Gravity = 1400.0
JumpStrength = -480.0
JumpStrength = -580.0
MaxFallSpeed = 900.0
GroundFriction = 0.82
AirFriction = 0.96
AirFriction = 0.86
)
// Gameplay

View File

@@ -7,6 +7,7 @@ import (
"github.com/atridad/LilGuy/internal/config"
"github.com/atridad/LilGuy/internal/projectile"
"github.com/atridad/LilGuy/internal/world"
)
const (
@@ -49,6 +50,14 @@ const (
DirRight
)
// Tags
type Tag int
const (
TagGravity Tag = iota
)
// Hero state
type Hero struct {
@@ -63,6 +72,8 @@ type Hero struct {
Color color.NRGBA
Tags map[Tag]bool
Stamina float64
MaxStamina float64
StaminaDrain float64
@@ -118,6 +129,7 @@ func New(cfg Config) *Hero {
Radius: cfg.Radius,
Speed: cfg.Speed,
Color: cfg.Color,
Tags: map[Tag]bool{TagGravity: true},
Stamina: cfg.MaxStamina,
MaxStamina: cfg.MaxStamina,
StaminaDrain: cfg.StaminaDrain,
@@ -136,42 +148,69 @@ func New(cfg Config) *Hero {
}
}
func (h *Hero) Update(input Input, dt float64, bounds Bounds) {
func (h *Hero) Update(input Input, dt float64, bounds Bounds, w *world.World) {
if dt > 0.1 {
dt = 0.1
}
h.updateMovement(input, dt, bounds)
h.updateMovement(input, dt, bounds, w)
h.updateStamina(input, dt)
h.updateAnimation(dt)
}
// Movement and physics
func (h *Hero) updateMovement(input Input, dt float64, bounds Bounds) {
// apply gravity
func (h *Hero) updateMovement(input Input, dt float64, bounds Bounds, w *world.World) {
if h.HasTag(TagGravity) {
h.VelocityY += config.Gravity * dt
}
if h.VelocityY > config.MaxFallSpeed {
h.VelocityY = config.MaxFallSpeed
}
newY := h.Y + h.VelocityY*dt
wasGrounded := h.isGrounded
if newY >= bounds.Ground {
h.Y = bounds.Ground
h.VelocityY = 0
h.isGrounded = true
} else {
h.Y = newY
h.isGrounded = false
if w != nil && h.VelocityY >= 0 {
feetX := h.X
var landedSurface *world.Surface
for _, s := range w.Surfaces {
if !s.IsWalkable() {
continue
}
if input.Jump && (h.isGrounded || (!wasGrounded && h.isGrounded)) {
if feetX >= s.X && feetX <= s.X+s.Width {
if h.Y <= s.Y && newY >= s.Y {
if landedSurface == nil || s.Y < landedSurface.Y {
landedSurface = s
}
}
}
}
if landedSurface != nil {
newY = landedSurface.Y
h.VelocityY = 0
h.isGrounded = true
}
}
if !h.isGrounded {
if newY >= bounds.Ground {
newY = bounds.Ground
h.VelocityY = 0
h.isGrounded = true
}
}
h.Y = newY
if input.Jump && h.isGrounded {
h.VelocityY = config.JumpStrength
h.isGrounded = false
}
// horizontal input
targetVelocityX := 0.0
if input.Left {
targetVelocityX -= h.Speed
@@ -184,7 +223,6 @@ func (h *Hero) updateMovement(input Input, dt float64, bounds Bounds) {
h.isMoving = targetVelocityX != 0
// sprinting
h.isSprinting = input.Sprint && h.canSprint && h.Stamina > 0 && h.isMoving
if h.isSprinting {
targetVelocityX *= config.SprintSpeedMultiplier
@@ -329,6 +367,27 @@ func (h *Hero) getCurrentSprite() *ebiten.Image {
return getKnightSprite(h.direction, h.isMoving, h.animFrame)
}
func (h *Hero) AddTag(tag Tag) {
if h.Tags == nil {
h.Tags = make(map[Tag]bool)
}
h.Tags[tag] = true
}
func (h *Hero) RemoveTag(tag Tag) {
if h.Tags == nil {
return
}
delete(h.Tags, tag)
}
func (h *Hero) HasTag(tag Tag) bool {
if h.Tags == nil {
return false
}
return h.Tags[tag]
}
func (h *Hero) GetDirection() Direction {
return h.direction
}

View File

@@ -13,13 +13,48 @@ func CreatePlains(screenWidth, screenHeight float64) *Map {
m.BackgroundColor = color.NRGBA{R: 135, G: 206, B: 235, A: 255}
// ground surface
groundColor := color.NRGBA{R: 34, G: 139, B: 34, A: 255}
m.World.AddSurface(&world.Surface{
X: 0,
Y: screenHeight - config.GroundHeight,
Width: screenWidth,
Height: config.GroundHeight,
Tag: world.TagGround,
Color: color.NRGBA{R: 34, G: 139, B: 34, A: 255},
Color: groundColor,
})
// Platforms
// Use ground color by default as requested
platformColor := groundColor
// Platform 1: Low left
m.World.AddSurface(&world.Surface{
X: 100,
Y: screenHeight - 120,
Width: 150,
Height: 20,
Tag: world.TagPlatform,
Color: platformColor,
})
// Platform 2: Mid center
m.World.AddSurface(&world.Surface{
X: 350,
Y: screenHeight - 200,
Width: 200,
Height: 20,
Tag: world.TagPlatform,
Color: platformColor,
})
// Platform 3: High right
m.World.AddSurface(&world.Surface{
X: 650,
Y: screenHeight - 280,
Width: 150,
Height: 20,
Tag: world.TagPlatform,
Color: platformColor,
})
// left portal to desert

View File

@@ -119,7 +119,7 @@ func (g *GameplayScreen) Update(input GameplayInput, delta time.Duration) {
Right: input.Right,
Jump: input.Jump,
Sprint: input.Sprint,
}, dt, g.bounds)
}, dt, g.bounds, g.world)
if input.Shoot {
direction := 1.0