Example #1
0
        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);
        }
Example #2
0
        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;
            }