Switch world position to simple Vec2F implementation.
parent
46a1e33ae8
commit
ddd9ace4b6
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
|
@ -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
16
main.go
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue