Switch world position to simple Vec2F implementation.

main
Sean Hickey 2022-10-13 21:38:52 -07:00
parent 46a1e33ae8
commit ddd9ace4b6
6 changed files with 130 additions and 24 deletions

View File

@ -1,6 +1,8 @@
package entity package entity
import "github.com/veandco/go-sdl2/sdl" import (
"github.com/veandco/go-sdl2/sdl"
)
type SpriteAnimation interface { type SpriteAnimation interface {
Draw(frame int32, worldPosition *sdl.Point, angle float64, center *sdl.Point, flip sdl.RendererFlip) error Draw(frame int32, worldPosition *sdl.Point, angle float64, center *sdl.Point, flip sdl.RendererFlip) error
@ -38,6 +40,6 @@ func NewEntityAnimation(
return &e return &e
} }
func (e *entityAnimation) Draw(frame int32, worldPosition *sdl.Point) error { func (e *entityAnimation) Draw(frame int32, windowPosition *sdl.Point) error {
return e.spriteAnimation.Draw(frame, worldPosition, e.angle, e.center, e.flip) return e.spriteAnimation.Draw(frame, windowPosition, e.angle, e.center, e.flip)
} }

View File

@ -2,25 +2,36 @@ package entity
import ( import (
"log" "log"
"math"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/vector"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
) )
type penguin struct { type penguin struct {
worldPosition *sdl.Point // Animation parameters
currentAnimation *entityAnimation currentAnimation *entityAnimation
animationStep int32 animationStep int32
facingRight bool facingRight bool
// Physical parameters
worldPosition *vector.Vec2F
direction *vector.Vec2F
speed float64
} }
func NewPenguin(renderer *sdl.Renderer) *penguin { func NewPenguin(renderer *sdl.Renderer) *penguin {
position := sdl.Point{} position := vector.Vec2F{}
direction := vector.Vec2F{}
p := penguin{ p := penguin{
worldPosition: &position,
currentAnimation: penguinAnimations[PENGUIN_DEFAULT], currentAnimation: penguinAnimations[PENGUIN_DEFAULT],
animationStep: 0, animationStep: 0,
facingRight: true, facingRight: true,
worldPosition: &position,
speed: 2.0,
direction: &direction,
} }
return &p return &p
@ -29,7 +40,13 @@ func NewPenguin(renderer *sdl.Renderer) *penguin {
func (p *penguin) Draw() error { func (p *penguin) Draw() error {
step := p.animationStep / p.currentAnimation.speed step := p.animationStep / p.currentAnimation.speed
err := p.currentAnimation.Draw(step, p.worldPosition) //windowPosition := worldPosToWindowPos()
windowPosition := &sdl.Point{
X: int32(math.Round(p.worldPosition.X)),
Y: int32(math.Round(p.worldPosition.Y)),
}
err := p.currentAnimation.Draw(step, windowPosition)
if err != nil { if err != nil {
return err return err
} }
@ -39,8 +56,8 @@ func (p *penguin) Draw() error {
return nil return nil
} }
func (p *penguin) SetPosition(point *sdl.Point) { func (p *penguin) SetPosition(vec *vector.Vec2F) {
p.worldPosition = point p.worldPosition = vec
} }
func (p *penguin) SetAnimation(name string) { func (p *penguin) SetAnimation(name string) {
@ -59,31 +76,70 @@ func (p *penguin) SetAnimation(name string) {
} }
func (p *penguin) MoveRight() { func (p *penguin) MoveRight() {
p.worldPosition.X += 1 p.direction.X = 1
p.SetAnimation(PENGUIN_WALK_RIGHT)
p.facingRight = true p.facingRight = true
p.SetMoveAnimation()
} }
func (p *penguin) MoveLeft() { func (p *penguin) MoveLeft() {
p.worldPosition.X -= 1 p.direction.X = -1
p.SetAnimation(PENGUIN_WALK_LEFT)
p.facingRight = false p.facingRight = false
p.SetMoveAnimation()
} }
func (p *penguin) MoveUp() { func (p *penguin) MoveUp() {
// (0,0) is the top left, so negative y moves up // (0,0) is the top left, so negative y moves up
p.worldPosition.Y -= 1 p.direction.Y = -1
p.SetMoveAnimation()
} }
func (p *penguin) MoveDown() { func (p *penguin) MoveDown() {
// positive y moves down // positive y moves down
p.worldPosition.Y += 1 p.direction.Y = 1
p.SetMoveAnimation()
} }
func (p *penguin) StopMove() { func (p *penguin) StopMove() {
if p.facingRight { p.direction.X = 0
p.SetAnimation(PENGUIN_STATIONARY_RIGHT) p.direction.Y = 0
p.SetMoveAnimation()
}
func (p *penguin) StopHorizontal() {
p.direction.X = 0
p.SetMoveAnimation()
}
func (p *penguin) StopVertical() {
p.direction.Y = 0
p.SetMoveAnimation()
}
func (p *penguin) SetMoveAnimation() {
if p.direction.X == 0 && p.direction.Y == 0 {
// Stationary
if p.facingRight {
p.SetAnimation(PENGUIN_STATIONARY_RIGHT)
} else {
p.SetAnimation(PENGUIN_STATIONARY_LEFT)
}
} else { } else {
p.SetAnimation(PENGUIN_STATIONARY_LEFT) // Moving
if p.facingRight {
p.SetAnimation(PENGUIN_WALK_RIGHT)
} else {
p.SetAnimation(PENGUIN_WALK_LEFT)
}
} }
} }
func (p *penguin) Update() error {
p.direction.Normalize()
x := p.direction.X * p.speed
y := p.direction.Y * p.speed
log.Printf("X: %v, Y: %v\n", x, y)
p.worldPosition.X += x
p.worldPosition.Y += y
return nil
}

View File

@ -31,7 +31,7 @@ func DefinePenguinAnimations() {
penguinAnimations = make(map[string]*entityAnimation) penguinAnimations = make(map[string]*entityAnimation)
// Walking Right is in the spritesheet. // Walking Right is in the spritesheet.
speed = 10 speed = 5
offset = sdl.Point{X: 0, Y: 2} offset = sdl.Point{X: 0, Y: 2}
length = 4 length = 4
center = nil // center is for rotation, nil will default to w/2 h/2 center = nil // center is for rotation, nil will default to w/2 h/2

View File

@ -21,6 +21,7 @@ func NewAnimation(
offset sdl.Point, offset sdl.Point,
length int32, length int32,
) *spriteAnimation { ) *spriteAnimation {
spritesheet := GetSpritesheet(filename) spritesheet := GetSpritesheet(filename)
a := spriteAnimation{ a := spriteAnimation{
@ -35,7 +36,7 @@ func NewAnimation(
func (a *spriteAnimation) Draw( func (a *spriteAnimation) Draw(
frame int32, frame int32,
worldPosition *sdl.Point, windowPosition *sdl.Point,
angle float64, angle float64,
center *sdl.Point, center *sdl.Point,
flip sdl.RendererFlip, flip sdl.RendererFlip,
@ -63,10 +64,9 @@ func (a *spriteAnimation) Draw(
return err return err
} }
// TODO convert to window position eventually
placement := sdl.Rect{ placement := sdl.Rect{
X: worldPosition.X, X: windowPosition.X,
Y: worldPosition.Y, Y: windowPosition.Y,
W: width, W: width,
H: height, H: height,
} }

34
internal/vector/vector.go Normal file
View File

@ -0,0 +1,34 @@
package vector
import "math"
// This is a small-scale vector implementation for a Vec2F.
// If you need anything more complicated than just normals and dot-products,
// then you should probably just switch to the glmath library instead.
type Vec2F struct {
X float64
Y float64
}
func (v *Vec2F) NonZero() bool {
return v.LengthSquared() > 0
}
func (v *Vec2F) LengthSquared() float64 {
return v.X*v.X + v.Y*v.Y
}
func (v *Vec2F) Normalize() {
length := math.Hypot(v.X, v.Y)
if length == 0 {
return
}
v.X = v.X / length
v.Y = v.Y / length
}
func (v *Vec2F) Dot(other *Vec2F) float64 {
return v.X*other.X + v.Y*other.Y
}

16
main.go
View File

@ -9,6 +9,7 @@ import (
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/game" "gitea.wisellama.rocks/Project-Ely/project-ely/internal/game"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/game/entity" "gitea.wisellama.rocks/Project-Ely/project-ely/internal/game/entity"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/game/sprite" "gitea.wisellama.rocks/Project-Ely/project-ely/internal/game/sprite"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/vector"
"gitea.wisellama.rocks/Wisellama/gosimpleconf" "gitea.wisellama.rocks/Wisellama/gosimpleconf"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
) )
@ -90,7 +91,7 @@ func run(configMap gosimpleconf.ConfigMap) error {
penguin := entity.NewPenguin(renderer) penguin := entity.NewPenguin(renderer)
p2 := entity.NewPenguin(renderer) p2 := entity.NewPenguin(renderer)
p2.SetPosition(&sdl.Point{X: 100, Y: 100}) p2.SetPosition(&vector.Vec2F{X: 100, Y: 100})
p2.SetAnimation(entity.PENGUIN_WALK_LEFT) p2.SetAnimation(entity.PENGUIN_WALK_LEFT)
keystates := make(map[sdl.Keycode]bool) keystates := make(map[sdl.Keycode]bool)
@ -128,12 +129,16 @@ func run(configMap gosimpleconf.ConfigMap) error {
penguin.MoveRight() penguin.MoveRight()
} else if keystates[sdl.K_a] { } else if keystates[sdl.K_a] {
penguin.MoveLeft() penguin.MoveLeft()
} else {
penguin.StopHorizontal()
} }
if keystates[sdl.K_w] { if keystates[sdl.K_w] {
penguin.MoveUp() penguin.MoveUp()
} else if keystates[sdl.K_s] { } else if keystates[sdl.K_s] {
penguin.MoveDown() penguin.MoveDown()
} else {
penguin.StopVertical()
} }
if !keystates[sdl.K_a] && !keystates[sdl.K_d] && !keystates[sdl.K_w] && !keystates[sdl.K_s] { if !keystates[sdl.K_a] && !keystates[sdl.K_d] && !keystates[sdl.K_w] && !keystates[sdl.K_s] {
@ -154,10 +159,19 @@ func run(configMap gosimpleconf.ConfigMap) error {
}) })
// Everything else // Everything else
err = penguin.Update()
if err != nil {
log.Printf("error updating: %v\n", err)
}
err = penguin.Draw() err = penguin.Draw()
if err != nil { if err != nil {
log.Printf("error drawing: %v\n", err) log.Printf("error drawing: %v\n", err)
} }
err = p2.Update()
if err != nil {
log.Printf("error updating: %v\n", err)
}
err = p2.Draw() err = p2.Draw()
if err != nil { if err != nil {
log.Printf("error drawing: %v\n", err) log.Printf("error drawing: %v\n", err)