-
Notifications
You must be signed in to change notification settings - Fork 0
/
entity.go
116 lines (100 loc) · 3.02 KB
/
entity.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package engine
import (
"image/color"
"engine/vec2"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
// Entity is basis for all entities in the game
type Entity struct {
Position *vec2.T // position in the world
Image *ebiten.Image // (optional) image to draw
ImageOffset *vec2.T // draw image at offset relative to position
ImageScale float64 // scale image before drawing
HitboxSize *vec2.T // (optional) size of hitbox relative to position
HitboxOffset *vec2.T // offset of hitbox relative to position
Alive bool // dead or alive?
Debug bool // debug mode
}
// NewEntity created a new entity and sets sane defaults
func NewEntity() *Entity {
entity := &Entity{
Position: &vec2.T{X: 0.0, Y: 0.0},
Image: nil,
ImageOffset: &vec2.T{X: 0.0, Y: 0.0},
ImageScale: 1.0,
HitboxSize: nil,
HitboxOffset: &vec2.T{X: 0.0, Y: 0.0},
Alive: true,
Debug: false,
}
return entity
}
// ImageRect builds destination rectangle of image in world
func (entity *Entity) ImageRect() vec2.Rect {
imageSize := vec2.NewI(entity.Image.Size()).AsT()
minPoint := entity.Position.Added(entity.ImageOffset)
return vec2.Rect{
Min: minPoint,
Max: minPoint.Added(imageSize.Muled(entity.ImageScale)),
}
}
// Update should be called in game loop
func (entity *Entity) Update() error {
if inpututil.IsKeyJustPressed(ebiten.KeyF10) {
entity.ToggleDebug()
}
return nil
}
// Draw should be called in draw loop
func (entity *Entity) Draw(screen *ebiten.Image) {
if entity.Image != nil {
options := &ebiten.DrawImageOptions{}
options.GeoM.Scale(entity.ImageScale, entity.ImageScale)
options.GeoM.Translate(
entity.Position.Added(entity.ImageOffset).Coords(),
)
screen.DrawImage(entity.Image, options)
}
if entity.Debug {
if entity.HitboxSize != nil {
DrawRect(screen, *entity.Hitbox(), color.RGBA{255, 0, 0, 255})
}
if entity.Image != nil {
DrawRect(screen, entity.ImageRect(), color.RGBA{0, 255, 0, 255})
}
DrawRect(
screen,
*vec2.NewRect(entity.Position.X, entity.Position.Y, 2, 2),
color.RGBA{0, 0, 255, 255},
)
}
}
// Center provides the middle point of this entity (image)
func (entity *Entity) Center() *vec2.T {
halfImageSize := vec2.NewI(entity.Image.Size()).AsT().Mul(0.5)
return entity.Position.Added(halfImageSize).Add(entity.ImageOffset)
}
// Hitbox returns entities hitbox, which is based on players position, as well
// as hitbox offset and size
func (entity *Entity) Hitbox() *vec2.Rect {
if entity.HitboxSize == nil {
return nil
}
return &vec2.Rect{
Min: entity.Position.Added(entity.HitboxOffset),
Max: entity.Position.Added(entity.HitboxOffset).Add(entity.HitboxSize),
}
}
// Die kills the entity
func (entity *Entity) Die() {
entity.Alive = false
}
// Dead returns true if the entity is dead
func (entity *Entity) Dead() bool {
return !entity.Alive
}
// ToggleDebug mode for this entity
func (entity *Entity) ToggleDebug() {
entity.Debug = !entity.Debug
}