예제 #1
0
        public DoorSliding(int x, int y, Level level)
        {
            if (level != null)
            {
                Location = new Point2(x, y);
                Level    = level;

                Type = (DoorType)level.Map.Planes[(int)Level.Planes.Walls][y, x];

                level.Cells[y, x] = Level.Cell.Default();

                // Adjust neighboring walls to show the door excavation.

                if (!IsVertical)
                {
                    if ((x - 1) > -1 &&
                        level.Cells[y, x - 1].East != Level.Cell.NoWall)
                    {
                        level.Cells[y, x - 1].East = DoorWestEastWall;
                    }

                    if ((x + 1) < level.Map.Width &&
                        level.Cells[y, x + 1].West != Level.Cell.NoWall)
                    {
                        level.Cells[y, x + 1].West = DoorWestEastWall;
                    }
                }
                else
                {
                    if ((y + 1) < level.Map.Height &&
                        level.Cells[y + 1, x].North != Level.Cell.NoWall)
                    {
                        level.Cells[y + 1, x].North = DoorNorthSouthWall;
                    }

                    if ((y - 1) > -1 &&
                        level.Cells[y - 1, x].South != Level.Cell.NoWall)
                    {
                        level.Cells[y - 1, x].South = DoorNorthSouthWall;
                    }
                }

                // Create a static body for the cell so that
                // we can block the player from entering or exiting the cell
                // when the door is closed or moving.

                _cellShape = new CollisionShape();
                BoxShape box = new BoxShape();
                box.Extents = new Vector3(Level.CellSize * 0.5f, Level.CellSize * 0.5f, Level.CellSize * 0.5f);

                _cellShape.Shape = box;
                _cellShape.Name  = "CollisionShape";

                _cellBody = new StaticBody();
                _cellBody.CollisionLayer = (uint)Level.CollisionLayers.Static;
                _cellBody.CollisionMask  = (uint)(Level.CollisionLayers.Characters);
                _cellBody.AddChild(_cellShape);

                AddChild(_cellBody);

                // Create the actual mesh for the door and set it up for
                // this particular instance.

                BuildDoorMesh();

                _mesh                  = new MeshInstance();
                _mesh.Mesh             = _doorMesh;
                _mesh.MaterialOverride = Assets.GetTexture(_doorTexture[Type]);

                if (IsVertical)
                {
                    _mesh.Transform = Transform.Identity.Rotated(Vector3.Up, Mathf.Pi * 0.5f);
                }
                else
                {
                    _mesh.Transform = Transform.Identity.Rotated(Vector3.Up, Mathf.Pi);
                }

                // Setup a physics body for the door itself for the purposes
                // of detecting collisions with projectiles since projectiles shouldn't
                // be blocked by the cell's static body that is normally only used for
                // ensuring characters can't enter or exit the cell if the door is closed
                // or moving.

                _doorShape  = new CollisionShape();
                box         = new BoxShape();
                box.Extents = new Vector3(Level.CellSize * 0.5f, Level.CellSize * 0.5f, Mathf.Epsilon);

                _doorShape.Shape = box;
                _doorShape.Name  = "CollisionShape";

                _doorBody = new RigidBody();
                _doorBody.CollisionLayer = (uint)Level.CollisionLayers.Doors;
                _doorBody.CollisionMask  = (uint)Level.CollisionLayers.Projectiles;
                _doorBody.AddChild(_doorShape);
                _doorBody.Mode = RigidBody.ModeEnum.Static;

                _mesh.AddChild(_doorBody);

                AddChild(_mesh);

                // Add myself to the world and set my position
                // along with some default state variables.

                level.AddChild(this);

                Transform tform = this.Transform;
                tform.origin   = level.MapToWorld(x, y);
                this.Transform = tform;

                State = DoorState.Closed;

                _openCloseDuration = 0.75f;
                _canClose          = true;

                _openSound  = Assets.GetSoundClip(Assets.DigitalSoundList.DoorOpening);
                _closeSound = Assets.GetSoundClip(Assets.DigitalSoundList.DoorClosing);

                // Add a tween node for controlling the animation of the
                // door opening and closing.

                _tween = new Tween();
                _tween.Connect("tween_all_completed", this, "OnTweenCompleted");

                _mesh.AddChild(_tween);

                // Add an audio player so we can emit a sound
                // when the door opens and closes.

                _audioPlayer      = new AudioStreamPlayer3D();
                _audioPlayer.Name = "AudioPlayer";

                AddChild(_audioPlayer);

                SetProcess(true);
                SetPhysicsProcess(true);
            }
        }