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

Revision 6549, 7.9 KB checked in by sieerinn, 4 years ago (diff)

Miekan heiluttelu kirjoitettu uusiksi.

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5using Jypeli;
6using Jypeli.Assets;
7using Jypeli.Controls;
8using Jypeli.Effects;
9using Jypeli.Widgets;
10
11
12public partial class TheLegendOfGabriel : PhysicsGame
13{
14    public const int TILE_SIZE = 20;
15
16    private Player player;
17
18    private bool transition;
19    List<GameObject> oldObjects = new List<GameObject>();
20    List<Exit> exits = new List<Exit>();
21
22    #region Resources
23
24    public static Image GunImage = LoadImage("gun");
25
26    public static Image SmallSwordImage = LoadImage("smallsword");
27
28    [AssetName("walkright")]
29    internal Animation playerWalkRight;
30    [AssetName("walkright", mirror: true)]
31    internal Animation playerWalkLeft;
32    [AssetName("walkup")]
33    private Animation playerWalkUp;
34    [AssetName("walkdown")]
35    private Animation playerWalkDown;
36
37    [AssetName("swingup")]
38    private Animation playerSwingUp;
39    [AssetName("swingright")]
40    private Animation playerSwingRight;
41    [AssetName("swingright", mirror: true)]
42    private Animation playerSwingLeft;
43    [AssetName("swingdown")]
44    private Animation playerSwingDown;
45
46    #endregion
47
48    public override void Begin()
49    {
50        SmoothTextures = false;
51        LoadAnimations();
52        StartGame();
53    }
54
55    /// <summary>
56    /// Lataa automaagisesti kaikki animaatiot.
57    /// </summary>
58    private void LoadAnimations()
59    {
60        // Haetaan tämän luokan kaikki ei-julkiset attribuutit.
61        foreach (var field in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
62        {
63            // Jos attribuutille on laitettu AsseName, niin ladataan sen niminen animaatio.
64            var assetAttr = Attribute.GetCustomAttribute(field, typeof(AssetNameAttribute)) as AssetNameAttribute;
65            if (assetAttr == null) continue;
66            var anim = LoadAnimation(assetAttr.AssetName);
67            field.SetValue(this, assetAttr.Mirror ? MirrorAnimation(anim) : anim);
68        }
69    }
70
71    /// <summary>
72    /// Peilaa kaikki animaation kuvat.
73    /// </summary>
74    private static Animation MirrorAnimation(Animation anim)
75    {
76        return new Animation(anim.Select(Image.Mirror).ToArray()) { FPS = anim.FPS };
77    }
78
79    private void StartGame()
80    {
81        ClearAll();
82        CreateLevel("level1");
83        //CreatePlayer(new Vector(-Level.Width/3, Level.Bottom + TILE_SIZE * 2));
84        SetControls();
85        Camera.ZoomToLevel();
86    }
87
88    void SetControls()
89    {
90        Keyboard.Listen(Key.Left, ButtonState.Down, player.Move, null, Direction.Left);
91        Keyboard.Listen(Key.Right, ButtonState.Down, player.Move, null, Direction.Right);
92        Keyboard.Listen(Key.Up, ButtonState.Down, player.Move, null, Direction.Up);
93        Keyboard.Listen(Key.Down, ButtonState.Down, player.Move, null, Direction.Down);
94
95        Keyboard.Listen(Key.Space, ButtonState.Pressed, delegate { if (player.ActiveItem != null) player.ActiveItem.UseKeyPressed(); }, null);
96        Keyboard.Listen(Key.Space, ButtonState.Released, delegate { if (player.ActiveItem != null) player.ActiveItem.UseKeyReleased(); }, null);
97        Keyboard.Listen(Key.Space, ButtonState.Down, delegate { if (player.ActiveItem != null) player.ActiveItem.UseKeyDown(); }, null);
98
99        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, null);
100    }
101
102    ///// <summary>
103    ///// Luo pelaajan.
104    ///// </summary>
105    //void CreatePlayer(Vector position)
106    //{
107    //    player = new Creature(TILE_SIZE, TILE_SIZE);
108    //    player.MovementSpeed = 2300;
109    //    player.Position = position;
110    //    Add(player);
111
112    //    AddCollisionHandler(player, "exit", CollidesWithExit);
113    //}
114
115    void CollidesWithExit(PhysicsObject pPlayer, PhysicsObject pExit)
116    {
117        var oldExit = pExit as Exit;
118        if (oldExit == null || transition)
119            return;
120
121        transition = true;
122
123        // Otetaan vanhat objektit talteen.
124        oldObjects.Clear();
125        foreach (var obj in GetObjects(o => o != player))
126        {
127            if (obj != player)
128            {
129                oldObjects.Add(obj);
130            }
131        }
132
133        // Luodaan seuraava kenttä.
134        exits.Clear();
135        CreateLevel(oldExit.TargetLevel);
136
137        // Etsitään seuraavan kentän kohde exitti johon siirrytään.
138        var targetExit = exits.FirstOrDefault(e => e.Name == oldExit.TargetExitName);
139
140        // Jompikumpi uloskäynti ei ole kentän laidalla, sulava siirtyminen ei ole mahdollista.
141        if (GetExitDirection(targetExit) == Direction.None || GetExitDirection(oldExit) == Direction.None)
142        {
143            transition = false;
144            oldObjects.ForEach(o => o.Destroy());
145            oldObjects.Clear();
146
147            // Yritetään päätellä pelaajalle joku järkevä paikka.
148            player.Position = targetExit.Position + Direction.Inverse(targetExit.Position.Angle.MainDirection).GetVector() * TILE_SIZE * 2;
149            Camera.ZoomToLevel();
150            return;
151        }
152
153        // Pysäytetään peli siirtymän ajaksi.
154        Pause();
155        PhysicsEnabled = false;
156
157        // Lasketaan siirtymävektorit.
158        Direction dir = GetExitDirection(targetExit);
159        Vector exitDelta = targetExit.Position - oldExit.Position;
160        Vector transitionVector = Level.Size;
161        if (dir == Direction.Left || dir == Direction.Right)
162        {
163            transitionVector.X *= dir.GetVector().X;
164            transitionVector.Y = exitDelta.Y;
165        }
166        else
167        {
168            transitionVector.Y *= dir.GetVector().Y;
169            transitionVector.X = exitDelta.X;
170        }
171
172        // Siirretään vanhoja objekteja ja pelaajaa.
173        foreach (var obj in oldObjects)
174        {
175            obj.Position += transitionVector;
176        }
177        player.Position += transitionVector + Direction.Inverse(dir).GetVector() * TILE_SIZE * 4;
178
179        // Zoomataan kameraa sopivasti ja liikutetaan se vanhan kentän päälle, josta se sitten siirtyy uuden kentän päälle.
180        Camera.Position += transitionVector;
181        Vector pos = Camera.Position;
182        Camera.ZoomToLevel();
183        Camera.Position = pos;
184    }
185
186    /// <summary>
187    /// Palauttaa suunnan millä puolella kenttää uloskäynti on.
188    /// </summary>   
189    Direction GetExitDirection(Exit exit)
190    {
191        const double epsilon = 1e-3;
192        Func<double, double, bool> isSame = (x, y) => Math.Abs(y - x) < epsilon;
193
194        if (isSame(exit.Top, Level.Top))
195        {
196            return Direction.Up;
197        }
198        if (isSame(exit.Bottom, Level.Bottom))
199        {
200            return Direction.Down;
201        }
202        if (isSame(exit.Left, Level.Left))
203        {
204            return Direction.Left;
205        }
206        if (isSame(exit.Right, Level.Right))
207        {
208            return Direction.Right;
209        }
210        return Direction.None;
211    }
212
213    protected override void PausedUpdate(Time gameTime)
214    {
215        base.PausedUpdate(gameTime);
216        double dt = gameTime.SinceLastUpdate.TotalSeconds;
217
218        const double transitionSpeed = 500.0;
219
220        if (transition)
221        {
222            Camera.Position += Camera.Position.Normalize() * -transitionSpeed * dt;
223
224            // Siirtymä on ohi, jatketaan peliä ja poistetaan edellinen kenttä.
225            if (Camera.Position.Magnitude < transitionSpeed * dt)
226            {
227                transition = false;
228                Pause();
229                PhysicsEnabled = true;
230                Camera.Position = Vector.Zero;
231
232                foreach (var obj in oldObjects)
233                {
234                    obj.Destroy();
235                }
236                oldObjects.Clear();
237            }
238        }
239    }
240
241    protected override void Update(Time time)
242    {
243        player.UpdateCreature(time);
244        base.Update(time);
245    }
246}
Note: See TracBrowser for help on using the repository browser.