separate-collision-checker #1
							
								
								
									
										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