diff --git a/TODO.md b/TODO.md index b1d5f86..4bba62b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,22 +1,8 @@ ## Levels: -- Add shaders for animation (player destruction etc) - - Start New game starts with last played level, better add a Resume Game menu item for this and use Start New always for level 1. -- for finding caller: - pc := make([]uintptr, 10) - n := runtime.Callers(0, pc) - pc = pc[:n] - fs := runtime.CallersFrames(pc) - source, _ := fs.Next() - source, _ = fs.Next() - source, _ = fs.Next() - - slog.Debug("get observer", "minmoves", observer.LevelScore, - "file", source.File, "line", source.Line) - - Turn menu button in hud_system (events in level_scene!) into ebitenui button - Obstacle don't stop at collectibles @@ -47,8 +33,6 @@ - Add save to disk feature including settings and player accomplishements (FIXME: find the lib, asked in Discord) -- Add coded animated background like in https://github.com/tinne26/bindless/tree/main/src/misc/background - - Rework sprites (again!) to match stellar background: maybe more technical tiles and items? Like some robotic setup? @@ -56,10 +40,6 @@ or south (NOT left or north!) it snaps in visibly, so a short wobble can be seen. -- Rework animation system: since it is impossible to assign multiple - animation types to an entity via LDTK, hard code it in Tiles. Keep - implementation though. CAUTION: last time I changed this, the - collectible detonation didn't work anymore! @@ -82,3 +62,17 @@ Collider.IntersectResolve => func(newpos) {player.pos = newpos; player.vel = stop} - in the end it must be possible to add new entities without the need to write a collision check for them, but have collision detection anyway! + +## Just in case stuff + +- for finding caller: + pc := make([]uintptr, 10) + n := runtime.Callers(0, pc) + pc = pc[:n] + fs := runtime.CallersFrames(pc) + source, _ := fs.Next() + source, _ = fs.Next() + source, _ = fs.Next() + + slog.Debug("get observer", "minmoves", observer.LevelScore, + "file", source.File, "line", source.Line) diff --git a/assets/space/space.pal b/assets/space/space.pal new file mode 100644 index 0000000..c98d91e --- /dev/null +++ b/assets/space/space.pal @@ -0,0 +1,42 @@ +JASC-PAL +0100 +39 +32 0 59 +63 0 83 +108 0 108 +146 0 124 +187 0 151 +236 0 178 +255 19 186 +255 64 190 +255 113 213 +255 147 231 +255 186 253 +245 220 255 +255 255 255 +0 0 0 +12 12 12 +26 26 26 +39 39 39 +54 54 54 +71 71 71 +86 86 86 +99 99 99 +118 118 118 +133 133 133 +153 153 153 +177 177 177 +205 205 205 +42 2 0 +52 9 0 +71 24 0 +94 46 0 +131 71 0 +165 96 0 +201 106 0 +243 119 0 +255 165 41 +255 186 82 +255 239 169 +255 250 211 +255 255 247 diff --git a/assets/space/tilemap-oil.ase b/assets/space/tilemap-oil.ase new file mode 100644 index 0000000..6a37361 Binary files /dev/null and b/assets/space/tilemap-oil.ase differ diff --git a/assets/space/tilemap-oil.png b/assets/space/tilemap-oil.png new file mode 100644 index 0000000..ed1ded0 Binary files /dev/null and b/assets/space/tilemap-oil.png differ diff --git a/components/position.go b/components/position.go index f9b5d2f..8abef8e 100644 --- a/components/position.go +++ b/components/position.go @@ -115,3 +115,8 @@ func (tile *Position) Intersects(moving *Position, velocity *Velocity) (bool, *P return false, nil } + +func (tile *Position) Intersecting(position *Position, velocity *Velocity) bool { + is := tile.Rect.Bounds().Intersect(position.Rect.Bounds()) + return is != image.ZR +} diff --git a/grid/collider.go b/grid/collider.go index de2f661..38a19ab 100644 --- a/grid/collider.go +++ b/grid/collider.go @@ -3,6 +3,8 @@ package grid import ( "openquell/components" . "openquell/config" + + "log/slog" ) // Check a collision on the grid. We check if the entity in question @@ -24,8 +26,8 @@ func (grid *Grid) CheckGridCollision( } else { ok, tilepos := grid.GetSolidNeighborPosition(position, velocity, true) if ok { - // slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos", - // tilepos.Point(), "playerpos", playerposition) + slog.Debug("(3) HaveSolidNeighbor", "tilepos", + tilepos.String(), "playpos", position.String()) intersects, newpos := tilepos.Intersects(position, velocity) if intersects { respond_solid(position, velocity, newpos) @@ -44,6 +46,66 @@ func (grid *Grid) GetSolidNeighborPosition( return false, nil } + // set to true if we are already on the last tile in the current + // direction, i.e. on the edge of the grid + edge := true + moving := position.GetMoved(velocity) + + neighborpos := position.Point() + if velocity.Direction == East || velocity.Direction == South { + // FIXES snapin to down+right, but now top+left fail. Only in + // these cases we need to look at the neighbor in the future + // position where we will be when we move forward. I don't + // know why it is like this, in fact it doesn't really make + // any sense. But it works, so I'll keep it that way for the + // moment. + neighborpos = moving.Point() + } + + switch velocity.Direction { + case East: + if neighborpos.X < grid.TilesX { + neighborpos.X++ + edge = false + } + case West: + if neighborpos.X > 0 { + neighborpos.X-- + edge = false + } + case South: + if neighborpos.Y < grid.TilesY { + neighborpos.Y++ + edge = false + } + case North: + if neighborpos.Y > 0 { + neighborpos.Y-- + edge = false + } + } + + newpos := components.NewPosition(neighborpos, grid.Tilesize) + + slog.Debug("SolidNeighbor?", "player", position.Point(), + "neighbor", neighborpos, "edge", edge, "neighbor-solid", + grid.Map[neighborpos].Solid, "newpos", newpos.Point()) + if !edge && grid.Map[neighborpos].Solid { + return true, newpos + } + + return false, nil +} + +func (grid *Grid) OrigGetSolidNeighborPosition( + position *components.Position, + velocity *components.Velocity, + solid bool) (bool, *components.Position) { + + if !solid { + return false, nil + } + // set to true if we are already on the last tile in the current // direction, i.e. on the edge of the grid edge := true @@ -74,9 +136,9 @@ func (grid *Grid) GetSolidNeighborPosition( newpos := components.NewPosition(neighborpos, grid.Tilesize) - // slog.Debug("SolidNeighbor?", "player", position.Point(), - // "neighbor", neighborpos, "edge", edge, "neighbor-solid", - // grid.Map[neighborpos].Solid, "newpos", newpos.Point()) + slog.Debug("SolidNeighbor?", "player", position.Point(), + "neighbor", neighborpos, "edge", edge, "neighbor-solid", + grid.Map[neighborpos].Solid, "newpos", newpos.Point()) if !edge && grid.Map[neighborpos].Solid { return true, newpos } diff --git a/systems/player_system.go b/systems/player_system.go index f4f7025..6264fd5 100644 --- a/systems/player_system.go +++ b/systems/player_system.go @@ -1,6 +1,7 @@ package systems import ( + "fmt" "log/slog" "openquell/components" . "openquell/components" @@ -9,6 +10,7 @@ import ( "openquell/observers" "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/mlange-42/arche/ecs" "github.com/mlange-42/arche/generic" @@ -46,6 +48,7 @@ func PlayerBumpWallResponder( vel *components.Velocity, newpos *components.Position) { + slog.Debug("(2) PlayerBumpWallResponder", "old", pos.String(), "new", newpos.String()) pos.Set(newpos) vel.Change(Stop) } @@ -67,12 +70,16 @@ func (system PlayerSystem) Update() error { continue } - // check if the user alters or initiates movement + // check if the user alters or initiates movement, only + // changes player direction system.CheckMovement(playerposition, velocity, player) // check if player collides with walls or edges - system.GridContainer.Grid.CheckGridCollision( - playerposition, velocity, PlayerBumpEdgeResponder, PlayerBumpWallResponder) + if velocity.Moving() { + slog.Debug("(2) checking grid collision") + system.GridContainer.Grid.CheckGridCollision( + playerposition, velocity, PlayerBumpEdgeResponder, PlayerBumpWallResponder) + } if count > 1 { // check if player collides with another player, fuse them if any @@ -99,7 +106,11 @@ func (system PlayerSystem) Update() error { query = system.Selector.Query(system.World) for query.Next() { playerposition, velocity, _, _ := query.Get() - playerposition.Move(velocity) + oldpos := playerposition.String() + if velocity.Moving() { + playerposition.Move(velocity) + slog.Debug("(4) moving player", "old", oldpos, "new", playerposition.String()) + } } // we may have lost players, remove them here @@ -124,6 +135,8 @@ func (system *PlayerSystem) Draw(screen *ebiten.Image) { op.GeoM.Translate(float64(pos.X), float64(pos.Y)) screen.DrawImage(sprite.Image, op) + + ebitenutil.DebugPrintAt(screen, pos.String(), pos.X, pos.Y) // print player pos } } @@ -196,6 +209,9 @@ func (system *PlayerSystem) CheckMovement( player.LoopCount = 0 observer.AddMove() } + } else { + fmt.Println("------------------------") + slog.Debug("(1) player is at", "current", position.String()) } }