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

Revision 6617, 11.4 KB checked in by sieerinn, 4 years ago (diff)

Tähtäysanimaatiot ja inventory äheltämistä.

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    private bool viewing;
23    private double midpoint;
24    private double second;
25    GameObject frame;
26    Queue<string> messagesviewed;
27
28    #region Resources
29
30    public static Image GunImage = LoadImage("gun");
31    public static Image LetterImage = LoadImage("letter");
32    public static Image SmallSwordImage = LoadImage("smallsword");
33
34    [AssetName("walkright")]
35    internal Animation playerWalkRight;
36    [AssetName("walkright", mirror: true)]
37    internal Animation playerWalkLeft;
38    [AssetName("walkup")]
39    private Animation playerWalkUp;
40    [AssetName("walkdown")]
41    private Animation playerWalkDown;
42
43    [AssetName("swingup")]
44    private Animation playerSwingUp;
45    [AssetName("swingright")]
46    private Animation playerSwingRight;
47    [AssetName("swingright", mirror: true)]
48    private Animation playerSwingLeft;
49    [AssetName("swingdown")]
50    private Animation playerSwingDown;
51
52    [AssetName("shootup")]
53    private Animation playerShootUp;
54    [AssetName("shootright")]
55    private Animation playerShootRight;
56    [AssetName("shootright", mirror: true)]
57    private Animation playerShootLeft;
58    [AssetName("shootdown")]
59    private Animation playerShootDown;
60
61    #endregion
62
63    public override void Begin()
64    {
65        SmoothTextures = false;
66        LoadAnimations();
67        StartGame();
68        Intro();
69    }
70
71    /// <summary>
72    /// Lataa automaagisesti kaikki animaatiot.
73    /// </summary>
74    private void LoadAnimations()
75    {
76        // Haetaan tämän luokan kaikki ei-julkiset attribuutit.
77        foreach (var field in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
78        {
79            // Jos attribuutille on laitettu AsseName, niin ladataan sen niminen animaatio.
80            var assetAttr = Attribute.GetCustomAttribute(field, typeof(AssetNameAttribute)) as AssetNameAttribute;
81            if (assetAttr == null) continue;
82            var anim = LoadAnimation(assetAttr.AssetName);
83            field.SetValue(this, assetAttr.Mirror ? MirrorAnimation(anim) : anim);
84        }
85    }
86
87    void Intro()
88    {
89        ShowTextItem(LetterImage, new Queue<string>(new[] { "Dear Alexander,", 
90            "",
91            "",
92            "I have accepted a position at the Communal Assets for Justice.",
93            "Please do not consider this an act of rejection. I am simply",
94            "a victim to the scathing uncertainty of your release from service.",
95            "",
96            "I still see your face in my dreams. I believe that when",
97            "our immediate circumstances change, we'll meet again, we'll",
98            "work it out. Were you here, we'd certainly fall in love.",
99            "",
100            "And perhaps then nothing could keep us apart.",
101            "-Ana" 
102        }));
103        //Pause();
104    }
105
106    void ShowTextItem(Image image, Queue<string> messages)
107    {
108        viewing = true;
109        messagesviewed = messages;
110        Pause();
111
112        Level.AmbientLight -= 0.75;
113
114        frame = new GameObject(LetterImage);
115        frame.Image = LetterImage;
116        frame.Width = Window.Width * 0.25;
117        frame.Height = Window.Height * 0.25;
118        Add(frame);
119
120        midpoint = 26 * messages.Count() * 0.5;
121
122    }
123
124    /// <summary>
125    /// Peilaa kaikki animaation kuvat.
126    /// </summary>
127    private static Animation MirrorAnimation(Animation anim)
128    {
129        return new Animation(anim.Select(Image.Mirror).ToArray()) { FPS = anim.FPS };
130    }
131
132    private void StartGame()
133    {
134        ClearAll();
135        CreateLevel("level1");
136        //CreatePlayer(new Vector(-Level.Width/3, Level.Bottom + TILE_SIZE * 2));
137        SetControls();
138        Camera.ZoomToLevel();
139    }
140
141    void SetControls()
142    {
143        Keyboard.Listen(Key.Left, ButtonState.Down, player.Move, null, Direction.Left);
144        Keyboard.Listen(Key.Right, ButtonState.Down, player.Move, null, Direction.Right);
145        Keyboard.Listen(Key.Up, ButtonState.Down, player.Move, null, Direction.Up);
146        Keyboard.Listen(Key.Down, ButtonState.Down, player.Move, null, Direction.Down);
147
148        Keyboard.Listen(Key.Space, ButtonState.Pressed, delegate { if (player.ActiveItem != null) player.ActiveItem.UseKeyPressed(); }, null);
149        Keyboard.Listen(Key.Space, ButtonState.Released, delegate { if (player.ActiveItem != null) player.ActiveItem.UseKeyReleased(); }, null);
150        Keyboard.Listen(Key.Space, ButtonState.Down, delegate { if (player.ActiveItem != null) player.ActiveItem.UseKeyDown(); }, null);
151
152        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, null);
153    }
154
155    ///// <summary>
156    ///// Luo pelaajan.
157    ///// </summary>
158    //void CreatePlayer(Vector position)
159    //{
160    //    player = new Creature(TILE_SIZE, TILE_SIZE);
161    //    player.MovementSpeed = 2300;
162    //    player.Position = position;
163    //    Add(player);
164
165    //    AddCollisionHandler(player, "exit", CollidesWithExit);
166    //}
167
168    void CollidesWithExit(PhysicsObject pPlayer, PhysicsObject pExit)
169    {
170        var oldExit = pExit as Exit;
171        if (oldExit == null || transition)
172            return;
173
174        transition = true;
175
176        // Otetaan vanhat objektit talteen.
177        oldObjects.Clear();
178        foreach (var obj in GetObjects(o => o != player))
179        {
180            if (obj != player)
181            {
182                oldObjects.Add(obj);
183            }
184        }
185
186        // Luodaan seuraava kenttä.
187        exits.Clear();
188        CreateLevel(oldExit.TargetLevel);
189
190        // Etsitään seuraavan kentän kohde exitti johon siirrytään.
191        var targetExit = exits.FirstOrDefault(e => e.Name == oldExit.TargetExitName);
192
193        // Jompikumpi uloskäynti ei ole kentän laidalla, sulava siirtyminen ei ole mahdollista.
194        if (GetExitDirection(targetExit) == Direction.None || GetExitDirection(oldExit) == Direction.None)
195        {
196            transition = false;
197            oldObjects.ForEach(o => o.Destroy());
198            oldObjects.Clear();
199
200            // Yritetään päätellä pelaajalle joku järkevä paikka.
201            player.Position = targetExit.Position + Direction.Inverse(targetExit.Position.Angle.MainDirection).GetVector() * TILE_SIZE * 2;
202            Camera.ZoomToLevel();
203            return;
204        }
205
206        // Pysäytetään peli siirtymän ajaksi.
207        Pause();
208        PhysicsEnabled = false;
209
210        // Lasketaan siirtymävektorit.
211        Direction dir = GetExitDirection(targetExit);
212        Vector exitDelta = targetExit.Position - oldExit.Position;
213        Vector transitionVector = Level.Size;
214        if (dir == Direction.Left || dir == Direction.Right)
215        {
216            transitionVector.X *= dir.GetVector().X;
217            transitionVector.Y = exitDelta.Y;
218        }
219        else
220        {
221            transitionVector.Y *= dir.GetVector().Y;
222            transitionVector.X = exitDelta.X;
223        }
224
225        // Siirretään vanhoja objekteja ja pelaajaa.
226        foreach (var obj in oldObjects)
227        {
228            obj.Position += transitionVector;
229        }
230        player.Position += transitionVector + Direction.Inverse(dir).GetVector() * TILE_SIZE * 4;
231
232        // Zoomataan kameraa sopivasti ja liikutetaan se vanhan kentän päälle, josta se sitten siirtyy uuden kentän päälle.
233        Camera.Position += transitionVector;
234        Vector pos = Camera.Position;
235        Camera.ZoomToLevel();
236        Camera.Position = pos;
237    }
238
239    /// <summary>
240    /// Palauttaa suunnan millä puolella kenttää uloskäynti on.
241    /// </summary>   
242    Direction GetExitDirection(Exit exit)
243    {
244        const double epsilon = 1e-3;
245        Func<double, double, bool> isSame = (x, y) => Math.Abs(y - x) < epsilon;
246
247        if (isSame(exit.Top, Level.Top))
248        {
249            return Direction.Up;
250        }
251        if (isSame(exit.Bottom, Level.Bottom))
252        {
253            return Direction.Down;
254        }
255        if (isSame(exit.Left, Level.Left))
256        {
257            return Direction.Left;
258        }
259        if (isSame(exit.Right, Level.Right))
260        {
261            return Direction.Right;
262        }
263        return Direction.None;
264    }
265
266    protected override void PausedUpdate(Time gameTime)
267    {
268        base.PausedUpdate(gameTime);
269        double dt = gameTime.SinceLastUpdate.TotalSeconds;
270
271        const double transitionSpeed = 500.0;
272
273        if (transition && !viewing)
274        {
275            Camera.Position += Camera.Position.Normalize() * -transitionSpeed * dt;
276
277            // Siirtymä on ohi, jatketaan peliä ja poistetaan edellinen kenttä.
278            if (Camera.Position.Magnitude < transitionSpeed * dt)
279            {
280                transition = false;
281                Pause();
282                PhysicsEnabled = true;
283                Camera.Position = Vector.Zero;
284
285                foreach (var obj in oldObjects)
286                {
287                    obj.Destroy();
288                }
289                oldObjects.Clear();
290            }
291        }
292
293        if(viewing && !transition)  //!transition perhaps being somewhat unnecessary, but now I do feel a bit safer.
294        {
295            second += dt;
296            if(second > 1)
297            {
298                if (messagesviewed.Count < 1)   //The letter's read, we better head back.
299                {
300                    Level.AmbientLight = 1;
301                    frame.Destroy();
302                    GetObjectsWithTag("labelWaitingToDie").ForEach(g => g.Destroy());
303                    viewing = false;
304                    Pause();
305                    return;
306                }
307
308                second = 0;
309                var storyLabel = new Label(messagesviewed.Dequeue()) { TextColor = Color.White };
310                storyLabel.Y = -midpoint + storyLabel.Height * messagesviewed.Count() + 1;
311                storyLabel.Tag = "labelWaitingToDie";
312                Add(storyLabel);
313
314            }
315            //Timer textTimer = new Timer();
316            //textTimer.Interval = 1;
317            //textTimer.Timeout += delegate
318            //{
319            //    if (messages.Count < 1)
320            //    {
321            //        Keyboard.EnableAll();
322            //        Level.AmbientLight = 1;
323            //        frame.Destroy();
324            //        GetObjectsWithTag("labelWaitingToDie").ForEach(g => g.Destroy());
325            //        textTimer.Stop();
326            //        Pause();
327            //        return;
328            //    }
329
330            //    var storyLabel = new Label(messages.Dequeue()) { TextColor = Color.White };
331            //    storyLabel.Y = -midpoint + storyLabel.Height * messages.Count() + 1;
332            //    storyLabel.Tag = "labelWaitingToDie";
333            //    Add(storyLabel);
334            //};
335            //textTimer.Start();
336        }
337    }
338
339    protected override void Update(Time time)
340    {
341        player.UpdateCreature(time);
342        base.Update(time);
343    }
344}
Note: See TracBrowser for help on using the repository browser.