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 | ||||
| 
 | ||||
| - 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] | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ | ||||
| 	"iid": "267e9380-d7b0-11ee-a97e-35bec9c19d52", | ||||
| 	"jsonVersion": "1.5.3", | ||||
| 	"appBuildId": 473703, | ||||
| 	"nextUid": 31, | ||||
| 	"nextUid": 33, | ||||
| 	"identifierStyle": "Capitalize", | ||||
| 	"toc": [], | ||||
| 	"worldLayout": "Free", | ||||
| @ -3502,6 +3502,121 @@ | ||||
| 				} | ||||
| 			], | ||||
| 			"__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": [], | ||||
|  | ||||
| @ -61,6 +61,8 @@ func (velocity *Velocity) InvertDirection() int { | ||||
| 		return South | ||||
| 	case All: | ||||
| 		return Stop | ||||
| 	case Stop: | ||||
| 		return Stop | ||||
| 	} | ||||
| 
 | ||||
| 	// should not happen | ||||
|  | ||||
| @ -16,7 +16,7 @@ const ( | ||||
| const PLAYERSPEED int = 5 | ||||
| const PARTICLE_LOOPWAIT time.Duration = 250 * 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 MenuRectY int = 0 | ||||
|  | ||||
| @ -18,7 +18,7 @@ type Game struct { | ||||
| 	Scenes                              map[SceneName]Scene | ||||
| 	CurrentScene                        SceneName | ||||
| 	Observer                            *observers.GameObserver | ||||
| 	Levels                              []*Level // fed in LevelScene.GenerateLevels() | ||||
| 	Levels                              []*Level // fed in PlayScene.GenerateLevels() | ||||
| 	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[About] = NewAboutScene(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.CurrentScene = startscene | ||||
|  | ||||
| @ -10,7 +10,7 @@ import ( | ||||
| 	"github.com/hajimehoshi/ebiten/v2/inpututil" | ||||
| ) | ||||
| 
 | ||||
| type LevelScene struct { | ||||
| type PlayScene struct { | ||||
| 	Game         *Game | ||||
| 	CurrentLevel int | ||||
| 	Levels       []*Level | ||||
| @ -21,8 +21,8 @@ type LevelScene struct { | ||||
| } | ||||
| 
 | ||||
| // Implements the actual playing Scene | ||||
| func NewLevelScene(game *Game, startlevel int) Scene { | ||||
| 	scene := &LevelScene{Whoami: Play, Next: Play, Game: game} | ||||
| func NewPlayScene(game *Game, startlevel int) Scene { | ||||
| 	scene := &PlayScene{Whoami: Play, Next: Play, Game: game} | ||||
| 
 | ||||
| 	scene.GenerateLevels(game) | ||||
| 	scene.SetLevel(startlevel) | ||||
| @ -33,7 +33,7 @@ func NewLevelScene(game *Game, startlevel int) Scene { | ||||
| 	return scene | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) GenerateLevels(game *Game) { | ||||
| func (scene *PlayScene) GenerateLevels(game *Game) { | ||||
| 	min := []int{} | ||||
| 	for _, level := range assets.Project.Levels { | ||||
| 		level := level | ||||
| @ -46,30 +46,30 @@ func (scene *LevelScene) GenerateLevels(game *Game) { | ||||
| 	scene.Game.Levels = scene.Levels | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) SetLevel(level int) { | ||||
| func (scene *PlayScene) SetLevel(level int) { | ||||
| 	scene.CurrentLevel = level | ||||
| 	scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game) | ||||
| } | ||||
| 
 | ||||
| // Interface methods | ||||
| func (scene *LevelScene) SetNext(next SceneName) { | ||||
| func (scene *PlayScene) SetNext(next SceneName) { | ||||
| 	scene.Next = next | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) GetNext() SceneName { | ||||
| func (scene *PlayScene) GetNext() SceneName { | ||||
| 	// FIXME: set to winner or options screen | ||||
| 	return scene.Next | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) ResetNext() { | ||||
| func (scene *PlayScene) ResetNext() { | ||||
| 	scene.Next = scene.Whoami | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) Clearscreen() bool { | ||||
| func (scene *PlayScene) Clearscreen() bool { | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) Update() error { | ||||
| func (scene *PlayScene) Update() error { | ||||
| 	scene.Levels[scene.CurrentLevel].Update() | ||||
| 
 | ||||
| 	switch { | ||||
| @ -87,7 +87,7 @@ func (scene *LevelScene) Update() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (scene *LevelScene) Draw(screen *ebiten.Image) { | ||||
| func (scene *PlayScene) Draw(screen *ebiten.Image) { | ||||
| 	// FIXME: why not in Update() ?!?!?! | ||||
| 	if scene.CurrentLevel != scene.Game.Observer.CurrentLevel { | ||||
| 		slog.Debug("level", "current", scene.CurrentLevel, | ||||
| @ -5,6 +5,7 @@ import ( | ||||
| 	"log/slog" | ||||
| 	"openquell/assets" | ||||
| 	"openquell/gameui" | ||||
| 	"openquell/observers" | ||||
| 
 | ||||
| 	"github.com/ebitenui/ebitenui" | ||||
| 	"github.com/ebitenui/ebitenui/widget" | ||||
| @ -75,6 +76,7 @@ func (scene *PopupScene) Draw(screen *ebiten.Image) { | ||||
| 
 | ||||
| func (scene *PopupScene) SetupUI() { | ||||
| 	blue := color.RGBA{0, 255, 128, 255} | ||||
| 	observer := observers.GetGameObserver(scene.Game.World) | ||||
| 
 | ||||
| 	rowContainer := gameui.NewRowContainer(false) | ||||
| 
 | ||||
| @ -88,10 +90,11 @@ func (scene *PopupScene) SetupUI() { | ||||
| 			scene.SetNext(Menu) | ||||
| 		}) | ||||
| 
 | ||||
| 	// buttonOptions := gameui.NewMenuButton("Options", *assets.FontRenderer.FontNormal, | ||||
| 	// 	func(args *widget.ButtonClickedEventArgs) { | ||||
| 	// 		scene.SetNext(Settings) | ||||
| 	// 	}) | ||||
| 	buttonRetry := gameui.NewMenuButton("Retry", *assets.FontRenderer.FontNormal, | ||||
| 		func(args *widget.ButtonClickedEventArgs) { | ||||
| 			scene.SetNext(Play) | ||||
| 			observer.Retry = true | ||||
| 		}) | ||||
| 
 | ||||
| 	label := widget.NewText( | ||||
| 		widget.TextOpts.Text("Menu", *assets.FontRenderer.FontBig, blue), | ||||
| @ -100,8 +103,8 @@ func (scene *PopupScene) SetupUI() { | ||||
| 
 | ||||
| 	rowContainer.AddChild(label) | ||||
| 	rowContainer.AddChild(buttonContinue) | ||||
| 	rowContainer.AddChild(buttonRetry) | ||||
| 	rowContainer.AddChild(buttonAbort) | ||||
| 	//rowContainer.AddChild(buttonOptions) | ||||
| 
 | ||||
| 	scene.Ui = &ebitenui.UI{ | ||||
| 		Container: rowContainer.Container(), | ||||
|  | ||||
| @ -5,25 +5,30 @@ import ( | ||||
| 	. "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( | ||||
| 	playerposition *components.Position, | ||||
| 	velocity *components.Velocity) { | ||||
| 	position *components.Position, | ||||
| 	velocity *components.Velocity, | ||||
| 	respond_edge func(*components.Position, *components.Velocity, *components.Position), | ||||
| 	respond_solid func(*components.Position, *components.Velocity, *components.Position), | ||||
| ) { | ||||
| 
 | ||||
| 	if velocity.Moving() { | ||||
| 		ok, newpos := grid.BumpEdge(playerposition, velocity) | ||||
| 		ok, newpos := grid.BumpEdge(position, velocity) | ||||
| 		if ok { | ||||
| 			//slog.Debug("falling off the edge", "newpos", newpos) | ||||
| 			playerposition.Set(newpos) | ||||
| 			respond_edge(position, velocity, newpos) | ||||
| 		} else { | ||||
| 			ok, tilepos := grid.GetSolidNeighborPosition(playerposition, velocity, true) | ||||
| 			ok, tilepos := grid.GetSolidNeighborPosition(position, velocity, true) | ||||
| 			if ok { | ||||
| 				// slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos", | ||||
| 				// 	tilepos.Point(), "playerpos", playerposition) | ||||
| 				intersects, newpos := tilepos.Intersects(playerposition, velocity) | ||||
| 				intersects, newpos := tilepos.Intersects(position, velocity) | ||||
| 				if intersects { | ||||
| 					playerposition.Set(newpos) | ||||
| 					velocity.Change(Stop) | ||||
| 					respond_solid(position, velocity, newpos) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -30,6 +30,23 @@ func NewObstacleSystem(world *ecs.World, gridcontainer *grid.GridContainer) Syst | ||||
| 	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 { | ||||
| 	observer := observers.GetGameObserver(system.World) | ||||
| 
 | ||||
| @ -58,16 +75,15 @@ func (system *ObstacleSystem) Update() error { | ||||
| 
 | ||||
| 			ok, newpos := obsposition.Intersects(playerposition, playervelocity) | ||||
| 			if ok { | ||||
| 				// slog.Debug("bumped into obstacle", "obstacle", obstacle) | ||||
| 
 | ||||
| 				if CheckObstacleSide(playervelocity, obsvelocity.Direction) { | ||||
| 				if CheckObstacleSide(playervelocity, obsvelocity) { | ||||
| 					// player died | ||||
| 					EntitiesToRemove = append(EntitiesToRemove, player) | ||||
| 				} else { | ||||
| 					// bumped  into nonlethal obstacle side,  stop the | ||||
| 					// 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) | ||||
| 					//slog.Debug("bump not die", "obsvelo", obsvelocity) | ||||
| 					playervelocity.Change(Stop) | ||||
| 					playerposition.Set(newpos) | ||||
| 				} | ||||
| @ -91,31 +107,14 @@ func (system *ObstacleSystem) Update() error { | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//system.GridContainer.Grid.CheckGridCollision(obsposition, obsvelocity) | ||||
| 		// FIXME: this is the same loop as in player_system, unite the | ||||
| 		// two, just iterate over all entities with pos,vel,render, dammit | ||||
| 		// check if [moving] obstacle collides with walls or edges | ||||
| 		system.GridContainer.Grid.CheckGridCollision( | ||||
| 			obsposition, obsvelocity, ObstacleBumpEdgeResponder, ObstacleBumpWallResponder) | ||||
| 
 | ||||
| 		if obsvelocity.Moving() { | ||||
| 			ok, newpos := system.GridContainer.Grid.BumpEdge(obsposition, 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) | ||||
| 		} | ||||
| 	} | ||||
| 	} | ||||
| 
 | ||||
| 	for _, entity := range EntitiesToRemove { | ||||
| 		slog.Debug("remove player") | ||||
| @ -152,13 +151,14 @@ func (system *ObstacleSystem) Draw(screen *ebiten.Image) { | ||||
| } | ||||
| 
 | ||||
| // 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() | ||||
| 
 | ||||
| 	if movingdirection == Stop || movingdirection == obsdirection { | ||||
| 	if movingdirection == Stop || movingdirection == obsvelocity.PointingAt { | ||||
| 		slog.Debug("Damaging obstacle collision", | ||||
| 			"playerdirection", util.DirectionStr(playervelocity.Direction), | ||||
| 			"obsdirection", util.DirectionStr(obsdirection), | ||||
| 			"obsdirection", util.DirectionStr(obsvelocity.PointingAt), | ||||
| 			"movingdirection", util.DirectionStr(movingdirection), | ||||
| 		) | ||||
| 		return true | ||||
|  | ||||
| @ -33,6 +33,23 @@ func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer, width, | ||||
| 	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 { | ||||
| 	var EntitiesToRemove []ecs.Entity | ||||
| 
 | ||||
| @ -54,7 +71,8 @@ func (system PlayerSystem) Update() error { | ||||
| 		system.CheckMovement(playerposition, velocity, player) | ||||
| 
 | ||||
| 		// check if player collides with walls or edges | ||||
| 		system.CheckGridCollision(playerposition, velocity) | ||||
| 		system.GridContainer.Grid.CheckGridCollision( | ||||
| 			playerposition, velocity, PlayerBumpEdgeResponder, PlayerBumpWallResponder) | ||||
| 
 | ||||
| 		if count > 1 { | ||||
| 			// 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( | ||||
| 	position *components.Position, | ||||
| 	velocity *components.Velocity, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user