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

Revision 6616, 11.1 KB checked in by empaheik, 5 years ago (diff)

Tekstiesineiden näyttökalanruoto, odottaa evolvoitumista.

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