public virtual void Move(Player ply, MoveData mv, TimeSpan deltaTime) { float Dt = (float)deltaTime.TotalSeconds; var Body = ply.GetComponent <ECS.Components.PhysicsBody>().Value; // Movement properties depend on the current tile the player is standing on var Phys = TileProperties.GetByIndex(World.Map.GetTileAtWorldPosition(Body.Center)); // Apply other forces, like air friction GetWorldProperties(Body.Center, out WorldProps Props); Phys.Friction *= Props.AtmosFriction; // Predict movement this frame Body.Acceleration = (mv.Acceleration * Phys.PlayerAcceleration); Vector2 PredictedPos = Body.PredictStepPosition(Dt, Phys.Friction); //> If predicted movement collides with any world geometry // then cancel any acceleration and velocity. //> There are two separate checks for horizontal and vertical movement // so sliding across walls still works IfCollidesMultiply(Body, new Vector2(PredictedPos.X, Body.Position.Y), new Vector2(0, 1)); IfCollidesMultiply(Body, new Vector2(Body.Position.X, PredictedPos.Y), new Vector2(1, 0)); // Perform the actual step Body.Step(Dt, Phys.Friction); // EVENTUALLY: // If the player gets stuck in geometry somehow, any collision checks should // return TRUE here, which means we should rewind the player position until it's not stuck in the geometry // anymore. Ray casting from current stuck position to previous position. // Do not do this until the hypothetical bug actually shows up }
void Rebuild() { if (!IsDirty) { return; } IsDirty = false; TextureAtlas = new Texture((uint)TextureAtlasSize.X, (uint)TextureAtlasSize.Y); for (var index = 0; index < TilePropertyIndexes.Length; ++index) { var propertyIndex = TilePropertyIndexes[index]; var props = TileProperties.GetByIndex(propertyIndex); var fileName = Path.Combine("data", "tiles", props.Filename); if (File.Exists(fileName)) { SetTileTexture(new Image(fileName), propertyIndex); } } VertexArray.Clear(); for (var index = 0; index < TilePropertyIndexes.Length; ++index) { Vector2f TileUV = GetTileUV(TilePropertyIndexes[index]); var worldPosition = new Vector2f((index % Size.X) * TileSize.X, (index / Size.X) * TileSize.Y); VertexArray.Append(new Vertex() { Position = worldPosition, TexCoords = new Vector2f(TileUV.X, 0), Color = Color.White }); VertexArray.Append(new Vertex() { Position = worldPosition + new Vector2f(TileSize.X, 0), TexCoords = new Vector2f(TileUV.X + TileSize.X, TileUV.Y), Color = Color.White }); VertexArray.Append(new Vertex() { Position = worldPosition + new Vector2f(TileSize.X, TileSize.Y), TexCoords = new Vector2f(TileUV.X + TileSize.X, TileUV.Y + TileSize.Y), Color = Color.White }); VertexArray.Append(new Vertex() { Position = worldPosition + new Vector2f(0, TileSize.Y), TexCoords = new Vector2f(TileUV.X, TileUV.Y + TileSize.Y), Color = Color.White }); } }
public virtual void GetWorldProperties(Vector2 WorldPosition, out WorldProps WorldProperties) { var tilePropertiesIndex = World.Map.GetTileAtWorldPosition(WorldPosition); var tileProperties = TileProperties.GetByIndex(tilePropertiesIndex); WorldProperties = new WorldProps { // Check if tile solid // TODO: Check if any other static physics objects in the way IsSolid = IsSolid(tileProperties), // Get atmosphere friction AtmosFriction = 0.987f }; // space is at index 0 if (tilePropertiesIndex == 0) { WorldProperties.AtmosFriction = 1; } }