feat: implemented basic animation. (very raw)
This commit is contained in:
parent
60cd4e9e75
commit
f2d7feb8a4
7 changed files with 118 additions and 29 deletions
77
animation.go
77
animation.go
|
@ -1,15 +1,67 @@
|
|||
package gg
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Animation struct {
|
||||
Frames []*Image
|
||||
type Animation []*Image
|
||||
|
||||
type AnimationDefine struct{
|
||||
Id AnimationId
|
||||
Indexes []ImageRectIndex
|
||||
}
|
||||
// Animation define
|
||||
func AD(id AnimationId, indexes ...ImageRectIndex) AnimationDefine {
|
||||
return AnimationDefine{
|
||||
Id: id,
|
||||
Indexes: indexes,
|
||||
}
|
||||
}
|
||||
func (ad AnimationDefine) DefRow(y int, xs ...int) AnimationDefine {
|
||||
for _, x := range xs {
|
||||
ad.Indexes = append(ad.Indexes, ImageRectIndex{x, y})
|
||||
}
|
||||
return ad
|
||||
}
|
||||
|
||||
func (ad AnimationDefine) DefCol(x int, ys ...int) AnimationDefine {
|
||||
for _, y := range ys {
|
||||
ad.Indexes = append(ad.Indexes, ImageRectIndex{x, y})
|
||||
}
|
||||
return ad
|
||||
}
|
||||
|
||||
type AnimationId int
|
||||
type AnimationSet map[AnimationId] *Animation
|
||||
type AnimationSet map[AnimationId] Animation
|
||||
func AnimationSetFromImage(
|
||||
img *Image,
|
||||
w, h int,
|
||||
defines ...AnimationDefine,
|
||||
) (AnimationSet, error) {
|
||||
set := AnimationSet{}
|
||||
|
||||
r := img.Bounds()
|
||||
fw, fh := r.Dx()/w, r.Dy()/h
|
||||
|
||||
for _, define := range defines {
|
||||
fmt.Println("def-idx-len:", len(define.Indexes))
|
||||
animation := make(Animation, len(define.Indexes))
|
||||
for i := range animation {
|
||||
idx := define.Indexes[i]
|
||||
animation[i] = ebiten.NewImageFromImage(img.SubImage(
|
||||
ImageRect{
|
||||
Min: ImagePoint{idx.X*fw, idx.Y*fh},
|
||||
Max: ImagePoint{(idx.X+1)*fw, (idx.Y+1)*fh},
|
||||
},
|
||||
))
|
||||
}
|
||||
fmt.Println("animation-len:", len(animation))
|
||||
set[define.Id] = animation
|
||||
}
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// The type implements animated sprites.
|
||||
type AnimatedSprite struct {
|
||||
|
@ -17,18 +69,31 @@ type AnimatedSprite struct {
|
|||
Animations AnimationSet
|
||||
AnimationId AnimationId
|
||||
CurrentFrame int
|
||||
TimeBetweenFrames time.Duration
|
||||
// This is time between animation frames, not
|
||||
// engine ones.
|
||||
TimeBetweenFrames Duration
|
||||
duration Duration
|
||||
}
|
||||
|
||||
func (as *AnimatedSprite) Animate(id AnimationId) bool {
|
||||
_, ok := as.Animations[id]
|
||||
if ok {
|
||||
as.duration = 0
|
||||
as.AnimationId = id
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
func (as *AnimatedSprite) Draw(c *Context) []EVertex {
|
||||
return nil
|
||||
as.duration += c.DrawDt()
|
||||
frames := as.Animations[as.AnimationId]
|
||||
fmt.Println("len:", len(frames))
|
||||
fullTime := Duration(len(frames)) * as.TimeBetweenFrames
|
||||
if as.duration > fullTime {
|
||||
as.duration -= fullTime
|
||||
}
|
||||
as.Images[0] = frames[(as.duration/as.TimeBetweenFrames)%Duration(len(frames))]
|
||||
|
||||
return as.Sprite.Draw(c)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,13 @@ const (
|
|||
LowestL
|
||||
)
|
||||
|
||||
const (
|
||||
Stand gg.AnimationId = iota
|
||||
Walk
|
||||
)
|
||||
|
||||
var (
|
||||
playerAnimations gg.AnimationSet
|
||||
playerImg *gg.Image
|
||||
player *Player
|
||||
rectMove gg.Rectangle
|
||||
|
@ -45,6 +51,12 @@ func main() {
|
|||
}
|
||||
|
||||
rect = NewRect()
|
||||
|
||||
playerAnimations, _ = gg.AnimationSetFromImage(
|
||||
playerImg,
|
||||
8, 3,
|
||||
gg.AD(Walk).DefRow(0, 0, 1, 2, 3, 4),
|
||||
)
|
||||
player = NewPlayer()
|
||||
tri = NewTri()
|
||||
|
||||
|
@ -82,6 +94,7 @@ func main() {
|
|||
}
|
||||
e.Spawn(txt)
|
||||
|
||||
|
||||
//fmt.Println(rect.GetLayer(), player.GetLayer())
|
||||
fmt.Println("Starting...")
|
||||
err = e.Run()
|
||||
|
|
|
@ -3,12 +3,13 @@ package main
|
|||
import (
|
||||
//"math/rand"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
import "vultras.su/core/gg"
|
||||
|
||||
type Player struct {
|
||||
gg.Sprite
|
||||
gg.AnimatedSprite
|
||||
MoveSpeed gg.Float
|
||||
ScaleSpeed gg.Float
|
||||
Spawned bool
|
||||
|
@ -17,17 +18,15 @@ type Player struct {
|
|||
func NewPlayer() *Player {
|
||||
ret := &Player{}
|
||||
ret.Transform = gg.T()
|
||||
fmt.Println("transform:", ret.Transform)
|
||||
//ret.Parent = rect
|
||||
ret.Scale = gg.V2(1)
|
||||
// Around center.
|
||||
ret.Around = gg.V2(.5)
|
||||
ret.MoveSpeed = 90.
|
||||
ret.ScaleSpeed = .2
|
||||
ret.Animations = playerAnimations
|
||||
ret.TimeBetweenFrames = time.Second/5
|
||||
fmt.Println("player-walk", ret.Animate(Walk))
|
||||
|
||||
ret.Visible = true
|
||||
|
||||
ret.Images[0] = playerImg
|
||||
ret.Layer = PlayerL
|
||||
|
||||
return ret
|
||||
|
@ -40,7 +39,7 @@ func (p *Player) Update(c *Context) {
|
|||
if p.Spawned {
|
||||
return
|
||||
}
|
||||
dt := c.Dt()
|
||||
dt := c.Dt().Seconds()
|
||||
cam := c.Camera
|
||||
keys := c.Keys()
|
||||
|
||||
|
@ -124,7 +123,7 @@ func (p *Player) Update(c *Context) {
|
|||
c.Camera.Position = pos.Sub(ec.Abs)
|
||||
case *gg.WheelChange:
|
||||
c.Camera.Scale = c.Camera.Scale.Add(gg.V2(
|
||||
ec.Offset.Y * c.Dt() * p.ScaleSpeed * 40,
|
||||
ec.Offset.Y * dt * p.ScaleSpeed * 40,
|
||||
))
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func NewTri() *Tri {
|
|||
}
|
||||
|
||||
func (t *Tri) Update(c *Context) {
|
||||
dt := c.Dt()
|
||||
dt := c.Dt().Seconds()
|
||||
if t.ContainsPoint(c.AbsCursorPosition()) {
|
||||
t.Color = gg.Rgba(0, 1, 0, 1)
|
||||
} else {
|
||||
|
@ -53,12 +53,12 @@ func (t *Tri) Update(c *Context) {
|
|||
case gg.KeyM:
|
||||
absPos := t.AbsPosition()
|
||||
t.SetAbsPosition(
|
||||
absPos.Add(gg.V(0, 100*c.Dt()*d)),
|
||||
absPos.Add(gg.V(0, 100*dt*d)),
|
||||
)
|
||||
case gg.KeyN:
|
||||
absPos := t.AbsPosition()
|
||||
t.SetAbsPosition(
|
||||
absPos.Add(gg.V(100*c.Dt()*d, 0)),
|
||||
absPos.Add(gg.V(100*dt*d, 0)),
|
||||
)
|
||||
case gg.KeyV:
|
||||
t.Rotation += d * gg.Pi * 0.3 * dt
|
||||
|
|
24
engine.go
24
engine.go
|
@ -61,12 +61,12 @@ type Engine struct {
|
|||
// If is set to nil then the engine will panic.
|
||||
Camera *Camera
|
||||
|
||||
lastTime time.Time
|
||||
dt Float
|
||||
drawLastTime time.Time
|
||||
drawdt Duration
|
||||
|
||||
// Frame delta time.
|
||||
fdt Float
|
||||
fLastTime time.Time
|
||||
dt Duration
|
||||
lastTime time.Time
|
||||
|
||||
// Temporary stuff
|
||||
keys, prevKeys []Key
|
||||
|
@ -228,7 +228,7 @@ func (e *Engine) AbsCursorPosition() Vector {
|
|||
|
||||
func (e *engine) Update() error {
|
||||
eng := (*Engine)(e)
|
||||
e.fdt = time.Since(e.fLastTime).Seconds()
|
||||
e.dt = time.Since(e.lastTime)
|
||||
|
||||
// Buffering the context for faster.
|
||||
|
||||
|
@ -302,7 +302,7 @@ func (e *engine) Update() error {
|
|||
object.Input() <- c
|
||||
}
|
||||
e.wg.Wait()
|
||||
e.fLastTime = time.Now()
|
||||
e.lastTime = time.Now()
|
||||
e.frame++
|
||||
return nil
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ var (
|
|||
defaultTriOptions = &ebiten.DrawTrianglesOptions{}
|
||||
)
|
||||
func (e *engine) Draw(img *ebiten.Image) {
|
||||
e.dt = time.Since(e.lastTime).Seconds()
|
||||
e.drawdt = time.Since(e.drawLastTime)
|
||||
eng := (*Engine)(e)
|
||||
m := map[Layer][]Drawer{}
|
||||
for _, object := range eng.Objects.store {
|
||||
|
@ -378,7 +378,7 @@ func (e *engine) Draw(img *ebiten.Image) {
|
|||
|
||||
// Empty the buff to generate it again.
|
||||
eng.Camera.buffered = false
|
||||
e.lastTime = time.Now()
|
||||
e.drawLastTime = time.Now()
|
||||
e.dframe++
|
||||
}
|
||||
|
||||
|
@ -391,8 +391,8 @@ func (e *engine) Layout(ow, oh int) (int, int) {
|
|||
}
|
||||
|
||||
// Return the delta time.
|
||||
func (e *Engine) Dt() Float {
|
||||
return e.dt
|
||||
func (e *Engine) DrawDt() Duration {
|
||||
return e.drawdt
|
||||
}
|
||||
|
||||
func (e *Engine) Dframe() uint {
|
||||
|
@ -400,8 +400,8 @@ func (e *Engine) Dframe() uint {
|
|||
}
|
||||
|
||||
// Return the current fixed delta time.
|
||||
func (e *Engine) Fdt() Float {
|
||||
return 1/60
|
||||
func (e *Engine) Dt() Duration {
|
||||
return e.dt
|
||||
}
|
||||
|
||||
func (e *Engine) Frame() uint {
|
||||
|
|
5
img.go
5
img.go
|
@ -9,6 +9,11 @@ import (
|
|||
)
|
||||
|
||||
type Image = ebiten.Image
|
||||
type ImageRect = image.Rectangle
|
||||
type ImagePoint = image.Point
|
||||
type ImageRectIndex struct {
|
||||
X, Y int
|
||||
}
|
||||
|
||||
type ColorV uint32
|
||||
type ColorM = ebiten.ColorM
|
||||
|
|
7
time.go
7
time.go
|
@ -7,3 +7,10 @@ import (
|
|||
type Time = time.Time
|
||||
type Duration = time.Duration
|
||||
|
||||
const (
|
||||
ZeroDuration Duration = 0
|
||||
Microsecond = time.Microsecond
|
||||
Millisecond = time.Millisecond
|
||||
Second = time.Second
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue