fixed observers, added GameObserver
This commit is contained in:
parent
72f0aa7691
commit
65ddec3fa4
17
assets/levels/0-own.lvl
Normal file
17
assets/levels/0-own.lvl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Description: win
|
||||||
|
Background: background-lila
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########
|
||||||
|
# #o#
|
||||||
|
# S # #
|
||||||
|
# #### #
|
||||||
|
|
||||||
|
|
||||||
|
# #### #
|
||||||
|
# #
|
||||||
|
# o #
|
||||||
|
########
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
width=$(grep "width int" ../main.go | awk '{print $4}')
|
width=$(grep "width " ../../main.go | awk '{print $4}')
|
||||||
height=$(grep "height int" ../main.go | awk '{print $4}')
|
height=$(grep "height " ../../main.go | awk '{print $4}')
|
||||||
|
|
||||||
read -p " Enter level name: " name
|
read -p " Enter level name: " name
|
||||||
read -p " Enter background: " background
|
read -p " Enter background: " background
|
||||||
@ -14,11 +14,12 @@ if test -z "$bbackground"; then
|
|||||||
background="background-lila"
|
background="background-lila"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
w=$(($width/32))
|
||||||
|
h=$(($height/32))
|
||||||
|
|
||||||
(
|
(
|
||||||
echo "Description: $des"
|
echo "Description: $des"
|
||||||
echo "Background: $background"
|
echo "Background: $background"
|
||||||
w=$(($width / 32))
|
|
||||||
h=$(($height / 32))
|
|
||||||
|
|
||||||
for x in $(seq 1 $h); do
|
for x in $(seq 1 $h); do
|
||||||
for y in $(seq 1 $w); do
|
for y in $(seq 1 $w); do
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
Description: Introduction: collect the goods by moving the ball onto them
|
|
||||||
Background: background-lila
|
|
||||||
####################
|
|
||||||
# #
|
|
||||||
# #
|
|
||||||
# #
|
|
||||||
# #
|
|
||||||
# #
|
|
||||||
# #
|
|
||||||
# ######
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
####################
|
|
||||||
@ -10,14 +10,18 @@ type Renderable struct {
|
|||||||
Image *ebiten.Image
|
Image *ebiten.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Particle struct {
|
||||||
|
Index int
|
||||||
|
Particles []*ebiten.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
type Speed struct {
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
// only tile entities will have those
|
// only tile entities will have those
|
||||||
type Tilish struct{}
|
type Tilish struct{}
|
||||||
type Solid struct{}
|
type Solid struct{}
|
||||||
type Floor struct{}
|
type Floor struct{}
|
||||||
type Player struct{}
|
type Player struct{}
|
||||||
type Collectible struct{}
|
type Collectible struct{}
|
||||||
|
|
||||||
type Particle struct {
|
|
||||||
Index int
|
|
||||||
Particles []*ebiten.Image
|
|
||||||
}
|
|
||||||
|
|||||||
@ -70,8 +70,8 @@ func (position *Position) String() string {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (position *Position) Move(velocity *Velocity) {
|
func (position *Position) Move(velocity *Velocity, speed *Speed) {
|
||||||
position.Update(position.X+velocity.Data.X, position.Y+velocity.Data.Y)
|
position.Update(position.X+(velocity.Data.X*speed.Value), position.Y+(velocity.Data.Y*speed.Value))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (position *Position) Set(newpos *Position) {
|
func (position *Position) Set(newpos *Position) {
|
||||||
|
|||||||
@ -11,21 +11,19 @@ type Velocity struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (velocity *Velocity) Change(direction int) {
|
func (velocity *Velocity) Change(direction int) {
|
||||||
ticks := 4
|
|
||||||
|
|
||||||
switch direction {
|
switch direction {
|
||||||
case East:
|
case East:
|
||||||
velocity.Data.X = ticks
|
velocity.Data.X = 1
|
||||||
velocity.Data.Y = 0
|
velocity.Data.Y = 0
|
||||||
case West:
|
case West:
|
||||||
velocity.Data.X = ticks - (ticks * 2)
|
velocity.Data.X = -1
|
||||||
velocity.Data.Y = 0
|
velocity.Data.Y = 0
|
||||||
case South:
|
case South:
|
||||||
velocity.Data.X = 0
|
velocity.Data.X = 0
|
||||||
velocity.Data.Y = ticks
|
velocity.Data.Y = 1
|
||||||
case North:
|
case North:
|
||||||
velocity.Data.X = 0
|
velocity.Data.X = 0
|
||||||
velocity.Data.Y = ticks - (ticks * 2)
|
velocity.Data.Y = -1
|
||||||
case Stop:
|
case Stop:
|
||||||
velocity.Data.X = 0
|
velocity.Data.X = 0
|
||||||
velocity.Data.Y = 0
|
velocity.Data.Y = 0
|
||||||
|
|||||||
@ -7,3 +7,5 @@ const (
|
|||||||
South
|
South
|
||||||
North
|
North
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const PLAYERSPEED int = 4
|
||||||
|
|||||||
@ -13,16 +13,15 @@ type Game struct {
|
|||||||
World *ecs.World
|
World *ecs.World
|
||||||
Bounds image.Rectangle
|
Bounds image.Rectangle
|
||||||
ScreenWidth, ScreenHeight int
|
ScreenWidth, ScreenHeight int
|
||||||
CurrentLevel int
|
|
||||||
Scenes map[int]Scene
|
Scenes map[int]Scene
|
||||||
|
Observer *observers.GameObserver
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGame(width, height, startlevel int, startscene int) *Game {
|
func NewGame(width, height, cellsize, startlevel int, startscene int) *Game {
|
||||||
world := ecs.NewWorld()
|
world := ecs.NewWorld()
|
||||||
|
|
||||||
game := &Game{
|
game := &Game{
|
||||||
Bounds: image.Rectangle{},
|
Bounds: image.Rectangle{},
|
||||||
CurrentLevel: startlevel,
|
|
||||||
World: &world,
|
World: &world,
|
||||||
ScreenWidth: width,
|
ScreenWidth: width,
|
||||||
ScreenHeight: height,
|
ScreenHeight: height,
|
||||||
@ -31,6 +30,7 @@ func NewGame(width, height, startlevel int, startscene int) *Game {
|
|||||||
|
|
||||||
observers.NewPlayerObserver(&world)
|
observers.NewPlayerObserver(&world)
|
||||||
observers.NewParticleObserver(&world)
|
observers.NewParticleObserver(&world)
|
||||||
|
game.Observer = observers.NewGameObserver(&world, startlevel, width, height, cellsize)
|
||||||
|
|
||||||
game.Scenes[Play] = NewLevelScene(game, startlevel)
|
game.Scenes[Play] = NewLevelScene(game, startlevel)
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
"openquell/grid"
|
"openquell/grid"
|
||||||
|
"openquell/observers"
|
||||||
"openquell/systems"
|
"openquell/systems"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -71,6 +72,10 @@ func (level *Level) SetupGrid(game *Game) {
|
|||||||
selector := ecs.All(posID)
|
selector := ecs.All(posID)
|
||||||
level.World.Batch().RemoveEntities(selector)
|
level.World.Batch().RemoveEntities(selector)
|
||||||
|
|
||||||
|
// get rid of any players on PlayerObserver. FIXME: remove them in grid.NewGrid()?
|
||||||
|
playerobserver := observers.GetPlayerObserver(level.World)
|
||||||
|
playerobserver.RemoveEntities()
|
||||||
|
|
||||||
// setup world
|
// setup world
|
||||||
level.GridSystem.SetGrid(grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice))
|
level.GridSystem.SetGrid(grid.NewGrid(game.World, level.Cellsize, level.Width, level.Height, level.Mapslice))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LevelScene struct {
|
type LevelScene struct {
|
||||||
|
Game *Game
|
||||||
CurrentLevel int
|
CurrentLevel int
|
||||||
Levels []*Level
|
Levels []*Level
|
||||||
Next int
|
Next int
|
||||||
@ -16,10 +18,10 @@ type LevelScene struct {
|
|||||||
|
|
||||||
// Implements the actual playing Scene
|
// Implements the actual playing Scene
|
||||||
func NewLevelScene(game *Game, startlevel int) Scene {
|
func NewLevelScene(game *Game, startlevel int) Scene {
|
||||||
scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play}
|
scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play, Game: game}
|
||||||
|
|
||||||
scene.GenerateLevels(game)
|
scene.GenerateLevels(game)
|
||||||
scene.Levels[game.CurrentLevel].SetupGrid(game)
|
scene.Levels[scene.CurrentLevel].SetupGrid(game)
|
||||||
|
|
||||||
return scene
|
return scene
|
||||||
}
|
}
|
||||||
@ -40,6 +42,12 @@ func (scene *LevelScene) SetNext() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) Update() error {
|
func (scene *LevelScene) Update() error {
|
||||||
|
if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
|
||||||
|
fmt.Printf("current: %d, next: %d\n", scene.CurrentLevel, scene.Game.Observer.CurrentLevel)
|
||||||
|
scene.CurrentLevel = scene.Game.Observer.CurrentLevel
|
||||||
|
scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
|
||||||
|
}
|
||||||
|
|
||||||
scene.Levels[scene.CurrentLevel].Update()
|
scene.Levels[scene.CurrentLevel].Update()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/components"
|
"openquell/components"
|
||||||
|
"openquell/config"
|
||||||
"openquell/observers"
|
"openquell/observers"
|
||||||
|
|
||||||
"github.com/mlange-42/arche/ecs"
|
"github.com/mlange-42/arche/ecs"
|
||||||
@ -27,10 +28,11 @@ func NewGrid(world *ecs.World,
|
|||||||
|
|
||||||
// we use this to turn our tiles into iterable entities, used for
|
// we use this to turn our tiles into iterable entities, used for
|
||||||
// collision detection, transformation and other things
|
// collision detection, transformation and other things
|
||||||
playermapper := generic.NewMap4[
|
playermapper := generic.NewMap5[
|
||||||
components.Position,
|
components.Position,
|
||||||
components.Velocity,
|
components.Velocity,
|
||||||
components.Renderable,
|
components.Renderable,
|
||||||
|
components.Speed,
|
||||||
components.Player](world)
|
components.Player](world)
|
||||||
|
|
||||||
solidmapper := generic.NewMap4[
|
solidmapper := generic.NewMap4[
|
||||||
@ -48,6 +50,7 @@ func NewGrid(world *ecs.World,
|
|||||||
|
|
||||||
var pos *components.Position
|
var pos *components.Position
|
||||||
var render *components.Renderable
|
var render *components.Renderable
|
||||||
|
var speed *components.Speed
|
||||||
|
|
||||||
playerobserver := observers.GetPlayerObserver(world)
|
playerobserver := observers.GetPlayerObserver(world)
|
||||||
|
|
||||||
@ -60,9 +63,9 @@ func NewGrid(world *ecs.World,
|
|||||||
pos, render, _, _ = solidmapper.Get(entity)
|
pos, render, _, _ = solidmapper.Get(entity)
|
||||||
case tile.Player:
|
case tile.Player:
|
||||||
entity := playermapper.New()
|
entity := playermapper.New()
|
||||||
pos, _, render, _ = playermapper.Get(entity)
|
pos, _, render, speed, _ = playermapper.Get(entity)
|
||||||
playerobserver.AddEntity(entity)
|
playerobserver.AddEntity(entity)
|
||||||
|
speed.Value = config.PLAYERSPEED
|
||||||
fmt.Printf("player start pos: %d,%d\n", point.X*tilesize, point.Y*tilesize)
|
fmt.Printf("player start pos: %d,%d\n", point.X*tilesize, point.Y*tilesize)
|
||||||
case tile.Collectible:
|
case tile.Collectible:
|
||||||
entity := colmapper.New()
|
entity := colmapper.New()
|
||||||
|
|||||||
7
main.go
7
main.go
@ -8,15 +8,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
width int = 640
|
width int = 640
|
||||||
height int = 480
|
height int = 480
|
||||||
|
cellsize int = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ebiten.SetWindowSize(width, height)
|
ebiten.SetWindowSize(width, height)
|
||||||
ebiten.SetWindowTitle("openquell")
|
ebiten.SetWindowTitle("openquell")
|
||||||
|
|
||||||
g := game.NewGame(width, height, 0, game.Play)
|
g := game.NewGame(width, height, cellsize, 0, game.Play)
|
||||||
|
|
||||||
err := ebiten.RunGame(g)
|
err := ebiten.RunGame(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
31
observers/game_observer.go
Normal file
31
observers/game_observer.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package observers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mlange-42/arche/ecs"
|
||||||
|
"github.com/mlange-42/arche/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Used for global game state
|
||||||
|
type GameObserver struct {
|
||||||
|
CurrentLevel, Width, Height, Cellsize, Score int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGameObserver(world *ecs.World, startlevel, width, height, cellsize int) *GameObserver {
|
||||||
|
observer := &GameObserver{
|
||||||
|
CurrentLevel: startlevel,
|
||||||
|
Width: width,
|
||||||
|
Height: height,
|
||||||
|
Cellsize: cellsize,
|
||||||
|
}
|
||||||
|
|
||||||
|
resmanger := generic.NewResource[GameObserver](world)
|
||||||
|
resmanger.Add(observer)
|
||||||
|
|
||||||
|
return observer
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetGameObserver(world *ecs.World) *GameObserver {
|
||||||
|
observerID := ecs.ResourceID[GameObserver](world)
|
||||||
|
observer := world.Resources().Get(observerID).(*GameObserver)
|
||||||
|
return observer
|
||||||
|
}
|
||||||
@ -50,3 +50,7 @@ func (observer *PlayerObserver) AddEntity(entity ecs.Entity) {
|
|||||||
func (observer *PlayerObserver) RemoveEntity(entity ecs.Entity) {
|
func (observer *PlayerObserver) RemoveEntity(entity ecs.Entity) {
|
||||||
delete(observer.Entities, entity)
|
delete(observer.Entities, entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (observer *PlayerObserver) RemoveEntities() {
|
||||||
|
observer.Entities = make(map[ecs.Entity]int)
|
||||||
|
}
|
||||||
|
|||||||
@ -35,6 +35,12 @@ func (system *CollectibleSystem) Update() {
|
|||||||
EntitiesToRemove := []ecs.Entity{}
|
EntitiesToRemove := []ecs.Entity{}
|
||||||
|
|
||||||
query := system.Selector.Query(system.World)
|
query := system.Selector.Query(system.World)
|
||||||
|
numcollectibles := query.Count()
|
||||||
|
|
||||||
|
if numcollectibles == 0 {
|
||||||
|
query.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for query.Next() {
|
for query.Next() {
|
||||||
colposition, collectible, _ := query.Get()
|
colposition, collectible, _ := query.Get()
|
||||||
@ -58,6 +64,14 @@ func (system *CollectibleSystem) Update() {
|
|||||||
|
|
||||||
for _, entity := range EntitiesToRemove {
|
for _, entity := range EntitiesToRemove {
|
||||||
system.World.RemoveEntity(entity)
|
system.World.RemoveEntity(entity)
|
||||||
|
numcollectibles--
|
||||||
|
}
|
||||||
|
|
||||||
|
if numcollectibles == 0 {
|
||||||
|
// winner, winner, chicken dinner!
|
||||||
|
game := observers.GetGameObserver(system.World)
|
||||||
|
game.Score++
|
||||||
|
game.CurrentLevel++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import (
|
|||||||
. "openquell/config"
|
. "openquell/config"
|
||||||
"openquell/grid"
|
"openquell/grid"
|
||||||
|
|
||||||
"github.com/alecthomas/repr"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/mlange-42/arche/ecs"
|
"github.com/mlange-42/arche/ecs"
|
||||||
"github.com/mlange-42/arche/generic"
|
"github.com/mlange-42/arche/generic"
|
||||||
@ -119,7 +118,6 @@ func (system *GridSystem) GetSolidNeighborPosition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
newpos := components.NewPosition(neighborpos, system.Tilesize)
|
newpos := components.NewPosition(neighborpos, system.Tilesize)
|
||||||
repr.Println(newpos)
|
|
||||||
|
|
||||||
if !edge && system.Grid.Map[neighborpos].Solid {
|
if !edge && system.Grid.Map[neighborpos].Solid {
|
||||||
return true, newpos
|
return true, newpos
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
type PlayerSystem struct {
|
type PlayerSystem struct {
|
||||||
World *ecs.World
|
World *ecs.World
|
||||||
Selector *generic.Filter4[Position, Velocity, Player, Renderable]
|
Selector *generic.Filter5[Position, Velocity, Player, Renderable, Speed]
|
||||||
Particle *ParticleSystem
|
Particle *ParticleSystem
|
||||||
Collectible *CollectibleSystem
|
Collectible *CollectibleSystem
|
||||||
Grid *GridSystem
|
Grid *GridSystem
|
||||||
@ -20,7 +20,7 @@ type PlayerSystem struct {
|
|||||||
|
|
||||||
func NewPlayerSystem(world *ecs.World, grid *GridSystem) *PlayerSystem {
|
func NewPlayerSystem(world *ecs.World, grid *GridSystem) *PlayerSystem {
|
||||||
system := &PlayerSystem{
|
system := &PlayerSystem{
|
||||||
Selector: generic.NewFilter4[Position, Velocity, Player, Renderable](),
|
Selector: generic.NewFilter5[Position, Velocity, Player, Renderable, Speed](),
|
||||||
Particle: NewParticleSystem(world, grid.Tilesize),
|
Particle: NewParticleSystem(world, grid.Tilesize),
|
||||||
Collectible: NewCollectibleSystem(world),
|
Collectible: NewCollectibleSystem(world),
|
||||||
Grid: grid,
|
Grid: grid,
|
||||||
@ -34,7 +34,7 @@ func (system PlayerSystem) Update() error {
|
|||||||
query := system.Selector.Query(system.World)
|
query := system.Selector.Query(system.World)
|
||||||
|
|
||||||
for query.Next() {
|
for query.Next() {
|
||||||
playerposition, velocity, _, _ := query.Get()
|
playerposition, velocity, _, _, speed := query.Get()
|
||||||
|
|
||||||
if !velocity.Moving() {
|
if !velocity.Moving() {
|
||||||
switch {
|
switch {
|
||||||
@ -72,7 +72,7 @@ func (system PlayerSystem) Update() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playerposition.Move(velocity)
|
playerposition.Move(velocity, speed)
|
||||||
}
|
}
|
||||||
|
|
||||||
system.Particle.Update()
|
system.Particle.Update()
|
||||||
@ -87,7 +87,7 @@ func (system *PlayerSystem) Draw(screen *ebiten.Image) {
|
|||||||
query := system.Selector.Query(system.World)
|
query := system.Selector.Query(system.World)
|
||||||
|
|
||||||
for query.Next() {
|
for query.Next() {
|
||||||
pos, _, _, sprite := query.Get()
|
pos, _, _, sprite, _ := query.Get()
|
||||||
|
|
||||||
op.GeoM.Reset()
|
op.GeoM.Reset()
|
||||||
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user