wall?
This commit is contained in:
parent
d3cc842b12
commit
3168c5eb54
1 changed files with 108 additions and 0 deletions
108
engine/walls.go
Normal file
108
engine/walls.go
Normal file
|
@ -0,0 +1,108 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
_ interface {
|
||||
Collider
|
||||
Identifier
|
||||
Scanner
|
||||
} = &Wall{}
|
||||
|
||||
_ interface {
|
||||
Drawer
|
||||
DrawOrderer
|
||||
Disabler
|
||||
Hider
|
||||
Prepper
|
||||
Updater
|
||||
} = &WallUnit{}
|
||||
)
|
||||
|
||||
// Wall is a more flexible kind of tilemap. WallUnits can be added at the same
|
||||
// level as other components and are responsible for their own drawing, so that
|
||||
// Scene can do draw ordering, e.g. hide the player character behind a wall.
|
||||
// But Wall is still responsible for collisions.
|
||||
type Wall struct {
|
||||
ID
|
||||
Ersatz bool
|
||||
Offset image.Point // offset the whole wall
|
||||
Sheet Sheet
|
||||
UnitOffset image.Point // drawing offset
|
||||
UnitSize image.Point // tile size
|
||||
|
||||
units map[image.Point]*WallUnit
|
||||
}
|
||||
|
||||
func (w *Wall) regUnit(u *WallUnit) {
|
||||
if w.units == nil {
|
||||
w.units = make(map[image.Point]*WallUnit)
|
||||
}
|
||||
w.units[u.Pos] = u
|
||||
}
|
||||
|
||||
func (w *Wall) CollidesWith(r image.Rectangle) bool {
|
||||
if w.Ersatz {
|
||||
return false
|
||||
}
|
||||
|
||||
// Probe the map at all tilespace coordinates overlapping the rect.
|
||||
r = r.Sub(w.Offset)
|
||||
min := div2(r.Min, w.UnitSize)
|
||||
max := div2(r.Max.Sub(image.Pt(1, 1)), w.UnitSize) // NB: fencepost
|
||||
|
||||
for j := min.Y; j <= max.Y; j++ {
|
||||
for i := min.X; i <= max.X; i++ {
|
||||
if w.units[image.Pt(i, j)] != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Wall) Scan() []interface{} { return []interface{}{&w.Sheet} }
|
||||
|
||||
// WallUnit
|
||||
type WallUnit struct {
|
||||
Disabled
|
||||
Hidden
|
||||
Pos image.Point // tilespace coordinates
|
||||
Tile Tile // chooses which cell in wall.Sheet to draw
|
||||
WallID string
|
||||
ZOrder
|
||||
|
||||
wall *Wall
|
||||
}
|
||||
|
||||
func (u *WallUnit) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||
if u.Hidden {
|
||||
return
|
||||
}
|
||||
var geom ebiten.GeoM
|
||||
geom.Translate(float2(mul2(u.Pos, u.wall.UnitSize).Add(u.wall.UnitOffset).Add(u.wall.Offset)))
|
||||
geom.Concat(opts.GeoM)
|
||||
opts.GeoM = geom
|
||||
|
||||
src := u.wall.Sheet.SubImage(u.Tile.CellIndex())
|
||||
screen.DrawImage(src, &opts)
|
||||
}
|
||||
|
||||
func (u *WallUnit) Prepare(g *Game) {
|
||||
u.wall = g.Component(u.WallID).(*Wall)
|
||||
u.wall.regUnit(u)
|
||||
}
|
||||
|
||||
func (u *WallUnit) Update() error {
|
||||
if u.Disabled {
|
||||
return nil
|
||||
}
|
||||
if up, ok := u.Tile.(Updater); ok {
|
||||
return up.Update()
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in a new issue