Merge pull request 'separate-collision-checker' (#1) from separate-collision-checker into master
Reviewed-on: #1
This commit is contained in:
commit
d055c9e913
8
TODO.md
8
TODO.md
@ -24,15 +24,7 @@
|
|||||||
|
|
||||||
- Turn menu button in hud_system (events in level_scene!) into ebitenui button
|
- Turn menu button in hud_system (events in level_scene!) into ebitenui button
|
||||||
|
|
||||||
- On level loose, do not offer "next level"
|
|
||||||
|
|
||||||
- Moving obstacles don't kill the player when they hit him, they just stop there.
|
|
||||||
|
|
||||||
- use grid/collider.CheckGridCollision() for players AND
|
|
||||||
obstacles. Currenty if I use it with obstacles, the don't move
|
|
||||||
anymore when a player bumps into it, for whatever strange reasons.
|
|
||||||
Maybe add a func argument to it so that the function can respond to
|
|
||||||
the event as the entity wishes.
|
|
||||||
|
|
||||||
## Collider Rework [abandoned: see branch collider-system, fails]
|
## Collider Rework [abandoned: see branch collider-system, fails]
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
"iid": "267e9380-d7b0-11ee-a97e-35bec9c19d52",
|
"iid": "267e9380-d7b0-11ee-a97e-35bec9c19d52",
|
||||||
"jsonVersion": "1.5.3",
|
"jsonVersion": "1.5.3",
|
||||||
"appBuildId": 473703,
|
"appBuildId": 473703,
|
||||||
"nextUid": 31,
|
"nextUid": 33,
|
||||||
"identifierStyle": "Capitalize",
|
"identifierStyle": "Capitalize",
|
||||||
"toc": [],
|
"toc": [],
|
||||||
"worldLayout": "Free",
|
"worldLayout": "Free",
|
||||||
@ -3502,6 +3502,121 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"__neighbours": []
|
"__neighbours": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identifier": "Level_13",
|
||||||
|
"iid": "df3a04b0-d7b0-11ee-b56f-5371345878c2",
|
||||||
|
"uid": 32,
|
||||||
|
"worldX": 480,
|
||||||
|
"worldY": 1632,
|
||||||
|
"worldDepth": 0,
|
||||||
|
"pxWid": 640,
|
||||||
|
"pxHei": 480,
|
||||||
|
"__bgColor": "#696A79",
|
||||||
|
"bgColor": null,
|
||||||
|
"useAutoIdentifier": true,
|
||||||
|
"bgRelPath": "../sprites/background-lila.png",
|
||||||
|
"bgPos": "Cover",
|
||||||
|
"bgPivotX": 0.5,
|
||||||
|
"bgPivotY": 0.5,
|
||||||
|
"__smartColor": "#ADADB5",
|
||||||
|
"__bgPos": { "topLeftPx": [0,0], "scale": [1,1], "cropRect": [0,0,640,480] },
|
||||||
|
"externalRelPath": null,
|
||||||
|
"fieldInstances": [
|
||||||
|
{ "__identifier": "level", "__type": "Int", "__value": 13, "__tile": null, "defUid": 11, "realEditorValues": [{ "id": "V_Int", "params": [13] }] },
|
||||||
|
{ "__identifier": "description", "__type": "String", "__value": "test", "__tile": null, "defUid": 12, "realEditorValues": [{
|
||||||
|
"id": "V_String",
|
||||||
|
"params": ["test"]
|
||||||
|
}] },
|
||||||
|
{ "__identifier": "background", "__type": "String", "__value": "background-lila", "__tile": null, "defUid": 13, "realEditorValues": [] },
|
||||||
|
{ "__identifier": "minmoves", "__type": "Int", "__value": 7, "__tile": null, "defUid": 14, "realEditorValues": [] }
|
||||||
|
],
|
||||||
|
"layerInstances": [
|
||||||
|
{
|
||||||
|
"__identifier": "Entities",
|
||||||
|
"__type": "Entities",
|
||||||
|
"__cWid": 20,
|
||||||
|
"__cHei": 15,
|
||||||
|
"__gridSize": 32,
|
||||||
|
"__opacity": 1,
|
||||||
|
"__pxTotalOffsetX": 0,
|
||||||
|
"__pxTotalOffsetY": 0,
|
||||||
|
"__tilesetDefUid": null,
|
||||||
|
"__tilesetRelPath": null,
|
||||||
|
"iid": "df3a04b1-d7b0-11ee-b56f-31d2a4bd4c5c",
|
||||||
|
"levelId": 32,
|
||||||
|
"layerDefUid": 5,
|
||||||
|
"pxOffsetX": 0,
|
||||||
|
"pxOffsetY": 0,
|
||||||
|
"visible": true,
|
||||||
|
"optionalRules": [],
|
||||||
|
"intGridCsv": [],
|
||||||
|
"autoLayerTiles": [],
|
||||||
|
"seed": 1934321,
|
||||||
|
"overrideTilesetUid": null,
|
||||||
|
"gridTiles": [],
|
||||||
|
"entityInstances": [
|
||||||
|
{
|
||||||
|
"__identifier": "PlayerPrimary",
|
||||||
|
"__grid": [9,7],
|
||||||
|
"__pivot": [0,0],
|
||||||
|
"__tags": [],
|
||||||
|
"__tile": { "tilesetUid": 1, "x": 32, "y": 96, "w": 32, "h": 32 },
|
||||||
|
"__smartColor": "#2F3BBE",
|
||||||
|
"iid": "f00cf6d0-d7b0-11ee-b56f-4d0f006a98b4",
|
||||||
|
"width": 32,
|
||||||
|
"height": 32,
|
||||||
|
"defUid": 3,
|
||||||
|
"px": [288,224],
|
||||||
|
"fieldInstances": [],
|
||||||
|
"__worldX": 768,
|
||||||
|
"__worldY": 1856
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__identifier": "ObstacleEast",
|
||||||
|
"__grid": [12,7],
|
||||||
|
"__pivot": [0,0],
|
||||||
|
"__tags": [],
|
||||||
|
"__tile": { "tilesetUid": 1, "x": 64, "y": 32, "w": 32, "h": 32 },
|
||||||
|
"__smartColor": "#D77643",
|
||||||
|
"iid": "f5429510-d7b0-11ee-b56f-4d263bc512ec",
|
||||||
|
"width": 32,
|
||||||
|
"height": 32,
|
||||||
|
"defUid": 8,
|
||||||
|
"px": [384,224],
|
||||||
|
"fieldInstances": [],
|
||||||
|
"__worldX": 864,
|
||||||
|
"__worldY": 1856
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__identifier": "Tiles",
|
||||||
|
"__type": "Tiles",
|
||||||
|
"__cWid": 20,
|
||||||
|
"__cHei": 15,
|
||||||
|
"__gridSize": 32,
|
||||||
|
"__opacity": 1,
|
||||||
|
"__pxTotalOffsetX": 0,
|
||||||
|
"__pxTotalOffsetY": 0,
|
||||||
|
"__tilesetDefUid": 1,
|
||||||
|
"__tilesetRelPath": "../sprites/map.png",
|
||||||
|
"iid": "df3a04b2-d7b0-11ee-b56f-99f67bd5211d",
|
||||||
|
"levelId": 32,
|
||||||
|
"layerDefUid": 2,
|
||||||
|
"pxOffsetX": 0,
|
||||||
|
"pxOffsetY": 0,
|
||||||
|
"visible": true,
|
||||||
|
"optionalRules": [],
|
||||||
|
"intGridCsv": [],
|
||||||
|
"autoLayerTiles": [],
|
||||||
|
"seed": 2843103,
|
||||||
|
"overrideTilesetUid": null,
|
||||||
|
"gridTiles": [{ "px": [352,320], "src": [64,0], "f": 0, "t": 2, "d": [211], "a": 1 }],
|
||||||
|
"entityInstances": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"__neighbours": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"worlds": [],
|
"worlds": [],
|
||||||
|
|||||||
@ -61,6 +61,8 @@ func (velocity *Velocity) InvertDirection() int {
|
|||||||
return South
|
return South
|
||||||
case All:
|
case All:
|
||||||
return Stop
|
return Stop
|
||||||
|
case Stop:
|
||||||
|
return Stop
|
||||||
}
|
}
|
||||||
|
|
||||||
// should not happen
|
// should not happen
|
||||||
|
|||||||
@ -16,7 +16,7 @@ const (
|
|||||||
const PLAYERSPEED int = 5
|
const PLAYERSPEED int = 5
|
||||||
const PARTICLE_LOOPWAIT time.Duration = 250 * time.Millisecond
|
const PARTICLE_LOOPWAIT time.Duration = 250 * time.Millisecond
|
||||||
const LEVEL_END_WAIT time.Duration = 500 * time.Millisecond
|
const LEVEL_END_WAIT time.Duration = 500 * time.Millisecond
|
||||||
const version string = "1.1.0"
|
const version string = "1.2.0"
|
||||||
|
|
||||||
const MenuRectX int = 600
|
const MenuRectX int = 600
|
||||||
const MenuRectY int = 0
|
const MenuRectY int = 0
|
||||||
|
|||||||
@ -18,7 +18,7 @@ type Game struct {
|
|||||||
Scenes map[SceneName]Scene
|
Scenes map[SceneName]Scene
|
||||||
CurrentScene SceneName
|
CurrentScene SceneName
|
||||||
Observer *observers.GameObserver
|
Observer *observers.GameObserver
|
||||||
Levels []*Level // fed in LevelScene.GenerateLevels()
|
Levels []*Level // fed in PlayScene.GenerateLevels()
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ func NewGame(width, height, cellsize int, cfg *config.Config, startscene SceneNa
|
|||||||
game.Scenes[Menu] = NewMenuScene(game)
|
game.Scenes[Menu] = NewMenuScene(game)
|
||||||
game.Scenes[About] = NewAboutScene(game)
|
game.Scenes[About] = NewAboutScene(game)
|
||||||
game.Scenes[Popup] = NewPopupScene(game)
|
game.Scenes[Popup] = NewPopupScene(game)
|
||||||
game.Scenes[Play] = NewLevelScene(game, cfg.Startlevel)
|
game.Scenes[Play] = NewPlayScene(game, cfg.Startlevel)
|
||||||
game.Scenes[Select] = NewSelectScene(game)
|
game.Scenes[Select] = NewSelectScene(game)
|
||||||
|
|
||||||
game.CurrentScene = startscene
|
game.CurrentScene = startscene
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LevelScene struct {
|
type PlayScene struct {
|
||||||
Game *Game
|
Game *Game
|
||||||
CurrentLevel int
|
CurrentLevel int
|
||||||
Levels []*Level
|
Levels []*Level
|
||||||
@ -21,8 +21,8 @@ type LevelScene struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implements the actual playing Scene
|
// Implements the actual playing Scene
|
||||||
func NewLevelScene(game *Game, startlevel int) Scene {
|
func NewPlayScene(game *Game, startlevel int) Scene {
|
||||||
scene := &LevelScene{Whoami: Play, Next: Play, Game: game}
|
scene := &PlayScene{Whoami: Play, Next: Play, Game: game}
|
||||||
|
|
||||||
scene.GenerateLevels(game)
|
scene.GenerateLevels(game)
|
||||||
scene.SetLevel(startlevel)
|
scene.SetLevel(startlevel)
|
||||||
@ -33,7 +33,7 @@ func NewLevelScene(game *Game, startlevel int) Scene {
|
|||||||
return scene
|
return scene
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) GenerateLevels(game *Game) {
|
func (scene *PlayScene) GenerateLevels(game *Game) {
|
||||||
min := []int{}
|
min := []int{}
|
||||||
for _, level := range assets.Project.Levels {
|
for _, level := range assets.Project.Levels {
|
||||||
level := level
|
level := level
|
||||||
@ -46,30 +46,30 @@ func (scene *LevelScene) GenerateLevels(game *Game) {
|
|||||||
scene.Game.Levels = scene.Levels
|
scene.Game.Levels = scene.Levels
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) SetLevel(level int) {
|
func (scene *PlayScene) SetLevel(level int) {
|
||||||
scene.CurrentLevel = level
|
scene.CurrentLevel = level
|
||||||
scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
|
scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface methods
|
// Interface methods
|
||||||
func (scene *LevelScene) SetNext(next SceneName) {
|
func (scene *PlayScene) SetNext(next SceneName) {
|
||||||
scene.Next = next
|
scene.Next = next
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) GetNext() SceneName {
|
func (scene *PlayScene) GetNext() SceneName {
|
||||||
// FIXME: set to winner or options screen
|
// FIXME: set to winner or options screen
|
||||||
return scene.Next
|
return scene.Next
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) ResetNext() {
|
func (scene *PlayScene) ResetNext() {
|
||||||
scene.Next = scene.Whoami
|
scene.Next = scene.Whoami
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) Clearscreen() bool {
|
func (scene *PlayScene) Clearscreen() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) Update() error {
|
func (scene *PlayScene) Update() error {
|
||||||
scene.Levels[scene.CurrentLevel].Update()
|
scene.Levels[scene.CurrentLevel].Update()
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
@ -87,7 +87,7 @@ func (scene *LevelScene) Update() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scene *LevelScene) Draw(screen *ebiten.Image) {
|
func (scene *PlayScene) Draw(screen *ebiten.Image) {
|
||||||
// FIXME: why not in Update() ?!?!?!
|
// FIXME: why not in Update() ?!?!?!
|
||||||
if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
|
if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
|
||||||
slog.Debug("level", "current", scene.CurrentLevel,
|
slog.Debug("level", "current", scene.CurrentLevel,
|
||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"openquell/assets"
|
"openquell/assets"
|
||||||
"openquell/gameui"
|
"openquell/gameui"
|
||||||
|
"openquell/observers"
|
||||||
|
|
||||||
"github.com/ebitenui/ebitenui"
|
"github.com/ebitenui/ebitenui"
|
||||||
"github.com/ebitenui/ebitenui/widget"
|
"github.com/ebitenui/ebitenui/widget"
|
||||||
@ -75,6 +76,7 @@ func (scene *PopupScene) Draw(screen *ebiten.Image) {
|
|||||||
|
|
||||||
func (scene *PopupScene) SetupUI() {
|
func (scene *PopupScene) SetupUI() {
|
||||||
blue := color.RGBA{0, 255, 128, 255}
|
blue := color.RGBA{0, 255, 128, 255}
|
||||||
|
observer := observers.GetGameObserver(scene.Game.World)
|
||||||
|
|
||||||
rowContainer := gameui.NewRowContainer(false)
|
rowContainer := gameui.NewRowContainer(false)
|
||||||
|
|
||||||
@ -88,10 +90,11 @@ func (scene *PopupScene) SetupUI() {
|
|||||||
scene.SetNext(Menu)
|
scene.SetNext(Menu)
|
||||||
})
|
})
|
||||||
|
|
||||||
// buttonOptions := gameui.NewMenuButton("Options", *assets.FontRenderer.FontNormal,
|
buttonRetry := gameui.NewMenuButton("Retry", *assets.FontRenderer.FontNormal,
|
||||||
// func(args *widget.ButtonClickedEventArgs) {
|
func(args *widget.ButtonClickedEventArgs) {
|
||||||
// scene.SetNext(Settings)
|
scene.SetNext(Play)
|
||||||
// })
|
observer.Retry = true
|
||||||
|
})
|
||||||
|
|
||||||
label := widget.NewText(
|
label := widget.NewText(
|
||||||
widget.TextOpts.Text("Menu", *assets.FontRenderer.FontBig, blue),
|
widget.TextOpts.Text("Menu", *assets.FontRenderer.FontBig, blue),
|
||||||
@ -100,8 +103,8 @@ func (scene *PopupScene) SetupUI() {
|
|||||||
|
|
||||||
rowContainer.AddChild(label)
|
rowContainer.AddChild(label)
|
||||||
rowContainer.AddChild(buttonContinue)
|
rowContainer.AddChild(buttonContinue)
|
||||||
|
rowContainer.AddChild(buttonRetry)
|
||||||
rowContainer.AddChild(buttonAbort)
|
rowContainer.AddChild(buttonAbort)
|
||||||
//rowContainer.AddChild(buttonOptions)
|
|
||||||
|
|
||||||
scene.Ui = &ebitenui.UI{
|
scene.Ui = &ebitenui.UI{
|
||||||
Container: rowContainer.Container(),
|
Container: rowContainer.Container(),
|
||||||
|
|||||||
@ -5,25 +5,30 @@ import (
|
|||||||
. "openquell/config"
|
. "openquell/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FIXME: make available everywhere
|
// Check a collision on the grid. We check if the entity in question
|
||||||
|
// bumps into the egde of the grid or if it bumps onto a solid wall
|
||||||
|
// tile. For both cases the user must provide responder funcs in which
|
||||||
|
// it must be implemented how to react on those events.
|
||||||
func (grid *Grid) CheckGridCollision(
|
func (grid *Grid) CheckGridCollision(
|
||||||
playerposition *components.Position,
|
position *components.Position,
|
||||||
velocity *components.Velocity) {
|
velocity *components.Velocity,
|
||||||
|
respond_edge func(*components.Position, *components.Velocity, *components.Position),
|
||||||
|
respond_solid func(*components.Position, *components.Velocity, *components.Position),
|
||||||
|
) {
|
||||||
|
|
||||||
if velocity.Moving() {
|
if velocity.Moving() {
|
||||||
ok, newpos := grid.BumpEdge(playerposition, velocity)
|
ok, newpos := grid.BumpEdge(position, velocity)
|
||||||
if ok {
|
if ok {
|
||||||
//slog.Debug("falling off the edge", "newpos", newpos)
|
//slog.Debug("falling off the edge", "newpos", newpos)
|
||||||
playerposition.Set(newpos)
|
respond_edge(position, velocity, newpos)
|
||||||
} else {
|
} else {
|
||||||
ok, tilepos := grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
ok, tilepos := grid.GetSolidNeighborPosition(position, velocity, true)
|
||||||
if ok {
|
if ok {
|
||||||
// slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos",
|
// slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos",
|
||||||
// tilepos.Point(), "playerpos", playerposition)
|
// tilepos.Point(), "playerpos", playerposition)
|
||||||
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
intersects, newpos := tilepos.Intersects(position, velocity)
|
||||||
if intersects {
|
if intersects {
|
||||||
playerposition.Set(newpos)
|
respond_solid(position, velocity, newpos)
|
||||||
velocity.Change(Stop)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,23 @@ func NewObstacleSystem(world *ecs.World, gridcontainer *grid.GridContainer) Syst
|
|||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ObstacleBumpEdgeResponder(
|
||||||
|
pos *components.Position,
|
||||||
|
vel *components.Velocity,
|
||||||
|
newpos *components.Position) {
|
||||||
|
|
||||||
|
pos.Set(newpos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ObstacleBumpWallResponder(
|
||||||
|
pos *components.Position,
|
||||||
|
vel *components.Velocity,
|
||||||
|
newpos *components.Position) {
|
||||||
|
|
||||||
|
pos.Set(newpos)
|
||||||
|
vel.ResetDirectionAndStop()
|
||||||
|
}
|
||||||
|
|
||||||
func (system *ObstacleSystem) Update() error {
|
func (system *ObstacleSystem) Update() error {
|
||||||
observer := observers.GetGameObserver(system.World)
|
observer := observers.GetGameObserver(system.World)
|
||||||
|
|
||||||
@ -58,16 +75,15 @@ func (system *ObstacleSystem) Update() error {
|
|||||||
|
|
||||||
ok, newpos := obsposition.Intersects(playerposition, playervelocity)
|
ok, newpos := obsposition.Intersects(playerposition, playervelocity)
|
||||||
if ok {
|
if ok {
|
||||||
// slog.Debug("bumped into obstacle", "obstacle", obstacle)
|
if CheckObstacleSide(playervelocity, obsvelocity) {
|
||||||
|
|
||||||
if CheckObstacleSide(playervelocity, obsvelocity.Direction) {
|
|
||||||
// player died
|
// player died
|
||||||
EntitiesToRemove = append(EntitiesToRemove, player)
|
EntitiesToRemove = append(EntitiesToRemove, player)
|
||||||
} else {
|
} else {
|
||||||
// bumped into nonlethal obstacle side, stop the
|
// bumped into nonlethal obstacle side, stop the
|
||||||
// player, set the obstacle in motion, if possible
|
// player, set the obstacle in motion, if possible
|
||||||
//slog.Debug("bump not die", "originalpos", playerposition, "newpos", newpos, "obspos", obsposition)
|
//slog.Debug("bump not die", "playervelo", playervelocity)
|
||||||
obsvelocity.Set(playervelocity)
|
obsvelocity.Set(playervelocity)
|
||||||
|
//slog.Debug("bump not die", "obsvelo", obsvelocity)
|
||||||
playervelocity.Change(Stop)
|
playervelocity.Change(Stop)
|
||||||
playerposition.Set(newpos)
|
playerposition.Set(newpos)
|
||||||
}
|
}
|
||||||
@ -91,29 +107,12 @@ func (system *ObstacleSystem) Update() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//system.GridContainer.Grid.CheckGridCollision(obsposition, obsvelocity)
|
// check if [moving] obstacle collides with walls or edges
|
||||||
// FIXME: this is the same loop as in player_system, unite the
|
system.GridContainer.Grid.CheckGridCollision(
|
||||||
// two, just iterate over all entities with pos,vel,render, dammit
|
obsposition, obsvelocity, ObstacleBumpEdgeResponder, ObstacleBumpWallResponder)
|
||||||
|
|
||||||
if obsvelocity.Moving() {
|
if obsvelocity.Moving() {
|
||||||
ok, newpos := system.GridContainer.Grid.BumpEdge(obsposition, obsvelocity)
|
obsposition.Move(obsvelocity)
|
||||||
if ok {
|
|
||||||
//slog.Debug("falling off the edge", "newpos", newpos)
|
|
||||||
obsposition.Set(newpos)
|
|
||||||
} else {
|
|
||||||
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(obsposition, obsvelocity, true)
|
|
||||||
if ok {
|
|
||||||
intersects, newpos := tilepos.Intersects(obsposition, obsvelocity)
|
|
||||||
if intersects {
|
|
||||||
// slog.Debug("collision with foreign obstacle detected", "tile",
|
|
||||||
// tilepos, "obs", obsposition, "new", newpos)
|
|
||||||
|
|
||||||
obsposition.Set(newpos)
|
|
||||||
obsvelocity.ResetDirectionAndStop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obsposition.Move(obsvelocity)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,13 +151,14 @@ func (system *ObstacleSystem) Draw(screen *ebiten.Image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return true if obstacle weapon points into the direction the player is moving
|
// return true if obstacle weapon points into the direction the player is moving
|
||||||
func CheckObstacleSide(playervelocity *Velocity, obsdirection int) bool {
|
// OR if the weapon points towards a non-moving player
|
||||||
|
func CheckObstacleSide(playervelocity *Velocity, obsvelocity *Velocity) bool {
|
||||||
movingdirection := playervelocity.InvertDirection()
|
movingdirection := playervelocity.InvertDirection()
|
||||||
|
|
||||||
if movingdirection == Stop || movingdirection == obsdirection {
|
if movingdirection == Stop || movingdirection == obsvelocity.PointingAt {
|
||||||
slog.Debug("Damaging obstacle collision",
|
slog.Debug("Damaging obstacle collision",
|
||||||
"playerdirection", util.DirectionStr(playervelocity.Direction),
|
"playerdirection", util.DirectionStr(playervelocity.Direction),
|
||||||
"obsdirection", util.DirectionStr(obsdirection),
|
"obsdirection", util.DirectionStr(obsvelocity.PointingAt),
|
||||||
"movingdirection", util.DirectionStr(movingdirection),
|
"movingdirection", util.DirectionStr(movingdirection),
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -33,6 +33,23 @@ func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer, width,
|
|||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PlayerBumpEdgeResponder(
|
||||||
|
pos *components.Position,
|
||||||
|
vel *components.Velocity,
|
||||||
|
newpos *components.Position) {
|
||||||
|
|
||||||
|
pos.Set(newpos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlayerBumpWallResponder(
|
||||||
|
pos *components.Position,
|
||||||
|
vel *components.Velocity,
|
||||||
|
newpos *components.Position) {
|
||||||
|
|
||||||
|
pos.Set(newpos)
|
||||||
|
vel.Change(Stop)
|
||||||
|
}
|
||||||
|
|
||||||
func (system PlayerSystem) Update() error {
|
func (system PlayerSystem) Update() error {
|
||||||
var EntitiesToRemove []ecs.Entity
|
var EntitiesToRemove []ecs.Entity
|
||||||
|
|
||||||
@ -54,7 +71,8 @@ func (system PlayerSystem) Update() error {
|
|||||||
system.CheckMovement(playerposition, velocity, player)
|
system.CheckMovement(playerposition, velocity, player)
|
||||||
|
|
||||||
// check if player collides with walls or edges
|
// check if player collides with walls or edges
|
||||||
system.CheckGridCollision(playerposition, velocity)
|
system.GridContainer.Grid.CheckGridCollision(
|
||||||
|
playerposition, velocity, PlayerBumpEdgeResponder, PlayerBumpWallResponder)
|
||||||
|
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
// check if player collides with another player, fuse them if any
|
// check if player collides with another player, fuse them if any
|
||||||
@ -175,30 +193,6 @@ func (system *PlayerSystem) CheckMovement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *PlayerSystem) CheckGridCollision(
|
|
||||||
playerposition *components.Position,
|
|
||||||
velocity *components.Velocity) {
|
|
||||||
|
|
||||||
if velocity.Moving() {
|
|
||||||
ok, newpos := system.GridContainer.Grid.BumpEdge(playerposition, velocity)
|
|
||||||
if ok {
|
|
||||||
//slog.Debug("falling off the edge", "newpos", newpos)
|
|
||||||
playerposition.Set(newpos)
|
|
||||||
} else {
|
|
||||||
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
|
|
||||||
if ok {
|
|
||||||
// slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos",
|
|
||||||
// tilepos.Point(), "playerpos", playerposition)
|
|
||||||
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
|
||||||
if intersects {
|
|
||||||
playerposition.Set(newpos)
|
|
||||||
velocity.Change(Stop)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (system *PlayerSystem) CheckPlayerCollision(
|
func (system *PlayerSystem) CheckPlayerCollision(
|
||||||
position *components.Position,
|
position *components.Position,
|
||||||
velocity *components.Velocity,
|
velocity *components.Velocity,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user