-
Notifications
You must be signed in to change notification settings - Fork 0
/
render_sprite.go
89 lines (81 loc) · 3.16 KB
/
render_sprite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package systems
import (
"image"
"sort"
"github.com/hajimehoshi/ebiten/v2"
gc "github.com/kijimaD/ruins/lib/components"
ec "github.com/kijimaD/ruins/lib/engine/components"
m "github.com/kijimaD/ruins/lib/engine/math"
w "github.com/kijimaD/ruins/lib/engine/world"
"github.com/kijimaD/ruins/lib/resources"
"github.com/kijimaD/ruins/lib/utils/camera"
ecs "github.com/x-hgg-x/goecs/v2"
)
func RenderSpriteSystem(world w.World, screen *ebiten.Image) {
gameComponents := world.Components.Game.(*gc.Components)
gameResources := world.Resources.Game.(*resources.Game)
{
iSprite := 0
entities := make([]ecs.Entity, world.Manager.Join(gameComponents.SpriteRender, gameComponents.GridElement).Size())
world.Manager.Join(
gameComponents.SpriteRender,
gameComponents.GridElement,
).Visit(ecs.Visit(func(entity ecs.Entity) {
entities[iSprite] = entity
iSprite++
}))
sort.Slice(entities, func(i, j int) bool {
spriteRender := gameComponents.SpriteRender.Get(entities[i]).(*ec.SpriteRender)
return spriteRender.Depth < spriteRender.Depth
})
for _, entity := range entities {
// タイル描画
gridElement := gameComponents.GridElement.Get(entity).(*gc.GridElement)
spriteRender := gameComponents.SpriteRender.Get(entity).(*ec.SpriteRender)
tileSize := gameResources.Level.TileSize
pos := &gc.Position{
X: int(gridElement.Row)*tileSize + tileSize/2,
Y: int(gridElement.Col)*tileSize + tileSize/2,
}
drawImage(world, screen, spriteRender, pos)
}
}
{
iSprite := 0
entities := make([]ecs.Entity, world.Manager.Join(gameComponents.SpriteRender, gameComponents.Position).Size())
world.Manager.Join(
gameComponents.SpriteRender,
gameComponents.Position,
).Visit(ecs.Visit(func(entity ecs.Entity) {
entities[iSprite] = entity
iSprite++
}))
sort.Slice(entities, func(i, j int) bool {
spriteRender := gameComponents.SpriteRender.Get(entities[i]).(*ec.SpriteRender)
return spriteRender.Depth < spriteRender.Depth
})
for _, entity := range entities {
// 座標描画
pos := gameComponents.Position.Get(entity).(*gc.Position)
spriteRender := gameComponents.SpriteRender.Get(entity).(*ec.SpriteRender)
drawImage(world, screen, spriteRender, pos)
}
}
}
func drawImage(world w.World, screen *ebiten.Image, spriteRender *ec.SpriteRender, pos *gc.Position) {
sprite := spriteRender.SpriteSheet.Sprites[spriteRender.SpriteNumber]
texture := spriteRender.SpriteSheet.Texture
textureWidth, textureHeight := texture.Image.Size()
// テクスチャから欲しいスプライトを切り出す
left := m.Max(0, sprite.X)
right := m.Min(textureWidth, sprite.X+sprite.Width)
top := m.Max(0, sprite.Y)
bottom := m.Min(textureHeight, sprite.Y+sprite.Height)
op := &spriteRender.Options
op.GeoM.Reset() // FIXME: Resetがないと非表示になる。なぜ?
op.GeoM.Translate(float64(-sprite.Width/2), float64(-sprite.Width/2)) // 回転軸を画像の中心にする
op.GeoM.Rotate(pos.Angle)
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
camera.SetTranslate(world, op)
screen.DrawImage(texture.Image.SubImage(image.Rect(left, top, right, bottom)).(*ebiten.Image), op)
}