tiles and walls

This commit is contained in:
Josh Deprez 2021-09-01 13:46:26 +10:00
parent 91785fb6c0
commit 1535573550
2 changed files with 40 additions and 22 deletions

View file

@ -14,6 +14,7 @@ var _ interface {
Drawer Drawer
Hider Hider
Scanner Scanner
Transformer
} = &Tilemap{} } = &Tilemap{}
// Ensure StaticTile and AnimatedTile satisfy Tile. // Ensure StaticTile and AnimatedTile satisfy Tile.
@ -67,13 +68,12 @@ func (t *Tilemap) CollidesWith(r image.Rectangle) bool {
// Draw draws the tilemap. // Draw draws the tilemap.
func (t *Tilemap) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) { func (t *Tilemap) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
og := opts.GeoM og := opts.GeoM
var geom ebiten.GeoM
for p, tile := range t.Map { for p, tile := range t.Map {
if tile == nil { if tile == nil {
continue continue
} }
geom.Reset() var geom ebiten.GeoM
geom.Translate(float2(mul2(p, t.Sheet.CellSize).Add(t.Offset))) geom.Translate(float2(mul2(p, t.Sheet.CellSize)))
geom.Concat(og) geom.Concat(og)
opts.GeoM = geom opts.GeoM = geom
@ -92,6 +92,11 @@ func (t *Tilemap) Scan() []interface{} {
return c return c
} }
func (t *Tilemap) Transform() (opts ebiten.DrawImageOptions) {
opts.GeoM.Translate(float2(t.Offset))
return opts
}
// TileAt returns the tile present at the given world coordinate. // TileAt returns the tile present at the given world coordinate.
func (t *Tilemap) TileAt(wc image.Point) Tile { func (t *Tilemap) TileAt(wc image.Point) Tile {
return t.Map[div2(wc.Sub(t.Offset), t.Sheet.CellSize)] return t.Map[div2(wc.Sub(t.Offset), t.Sheet.CellSize)]

View file

@ -11,13 +11,14 @@ var (
Collider Collider
Identifier Identifier
Scanner Scanner
Prepper
Transformer
} = &Wall{} } = &Wall{}
_ interface { _ interface {
Drawer Drawer
Disabler Disabler
Hider Hider
Prepper
Scanner Scanner
Transformer Transformer
} = &WallUnit{} } = &WallUnit{}
@ -34,17 +35,10 @@ type Wall struct {
Sheet Sheet Sheet Sheet
UnitOffset image.Point // drawing offset UnitOffset image.Point // drawing offset
UnitSize image.Point // tile size UnitSize image.Point // tile size
Units map[image.Point]*WallUnit
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
} }
// CollidesWith implements a tilerange collosion check, similar to Tilemap.
func (w *Wall) CollidesWith(r image.Rectangle) bool { func (w *Wall) CollidesWith(r image.Rectangle) bool {
if w.Ersatz { if w.Ersatz {
return false return false
@ -57,7 +51,7 @@ func (w *Wall) CollidesWith(r image.Rectangle) bool {
for j := min.Y; j <= max.Y; j++ { for j := min.Y; j <= max.Y; j++ {
for i := min.X; i <= max.X; i++ { for i := min.X; i <= max.X; i++ {
if w.units[image.Pt(i, j)] != nil { if w.Units[image.Pt(i, j)] != nil {
return true return true
} }
} }
@ -65,7 +59,30 @@ func (w *Wall) CollidesWith(r image.Rectangle) bool {
return false return false
} }
func (w *Wall) Scan() []interface{} { return []interface{}{&w.Sheet} } // Scan returns the Sheet and all WallUnits.
func (w *Wall) Scan() []interface{} {
c := make([]interface{}, 1, len(w.Units)+1)
c[0] = &w.Sheet
for _, unit := range w.Units {
c = append(c, unit)
}
return c
}
// Prepare makes sure all WallUnits know about Wall.
func (w *Wall) Prepare(*Game) error {
// Ensure all child units know about wall, which houses common attributes
for _, u := range w.Units {
u.wall = w
}
return nil
}
// Transform returns a GeoM translation by Offset.
func (w *Wall) Transform() (opts ebiten.DrawImageOptions) {
opts.GeoM.Translate(float2(w.Offset))
return opts
}
// WallUnit is a unit in a wall. Unlike a tile in a tilemap, WallUnit is // WallUnit is a unit in a wall. Unlike a tile in a tilemap, WallUnit is
// responsible for drawing itself. // responsible for drawing itself.
@ -80,19 +97,15 @@ type WallUnit struct {
wall *Wall wall *Wall
} }
// Draw draws this wall unit.
func (u *WallUnit) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) { func (u *WallUnit) Draw(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
screen.DrawImage(u.wall.Sheet.SubImage(u.Tile.CellIndex()), opts) screen.DrawImage(u.wall.Sheet.SubImage(u.Tile.CellIndex()), opts)
} }
func (u *WallUnit) Prepare(g *Game) error { // Scan returns the Tile.
u.wall = g.Component(u.WallID).(*Wall)
u.wall.regUnit(u)
return nil
}
func (u *WallUnit) Scan() []interface{} { return []interface{}{u.Tile} } func (u *WallUnit) Scan() []interface{} { return []interface{}{u.Tile} }
func (u *WallUnit) Transform() (opts ebiten.DrawImageOptions) { func (u *WallUnit) Transform() (opts ebiten.DrawImageOptions) {
opts.GeoM.Translate(float2(mul2(u.Pos, u.wall.UnitSize).Add(u.wall.UnitOffset).Add(u.wall.Offset))) opts.GeoM.Translate(float2(mul2(u.Pos, u.wall.UnitSize).Add(u.wall.UnitOffset)))
return opts return opts
} }