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