source: 2015/27/ohjaajat/TheLegendOfGabriel/TheLegendOfGabriel/TheLegendOfGabriel/TheLegendOfGabriel.cs @ 6539

Revision 6539, 6.1 KB checked in by sieerinn, 4 years ago (diff)

Kenttäsiirtymä on melko valmis.

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using Jypeli;
5using Jypeli.Assets;
6using Jypeli.Controls;
7using Jypeli.Effects;
8using Jypeli.Widgets;
9using Microsoft.Xna.Framework;
10using Physics2DDotNet;
11using Color = Jypeli.Color;
12
13sealed class Exit : PhysicsObject
14{
15    /// <summary>
16    /// Kentän nimi johon siirrytään.
17    /// </summary>
18    public string TargetLevel { get; set; }
19
20    /// <summary>
21    /// Kohdekentässä olevan exitin nimi jonka päältä aloitetaan.
22    /// </summary>
23    public string TargetExitName { get; set; }
24
25    /// <summary>
26    /// Tämän uloskäynnin nimi.
27    /// </summary>
28    public string Name { get; set; }
29
30    public Exit(double width, double height)
31        : base(width, height)
32    {
33        Color = new Color(255, 0, 0, 60); // Debuggausta varten jotta näkee uloskäynnit.
34        IgnoresCollisionResponse = true;
35        Tag = "exit";
36    }
37}
38
39class Creature : PhysicsObject
40{
41    public double MovementSpeed { get; set; }
42
43    public Creature(double width, double height)
44        : base(width, height)
45    {
46        LinearDamping = 0.5;
47    }
48
49    public void Move(Direction direction)
50    {
51        if (!Game.IsPaused)
52            Push(direction.GetVector() * MovementSpeed);
53    }
54}
55
56public partial class TheLegendOfGabriel : PhysicsGame
57{
58    public const int TILE_SIZE = 20;
59
60    private Creature player;
61
62    private bool transition = false;
63    List<GameObject> oldObjects = new List<GameObject>();
64    List<Exit> exits = new List<Exit>();
65
66    public override void Begin()
67    {
68        SmoothTextures = false;
69        StartGame();
70    }
71
72    private void StartGame()
73    {
74        ClearAll();
75        CreateLevel("testlevel");
76        CreatePlayer(new Vector(30, -30));
77        SetControls();
78        Camera.ZoomToLevel();
79    }
80
81    void SetControls()
82    {
83        Keyboard.Listen(Key.Left, ButtonState.Down, player.Move, null, Direction.Left);
84        Keyboard.Listen(Key.Right, ButtonState.Down, player.Move, null, Direction.Right);
85        Keyboard.Listen(Key.Up, ButtonState.Down, player.Move, null, Direction.Up);
86        Keyboard.Listen(Key.Down, ButtonState.Down, player.Move, null, Direction.Down);
87
88        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, null);
89    }
90
91    /// <summary>
92    /// Luo pelaajan.
93    /// </summary>
94    void CreatePlayer(Vector position)
95    {
96        player = new Creature(TILE_SIZE, TILE_SIZE);
97        player.MovementSpeed = 2300;
98        player.Position = position;
99        Add(player);
100
101        AddCollisionHandler(player, "exit", CollidesWithExit);
102    }
103
104    void CollidesWithExit(PhysicsObject pPlayer, PhysicsObject pExit)
105    {
106        var oldExit = pExit as Exit;
107        if (oldExit == null || transition)
108            return;
109
110        transition = true;
111
112        // Otetaan vanhat objektit talteen.
113        oldObjects.Clear();
114        foreach (var obj in GetObjects(o => o != player))
115        {
116            if (obj != player)
117            {
118                oldObjects.Add(obj);
119            }
120        }
121
122        // Luodaan seuraava kenttä.
123        exits.Clear();
124        CreateLevel(oldExit.TargetLevel);
125
126        // Pysäytetään peli siirtymän ajaksi.
127        Pause();
128        PhysicsEnabled = false;
129
130        // Etsitään seuraavan kentän kohde exitti johon siirrytään.
131        var targetExit = exits.FirstOrDefault(e => e.Name == oldExit.TargetExitName);
132
133        // Lasketaan siirtymävektorit.
134        Direction dir = GetExitDirection(targetExit);
135        Vector exitDelta = targetExit.Position - oldExit.Position;
136        Vector transitionVector = Level.Size;
137        if (dir == Direction.Left || dir == Direction.Right)
138        {
139            transitionVector.X *= dir.GetVector().X;
140            transitionVector.Y = exitDelta.Y;
141        }
142        else
143        {
144            transitionVector.Y *= dir.GetVector().Y;
145            transitionVector.X = exitDelta.X;
146        }
147
148        // Siirretään vanhoja objekteja ja pelaajaa.
149        foreach (var obj in oldObjects)
150        {
151            obj.Position += transitionVector;
152        }
153        player.Position += transitionVector + Direction.Inverse(dir).GetVector() * TILE_SIZE * 4;
154
155        // Zoomataan kameraa sopivasti ja liikutetaan se vanhan kentän päälle, josta se sitten siirtyy uuden kentän päälle.
156        Camera.Position += transitionVector;
157        Vector pos = Camera.Position;
158        Camera.ZoomToLevel();
159        Camera.Position = pos;
160    }
161
162    /// <summary>
163    /// Palauttaa suunnan millä puolella kenttää uloskäynti on.
164    /// </summary>   
165    Direction GetExitDirection(Exit exit)
166    {
167        const double epsilon = 1e-3;
168        Func<double, double, bool> isSame = (x, y) => Math.Abs(y - x) < epsilon;
169       
170        if (isSame(exit.Top, Level.Top))
171        {
172            return Direction.Up;
173        }
174        if (isSame(exit.Bottom, Level.Bottom))
175        {
176            return Direction.Down;
177        }
178        if (isSame(exit.Left, Level.Left))
179        {
180            return Direction.Left;
181        }
182        if (isSame(exit.Right, Level.Right))
183        {
184            return Direction.Right;
185        }
186        return Direction.None;
187    }
188
189    protected override void PausedUpdate(Time gameTime)
190    {
191        base.PausedUpdate(gameTime);
192        double dt = gameTime.SinceLastUpdate.TotalSeconds;
193
194        const double transitionSpeed = 3.0;
195
196        if (transition)
197        {
198            Camera.Position += Camera.Position * -transitionSpeed * dt;
199
200            // Siirtymä on ohi, jatketaan peliä ja poistetaan edellinen kenttä.
201            if (Camera.Position.Magnitude < 1.0)
202            {
203                transition = false;
204                Pause();
205                PhysicsEnabled = true;
206                Camera.Position = Vector.Zero;
207
208                foreach (var obj in oldObjects)
209                {
210                    obj.Destroy();
211                }
212                oldObjects.Clear();
213            }
214        }
215    }
216}
Note: See TracBrowser for help on using the repository browser.