public void CreateDebris(DestructibleDebris debris) { if (debris.CollisionAction == DebrisCollisionAction.Disappear && debris.Pos.Z >= layers[sprLayerIndex].Depth /*&& !IsTileEmpty((int)debris.Pos.X / 32, (int)debris.Pos.Y / 32)*/) { int x = (int)debris.Pos.X / 32; int y = (int)debris.Pos.Y / 32; if (x < 0 || y < 0 || x >= levelWidth || y >= levelHeight) { return; } int idx = layers[sprLayerIndex].Layout[x + y * levelWidth].TileID; if (layers[sprLayerIndex].Layout[x + y * levelWidth].IsAnimated) { idx = animatedTiles[idx].CurrentTile.TileID; } if (tileset.IsTileFilled(idx)) { return; } if (sprLayerIndex + 1 < layers.Count && layers[sprLayerIndex + 1].SpeedX == 1f && layers[sprLayerIndex + 1].SpeedY == 1f) { idx = layers[sprLayerIndex + 1].Layout[x + y * levelWidth].TileID; if (layers[sprLayerIndex + 1].Layout[x + y * levelWidth].IsAnimated) { idx = animatedTiles[idx].CurrentTile.TileID; } if (tileset.IsTileFilled(idx)) { return; } } } debrisList.Add(debris); }
private void UpdateDebris(float timeMult) { for (int i = 0; i < debrisList.Count; i++) { ref DestructibleDebris debris = ref debrisList.Data[i]; debris.Time -= timeMult; if (debris.Scale <= 0f || debris.Alpha <= 0f) { debrisList.RemoveAtFast(i); i--; continue; } if (debris.Time <= 0f) { debris.AlphaSpeed = -MathF.Min(0.02f, debris.Alpha); } if (debris.CollisionAction != DebrisCollisionAction.None) { // Debris should collide with tilemap float nx = debris.Pos.X + debris.Speed.X * timeMult; float ny = debris.Pos.Y + debris.Speed.Y * timeMult; Hitbox hitbox = new Hitbox(nx - 1, ny - 1, nx + 1, ny + 1); if (IsTileEmpty(ref hitbox, true)) { // Nothing... } else if (debris.CollisionAction == DebrisCollisionAction.Disappear) { debris.ScaleSpeed = -0.02f; debris.AlphaSpeed = -0.006f; debris.Speed = Vector2.Zero; debris.Acceleration = Vector2.Zero; } else { // Place us to the ground only if no horizontal movement was // involved (this prevents speeds resetting if the actor // collides with a wall from the side while in the air) hitbox = new Hitbox(nx - 1, debris.Pos.Y - 1, nx + 1, debris.Pos.Y + 1); if (IsTileEmpty(ref hitbox, true)) { if (debris.Speed.Y > 0f) { debris.Speed.Y = -(0.8f /*elasticity*/ * debris.Speed.Y); //OnHitFloorHook(); } else { debris.Speed.Y = 0; //OnHitCeilingHook(); } } // If the actor didn't move all the way horizontally, // it hit a wall (or was already touching it) hitbox = new Hitbox(debris.Pos.X - 1, ny - 1, debris.Pos.X + 1, ny + 1); if (IsTileEmpty(ref hitbox, true)) { debris.Speed.X = -(0.8f /*elasticity*/ * debris.Speed.X); debris.AngleSpeed = -(0.8f /*elasticity*/ * debris.AngleSpeed); //OnHitWallHook(); } } } debris.Pos.X += debris.Speed.X * timeMult; debris.Pos.Y += debris.Speed.Y * timeMult; if (debris.Acceleration.X != 0f) { debris.Speed.X = MathF.Min(debris.Speed.X + debris.Acceleration.X * timeMult, 10f); } if (debris.Acceleration.Y != 0f) { debris.Speed.Y = MathF.Min(debris.Speed.Y + debris.Acceleration.Y * timeMult, 10f); } debris.Scale += debris.ScaleSpeed * timeMult; debris.Angle += debris.AngleSpeed * timeMult; debris.Alpha += debris.AlphaSpeed * timeMult; }