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

Revision 6541, 6.6 KB checked in by sieerinn, 4 years ago (diff)

Testitalo lisätty.

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