added sphere bounce over the map borders
This commit is contained in:
parent
014209898f
commit
c9a57142e7
1
TODO.md
1
TODO.md
@ -7,3 +7,4 @@
|
||||
- use first line as background image name
|
||||
- ignore comments in lvl files
|
||||
- add whitespace-mode flag in lvl files
|
||||
- check when sphere bounces from one end to the other endlessly w/o any solids in between. this is a game lock and equals game over
|
||||
|
||||
@ -2,16 +2,16 @@ Description: find the fruit
|
||||
Background: background-orange
|
||||
|
||||
|
||||
##############
|
||||
# ############
|
||||
# #
|
||||
############ #
|
||||
# S #
|
||||
# ######## ###
|
||||
#
|
||||
############ #
|
||||
# # #
|
||||
# # ######## #
|
||||
# #
|
||||
# ############
|
||||
# # # #
|
||||
# ##### # # #
|
||||
# # #
|
||||
##############
|
||||
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ func (position *Position) Update(x, y int, size ...int) {
|
||||
position.Rect = &rect
|
||||
}
|
||||
|
||||
func NewPosition(point *image.Point, cellsize int) *Position {
|
||||
func NewPosition(point image.Point, cellsize int) *Position {
|
||||
position := &Position{}
|
||||
position.Update(point.X*cellsize, point.Y*cellsize, cellsize)
|
||||
return position
|
||||
@ -39,8 +39,8 @@ func (position *Position) GetMoved(velosity *Velocity) *Position {
|
||||
return pos
|
||||
}
|
||||
|
||||
func (position *Position) Point() *image.Point {
|
||||
return &image.Point{position.X / position.Cellsize, position.Y / position.Cellsize}
|
||||
func (position *Position) Point() image.Point {
|
||||
return image.Point{position.X / position.Cellsize, position.Y / position.Cellsize}
|
||||
}
|
||||
|
||||
func (position *Position) Left() int {
|
||||
|
||||
11
game/game.go
11
game/game.go
@ -1,6 +1,7 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
@ -12,10 +13,10 @@ type Game struct {
|
||||
Bounds image.Rectangle
|
||||
ScreenWidth, ScreenHeight int
|
||||
CurrentLevel int
|
||||
Scenes []Scene
|
||||
Scenes map[int]Scene
|
||||
}
|
||||
|
||||
func NewGame(width, height, startlevel int) *Game {
|
||||
func NewGame(width, height, startlevel int, startscene int) *Game {
|
||||
world := ecs.NewWorld()
|
||||
|
||||
game := &Game{
|
||||
@ -24,10 +25,12 @@ func NewGame(width, height, startlevel int) *Game {
|
||||
World: &world,
|
||||
ScreenWidth: width,
|
||||
ScreenHeight: height,
|
||||
Scenes: map[int]Scene{},
|
||||
}
|
||||
|
||||
levelscene := NewLevelScene(game, startlevel)
|
||||
game.Scenes = append(game.Scenes, levelscene)
|
||||
game.Scenes[Play] = NewLevelScene(game, startlevel)
|
||||
|
||||
fmt.Println(game.World.Stats().String())
|
||||
|
||||
return game
|
||||
}
|
||||
|
||||
40
game/grid.go
40
game/grid.go
@ -8,6 +8,7 @@ import (
|
||||
"openquell/components"
|
||||
. "openquell/config"
|
||||
|
||||
"github.com/alecthomas/repr"
|
||||
"github.com/mlange-42/arche/generic"
|
||||
)
|
||||
|
||||
@ -90,7 +91,6 @@ func (grid *Grid) GetSolidNeighborPosition(
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fmt.Println(position)
|
||||
// set to true, ifwe are already on the last tile in the current
|
||||
// direction, i.e. on the edge of the grid
|
||||
edge := true
|
||||
@ -120,9 +120,43 @@ func (grid *Grid) GetSolidNeighborPosition(
|
||||
}
|
||||
|
||||
newpos := components.NewPosition(neighborpos, grid.Tilesize)
|
||||
fmt.Println(newpos, edge)
|
||||
repr.Println(newpos)
|
||||
|
||||
if !edge && grid.Map[*neighborpos].Solid {
|
||||
if !edge && grid.Map[neighborpos].Solid {
|
||||
return true, newpos
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (grid *Grid) BumpEdge(
|
||||
pos *components.Position,
|
||||
velocity *components.Velocity) (bool, *components.Position) {
|
||||
|
||||
x := pos.X + velocity.Data.X
|
||||
y := pos.Y + velocity.Data.Y
|
||||
|
||||
if x < 0 || x > grid.Width-grid.Tilesize || y < 0 || y > grid.Height-grid.Tilesize {
|
||||
newpos := &components.Position{}
|
||||
X := pos.X
|
||||
Y := pos.Y
|
||||
|
||||
switch velocity.Direction {
|
||||
case East:
|
||||
X = 0
|
||||
fmt.Println("east X=0")
|
||||
case West:
|
||||
X = grid.Width - grid.Tilesize
|
||||
fmt.Println("west X=max")
|
||||
case South:
|
||||
Y = 0
|
||||
fmt.Println("south y=0")
|
||||
case North:
|
||||
Y = grid.Height - grid.Tilesize
|
||||
fmt.Println("north y=max")
|
||||
}
|
||||
|
||||
newpos.Update(X, Y, grid.Tilesize)
|
||||
return true, newpos
|
||||
}
|
||||
|
||||
|
||||
@ -25,10 +25,7 @@ type Level struct {
|
||||
}
|
||||
|
||||
func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
|
||||
//grid := NewGrid(game, cellsize, plan)
|
||||
|
||||
return &Level{
|
||||
//Grid: grid,
|
||||
Mapslice: LevelToSlice(game, plan, cellsize),
|
||||
Cellsize: cellsize,
|
||||
World: game.World,
|
||||
@ -40,19 +37,13 @@ func NewLevel(game *Game, cellsize int, plan *assets.RawLevel) *Level {
|
||||
}
|
||||
|
||||
func (level *Level) Update() {
|
||||
//playermapper := generic.NewMap3[components.Position, components.Velocity, components.Renderable](level.World)
|
||||
positionid := ecs.ComponentID[components.Position](level.World)
|
||||
velocityid := ecs.ComponentID[components.Velocity](level.World)
|
||||
playerid := ecs.ComponentID[components.Player](level.World)
|
||||
//solidid := ecs.ComponentID[components.Solid](level.World)
|
||||
//renderid := ecs.ComponentID[components.Renderable](level.World)
|
||||
|
||||
selector := filter.All(positionid, velocityid, playerid)
|
||||
query := level.World.Query(selector)
|
||||
|
||||
//tileselector := filter.All(positionid, solidid, renderid)
|
||||
//tilequery := level.World.Query(tileselector)
|
||||
|
||||
for query.Next() {
|
||||
playerposition := (*components.Position)(query.Get(positionid))
|
||||
velocity := (*components.Velocity)(query.Get(velocityid))
|
||||
@ -90,6 +81,11 @@ func (level *Level) Update() {
|
||||
*/
|
||||
|
||||
if velocity.Moving() {
|
||||
ok, newpos := level.Grid.BumpEdge(playerposition, velocity)
|
||||
if ok {
|
||||
fmt.Printf("falling off the edge, new pos: %v\n", newpos)
|
||||
playerposition.Set(newpos)
|
||||
} else {
|
||||
ok, tilepos := level.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
||||
if ok {
|
||||
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
||||
@ -104,6 +100,7 @@ func (level *Level) Update() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playerposition.Move(velocity)
|
||||
}
|
||||
|
||||
49
game/levelscene.go
Normal file
49
game/levelscene.go
Normal file
@ -0,0 +1,49 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"openquell/assets"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
type LevelScene struct {
|
||||
CurrentLevel int
|
||||
Levels []*Level
|
||||
Next int
|
||||
Whoami int
|
||||
}
|
||||
|
||||
// Implements the actual playing Scene
|
||||
func NewLevelScene(game *Game, startlevel int) Scene {
|
||||
scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play}
|
||||
|
||||
scene.GenerateLevels(game)
|
||||
scene.Levels[game.CurrentLevel].SetupGrid(game)
|
||||
|
||||
return scene
|
||||
}
|
||||
|
||||
func (scene *LevelScene) GenerateLevels(game *Game) {
|
||||
for _, level := range assets.Levels {
|
||||
scene.Levels = append(scene.Levels, NewLevel(game, 32, &level))
|
||||
}
|
||||
}
|
||||
|
||||
// Interface methods
|
||||
func (scene *LevelScene) SetNext() int {
|
||||
if scene.Whoami != scene.Next {
|
||||
return scene.Next
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (scene *LevelScene) Update() error {
|
||||
scene.Levels[scene.CurrentLevel].Update()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (scene *LevelScene) Draw(screen *ebiten.Image) {
|
||||
screen.Clear()
|
||||
scene.Levels[scene.CurrentLevel].Draw(screen)
|
||||
}
|
||||
@ -1,51 +1,24 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"openquell/assets"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
Welcome = iota
|
||||
Select
|
||||
Play
|
||||
About
|
||||
Settings
|
||||
)
|
||||
|
||||
// Wrapper for different screens to be shown, as Welcome, Options,
|
||||
// About, Select Level and of course the actual Levels.
|
||||
// Scenes are responsible for screen clearing! That way a scene is able
|
||||
// to render its content onto the running level, e.g. the options scene
|
||||
// etc.
|
||||
type Scene interface {
|
||||
SetNext() int
|
||||
Update() error
|
||||
Draw(screen *ebiten.Image)
|
||||
}
|
||||
|
||||
type LevelScene struct {
|
||||
Game *Game
|
||||
CurrentLevel int
|
||||
Levels []*Level
|
||||
}
|
||||
|
||||
// Implements the actual playing Scene
|
||||
func NewLevelScene(game *Game, startlevel int) Scene {
|
||||
scene := &LevelScene{Game: game, CurrentLevel: startlevel}
|
||||
|
||||
scene.GenerateLevels()
|
||||
scene.Levels[game.CurrentLevel].SetupGrid(game)
|
||||
fmt.Println(game.World.Stats().String())
|
||||
|
||||
return scene
|
||||
}
|
||||
|
||||
func (scene *LevelScene) GenerateLevels() {
|
||||
for _, level := range assets.Levels {
|
||||
scene.Levels = append(scene.Levels, NewLevel(scene.Game, 32, &level))
|
||||
}
|
||||
}
|
||||
|
||||
func (scene *LevelScene) Update() error {
|
||||
scene.Levels[scene.CurrentLevel].Update()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (scene *LevelScene) Draw(screen *ebiten.Image) {
|
||||
screen.Clear()
|
||||
scene.Levels[scene.CurrentLevel].Draw(screen)
|
||||
}
|
||||
|
||||
2
main.go
2
main.go
@ -16,7 +16,7 @@ func main() {
|
||||
ebiten.SetWindowSize(width, height)
|
||||
ebiten.SetWindowTitle("openquell")
|
||||
|
||||
g := game.NewGame(width, height, 0)
|
||||
g := game.NewGame(width, height, 0, game.Play)
|
||||
|
||||
err := ebiten.RunGame(g)
|
||||
if err != nil {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user