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

View File

@ -2,25 +2,36 @@ package entity
import (
"log"
"math"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/vector"
"github.com/veandco/go-sdl2/sdl"
)
type penguin struct {
worldPosition *sdl.Point
// Animation parameters
currentAnimation *entityAnimation
animationStep int32
facingRight bool
// Physical parameters
worldPosition *vector.Vec2F
direction *vector.Vec2F
speed float64
}
func NewPenguin(renderer *sdl.Renderer) *penguin {
position := sdl.Point{}
position := vector.Vec2F{}
direction := vector.Vec2F{}
p := penguin{
worldPosition: &position,
currentAnimation: penguinAnimations[PENGUIN_DEFAULT],
animationStep: 0,
facingRight: true,
worldPosition: &position,
speed: 2.0,
direction: &direction,
}
return &p
@ -29,7 +40,13 @@ func NewPenguin(renderer *sdl.Renderer) *penguin {
func (p *penguin) Draw() error {
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 {
return err
}
@ -39,8 +56,8 @@ func (p *penguin) Draw() error {
return nil
}
func (p *penguin) SetPosition(point *sdl.Point) {
p.worldPosition = point
func (p *penguin) SetPosition(vec *vector.Vec2F) {
p.worldPosition = vec
}
func (p *penguin) SetAnimation(name string) {
@ -59,31 +76,70 @@ func (p *penguin) SetAnimation(name string) {
}
func (p *penguin) MoveRight() {
p.worldPosition.X += 1
p.SetAnimation(PENGUIN_WALK_RIGHT)
p.direction.X = 1
p.facingRight = true
p.SetMoveAnimation()
}
func (p *penguin) MoveLeft() {
p.worldPosition.X -= 1
p.SetAnimation(PENGUIN_WALK_LEFT)
p.direction.X = -1
p.facingRight = false
p.SetMoveAnimation()
}
func (p *penguin) MoveUp() {
// (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() {
// positive y moves down
p.worldPosition.Y += 1
p.direction.Y = 1
p.SetMoveAnimation()
}
func (p *penguin) StopMove() {
if p.facingRight {
p.SetAnimation(PENGUIN_STATIONARY_RIGHT)
p.direction.X = 0
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 {
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)
// Walking Right is in the spritesheet.
speed = 10
speed = 5
offset = sdl.Point{X: 0, Y: 2}
length = 4
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,
length int32,
) *spriteAnimation {
spritesheet := GetSpritesheet(filename)
a := spriteAnimation{
@ -35,7 +36,7 @@ func NewAnimation(
func (a *spriteAnimation) Draw(
frame int32,
worldPosition *sdl.Point,
windowPosition *sdl.Point,
angle float64,
center *sdl.Point,
flip sdl.RendererFlip,
@ -63,10 +64,9 @@ func (a *spriteAnimation) Draw(
return err
}
// TODO convert to window position eventually
placement := sdl.Rect{
X: worldPosition.X,
Y: worldPosition.Y,
X: windowPosition.X,
Y: windowPosition.Y,
W: width,
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/entity"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/game/sprite"
"gitea.wisellama.rocks/Project-Ely/project-ely/internal/vector"
"gitea.wisellama.rocks/Wisellama/gosimpleconf"
"github.com/veandco/go-sdl2/sdl"
)
@ -90,7 +91,7 @@ func run(configMap gosimpleconf.ConfigMap) error {
penguin := 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)
keystates := make(map[sdl.Keycode]bool)
@ -128,12 +129,16 @@ func run(configMap gosimpleconf.ConfigMap) error {
penguin.MoveRight()
} else if keystates[sdl.K_a] {
penguin.MoveLeft()
} else {
penguin.StopHorizontal()
}
if keystates[sdl.K_w] {
penguin.MoveUp()
} else if keystates[sdl.K_s] {
penguin.MoveDown()
} else {
penguin.StopVertical()
}
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
err = penguin.Update()
if err != nil {
log.Printf("error updating: %v\n", err)
}
err = penguin.Draw()
if err != nil {
log.Printf("error drawing: %v\n", err)
}
err = p2.Update()
if err != nil {
log.Printf("error updating: %v\n", err)
}
err = p2.Draw()
if err != nil {
log.Printf("error drawing: %v\n", err)