changes:
- exchanged switch+door sprites - added asesprite cheat sheet - implemented door toggle on switch toggle
23
asesprite.org
Normal file
@ -0,0 +1,23 @@
|
||||
| key | sub key | function | hint |
|
||||
|--------------+------------+-----------------------+----------------------------------|
|
||||
| b | | brush | |
|
||||
| | d | draw | |
|
||||
| | s | shape | select color range before |
|
||||
| | x | switch color order | |
|
||||
| | a | alpha shape | |
|
||||
| | ctrl+wheel | brush size | |
|
||||
| c | | pick color | |
|
||||
| e | | erase | |
|
||||
| z | | zoom | click and drag, left+right click |
|
||||
| middle mouse | | move canvas | |
|
||||
| f | | fill | inside selection |
|
||||
| ctrl-d | | no selection | |
|
||||
| m | | marquee | rect selection |
|
||||
| w | | select by color | contiguous: all or only region |
|
||||
| q | | lasso select | |
|
||||
| tab | | hide/show layers | |
|
||||
| v | | switch layer | by click on region |
|
||||
| alt-n | | new frame | |
|
||||
| shift-n | | new layer | |
|
||||
| ctrl-f | | hide/show ui elements | |
|
||||
| shift-o | | outline tool | |
|
||||
@ -6096,7 +6096,15 @@
|
||||
"height": 32,
|
||||
"defUid": 65,
|
||||
"px": [224,224],
|
||||
"fieldInstances": [{ "__identifier": "Entity_ref", "__type": "EntityRef", "__value": null, "__tile": null, "defUid": 68, "realEditorValues": [] }],
|
||||
"fieldInstances": [{ "__identifier": "Entity_ref", "__type": "EntityRef", "__value": {
|
||||
"entityIid": "7d975370-d7b0-11ee-9add-971995295000",
|
||||
"layerIid": "50624190-d7b0-11ee-968e-3dbcbdc42f40",
|
||||
"levelIid": "50621a80-d7b0-11ee-968e-a98c2d35fbdb",
|
||||
"worldIid": "267ee1a0-d7b0-11ee-a97e-53f0a359eae1"
|
||||
}, "__tile": null, "defUid": 68, "realEditorValues": [{
|
||||
"id": "V_String",
|
||||
"params": ["7d975370-d7b0-11ee-9add-971995295000"]
|
||||
}] }],
|
||||
"__worldX": 0,
|
||||
"__worldY": 2976
|
||||
},
|
||||
|
||||
@ -240,8 +240,8 @@ func InitTiles() TileRegistry {
|
||||
"HiddenDoor11": NewTileHiddenDoor("block-greycolored", "damage"),
|
||||
"HiddenDoor12": NewTileHiddenDoor("block-greycolored", "damage"),
|
||||
"HiddenDoor13": NewTileHiddenDoor("block-greycolored", "damage"),
|
||||
"Switch": NewTileSwitch([]string{"switch-open.png", "switch-closed.png"}),
|
||||
"Door": NewTileDoor([]string{"door-open.png", "door-closed.png"}),
|
||||
"Switch": NewTileSwitch([]string{"switch1", "switch2"}),
|
||||
"Door": NewTileDoor([]string{"door1", "door2"}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 280 B |
|
Before Width: | Height: | Size: 250 B |
BIN
assets/sprites/door1.png
Normal file
|
After Width: | Height: | Size: 477 B |
BIN
assets/sprites/door2.png
Normal file
|
After Width: | Height: | Size: 446 B |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 463 B |
BIN
assets/sprites/switch1.png
Normal file
|
After Width: | Height: | Size: 508 B |
BIN
assets/sprites/switch2.png
Normal file
|
After Width: | Height: | Size: 532 B |
@ -23,11 +23,15 @@ type Door struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
func (door *Door) Open() *ebiten.Image {
|
||||
func (door *Door) Toggle() {
|
||||
door.IsOpen = !door.IsOpen
|
||||
}
|
||||
|
||||
func (door *Door) Sprite() *ebiten.Image {
|
||||
if door.IsOpen {
|
||||
return door.OpenSprite
|
||||
}
|
||||
|
||||
func (door *Door) Close() *ebiten.Image {
|
||||
return door.CloseSprite
|
||||
}
|
||||
|
||||
@ -39,3 +43,15 @@ type Switch struct {
|
||||
CloseSprite *ebiten.Image
|
||||
Ref string // the IId of the door
|
||||
}
|
||||
|
||||
func (switcher *Switch) Toggle() {
|
||||
switcher.IsOpen = !switcher.IsOpen
|
||||
}
|
||||
|
||||
func (switcher *Switch) Sprite() *ebiten.Image {
|
||||
if switcher.IsOpen {
|
||||
return switcher.OpenSprite
|
||||
}
|
||||
|
||||
return switcher.CloseSprite
|
||||
}
|
||||
|
||||
@ -55,6 +55,8 @@ func NewLevel(game *Game, cellsize int, plan *ldtkgo.Level) *Level {
|
||||
systemlist = append(systemlist, systems.NewDestroyableSystem(game.World, gridcontainer,
|
||||
game.Cellsize))
|
||||
|
||||
systemlist = append(systemlist, systems.NewPairSystem(game.World, gridcontainer))
|
||||
|
||||
systemlist = append(systemlist, systems.NewHudSystem(game.World, plan))
|
||||
|
||||
mapslice, backupmap := LevelToSlice(game, plan, cellsize)
|
||||
@ -176,11 +178,15 @@ func LevelToSlice(game *Game, level *ldtkgo.Level, tilesize int) (Map, Map) {
|
||||
if ref.Value != nil {
|
||||
refid := ref.Value.(map[string]interface{})
|
||||
tile.Ref = refid["entityIid"].(string)
|
||||
slog.Debug("LOAD TILE", "tileref",
|
||||
tile.Ref, "tileid", tile.Id,
|
||||
"name", entity.Identifier,
|
||||
"isswitch", tile.Switch,
|
||||
"isdoor", tile.Door,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
slog.Debug("LOAD TILE", "tile", entity.TileRect)
|
||||
|
||||
tileRect := entity.TileRect
|
||||
|
||||
tile.Sprite = tileset.SubImage(
|
||||
|
||||
12
grid/grid.go
@ -8,8 +8,6 @@ import (
|
||||
"openquell/config"
|
||||
"openquell/observers"
|
||||
|
||||
"log/slog"
|
||||
|
||||
"github.com/mlange-42/arche/ecs"
|
||||
"github.com/mlange-42/arche/generic"
|
||||
)
|
||||
@ -141,16 +139,16 @@ func NewGrid(world *ecs.World,
|
||||
case tile.Switch:
|
||||
entity := switchmapper.New()
|
||||
pos, render, _, switcher = switchmapper.Get(entity)
|
||||
switcher.OpenSprite = tile.Tiles[0]
|
||||
switcher.CloseSprite = tile.Tiles[0]
|
||||
switcher.OpenSprite = tile.Tiles[1]
|
||||
switcher.Ref = tile.Ref
|
||||
switches = append(switches, entity)
|
||||
|
||||
case tile.Door:
|
||||
entity := doormapper.New()
|
||||
pos, render, _, door = doormapper.Get(entity)
|
||||
door.OpenSprite = tile.Tiles[0]
|
||||
door.CloseSprite = tile.Tiles[0]
|
||||
door.OpenSprite = tile.Tiles[1]
|
||||
door.Id = tile.Id
|
||||
doors = append(doors, entity)
|
||||
|
||||
@ -176,17 +174,19 @@ func NewGrid(world *ecs.World,
|
||||
pos.Update(point.X*tilesize, point.Y*tilesize, tilesize)
|
||||
}
|
||||
|
||||
// check for switch->door references
|
||||
for _, switchentity := range switches {
|
||||
_, _, bond, switcher = switchmapper.Get(switchentity)
|
||||
|
||||
if switcher.Ref != "" {
|
||||
// this switch has a reference
|
||||
for _, doorentity := range doors {
|
||||
_, _, _, door = doormapper.Get(doorentity)
|
||||
if door.Id == switcher.Ref {
|
||||
// the switch reference matches the door id, relate the two
|
||||
bond.Ref = switcher.Ref
|
||||
relID := ecs.ComponentID[components.Bond](world)
|
||||
world.Relations().Set(doorentity, relID, switchentity)
|
||||
slog.Debug("setup switch/door reference")
|
||||
world.Relations().Set(switchentity, relID, doorentity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
117
systems/pair_system.go
Normal file
@ -0,0 +1,117 @@
|
||||
package systems
|
||||
|
||||
import (
|
||||
"openquell/components"
|
||||
. "openquell/components"
|
||||
. "openquell/config"
|
||||
"openquell/grid"
|
||||
"openquell/observers"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/mlange-42/arche/ecs"
|
||||
"github.com/mlange-42/arche/generic"
|
||||
)
|
||||
|
||||
type PairSystem struct {
|
||||
World *ecs.World
|
||||
DoorSelector *generic.Filter4[Position, Renderable, Bond, Door]
|
||||
SwitchSelector *generic.Filter4[Position, Renderable, Bond, Switch]
|
||||
GridContainer *grid.GridContainer
|
||||
DoorMapper generic.Map4[
|
||||
components.Position,
|
||||
components.Renderable,
|
||||
components.Bond,
|
||||
components.Door]
|
||||
}
|
||||
|
||||
type ToggleDoor struct {
|
||||
Entity ecs.Entity
|
||||
Open bool
|
||||
}
|
||||
|
||||
func NewPairSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
|
||||
doormapper := generic.NewMap4[
|
||||
components.Position,
|
||||
components.Renderable,
|
||||
components.Bond,
|
||||
components.Door](world)
|
||||
|
||||
system := &PairSystem{
|
||||
DoorSelector: generic.NewFilter4[Position, Renderable, Bond, Door](),
|
||||
SwitchSelector: generic.NewFilter4[Position, Renderable, Bond, Switch](),
|
||||
World: world,
|
||||
GridContainer: gridcontainer,
|
||||
DoorMapper: doormapper,
|
||||
}
|
||||
|
||||
return system
|
||||
}
|
||||
|
||||
func (system *PairSystem) Update() error {
|
||||
observer := observers.GetGameObserver(system.World)
|
||||
posID := ecs.ComponentID[components.Position](system.World)
|
||||
veloID := ecs.ComponentID[components.Velocity](system.World)
|
||||
|
||||
query := system.SwitchSelector.Query(system.World)
|
||||
relID := ecs.ComponentID[Bond](system.World)
|
||||
|
||||
EntitiesToSwitch := []*ToggleDoor{}
|
||||
|
||||
for query.Next() {
|
||||
swpos, _, _, switcher := query.Get()
|
||||
|
||||
for _, player := range observer.GetPlayers() {
|
||||
if !system.World.Alive(player) {
|
||||
continue
|
||||
}
|
||||
|
||||
playerposition := (*Position)(system.World.Get(player, posID))
|
||||
playervelocity := (*Velocity)(system.World.Get(player, veloID))
|
||||
|
||||
ok, newpos := swpos.Intersects(playerposition, playervelocity)
|
||||
if ok {
|
||||
// player moved on top of the switch
|
||||
switcher.Toggle()
|
||||
// open door
|
||||
door := system.World.Relations().Get(query.Entity(), relID)
|
||||
EntitiesToSwitch = append(EntitiesToSwitch,
|
||||
&ToggleDoor{Entity: door, Open: true})
|
||||
|
||||
playervelocity.Change(Stop)
|
||||
playerposition.Set(newpos)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, toggle := range EntitiesToSwitch {
|
||||
_, _, _, door := system.DoorMapper.Get(toggle.Entity)
|
||||
door.Toggle()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (system *PairSystem) Draw(screen *ebiten.Image) {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
query := system.SwitchSelector.Query(system.World)
|
||||
|
||||
for query.Next() {
|
||||
pos, _, _, switcher := query.Get()
|
||||
|
||||
op.GeoM.Reset()
|
||||
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
||||
screen.DrawImage(switcher.Sprite(), op)
|
||||
}
|
||||
|
||||
doorquery := system.DoorSelector.Query(system.World)
|
||||
|
||||
for doorquery.Next() {
|
||||
pos, _, _, door := doorquery.Get()
|
||||
|
||||
op.GeoM.Reset()
|
||||
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
||||
screen.DrawImage(door.Sprite(), op)
|
||||
}
|
||||
|
||||
}
|
||||