source: 2014/30/MitjaK/Attack to Agora/Attack to Agora/Attack to Agora/Attack to Agora/Attack_to_Agora.cs @ 6428

Revision 6428, 20.4 KB checked in by misakana, 5 years ago (diff)
Line 
1using System;
2using System.Collections.Generic;
3using Jypeli;
4using Jypeli.Assets;
5using Jypeli.Controls;
6using Jypeli.Effects;
7using Jypeli.Widgets;
8using Microsoft.Xna.Framework.Content;
9
10public partial class Attack_to_Agora : PhysicsGame
11{
12    private Animation chuckinkavely;
13    private Animation chuckinKavelyFlipped;
14
15    /// <summary>
16    /// Vakiot kannattaa merkitä constiksi (ei voi muuttaa). Tällöin ne kirjoitetaan isolla.
17    /// </summary>
18    const double NOPEUS = 1000; // 250
19    const double HYPPYVOIMA = 1500;
20    double prevVelocityX = 0.0;
21    const double STOP_LIMIT_X = 1;
22
23    Image level1 = LoadImage("kentta1");
24    Image taistelijanvarjo = LoadImage("varjo");
25    Image taistelijaOlio = LoadImage("olio");
26    Image cCaseD = LoadImage("laatikko_opening");
27    Image cCaseF = LoadImage("caseavausruutu");
28    Image karambitInspect = LoadImage("karambitfade");
29    Image tormaavavihollinen = LoadImage("ajlauta");
30
31    Image ePalkkiTyhja = LoadImage("healthbarempty");
32    Image ePalkkiTaysi = LoadImage("healthbarfull");
33
34    Image valveAlku = LoadImage("peliaukeaa1");
35    Image ajAlku = LoadImage("peliaukeaa2");
36    private bool stSequenceSkipped = false;
37
38    Elava taistelija;
39    AssaultRifle taistelijanAse;
40    const double ASEEN_DMG = 25.0;
41    const double WEAPON_INACCURACY = 20.0;
42    bool walkBackwards = false;
43
44    const double VIHOLLISEN_TORMAYSDMG = 4.0;
45    int kenttaNro = 18;
46
47    /// <summary>
48    /// Mitä tehdään tämänhetkisessä kentässä osuttaessa triggeriin.
49    /// </summary>
50    Action TriggerAction;
51    bool tActionTriggered = false;
52
53    /// <summary>
54    /// Viimeisen pelissä olevan kentän indeksi.
55    /// </summary>
56    const int VIIMEINEN_KENTTA = 18;
57
58    #region yleiset toiminnot
59    public override void Begin()
60    {
61        LataaContent();
62        AloitusAnimaatio();
63    }
64
65    void AloitaPeli()
66    {
67        ClearAll();
68        LuoKentta();
69        AsetaOhjaimet();
70        KirkastaRuutua(0.03, 1.0);
71        ensimmainentehtava.Play();
72        Timer.SingleShot(4.0, delegate { taustamusiikki_1.Play(); });
73    }
74
75    protected override void Update(Time time)
76    {
77        if (taistelija != null && taistelijanAse != null)
78        {
79            if (!walkBackwards)
80            {
81                if (taistelija.Velocity.X < -STOP_LIMIT_X)
82                {
83                    taistelijanAse.Angle = Angle.FromDegrees(180.0);
84                    taistelija.Animation = chuckinKavelyFlipped;
85                    if (prevVelocityX > 0)
86                        taistelija.Animation.Start();
87                }
88                if (taistelija.Velocity.X > STOP_LIMIT_X)
89                {
90                    taistelijanAse.Angle = Angle.FromDegrees(0.0);
91                    taistelija.Animation = chuckinkavely;
92                    if (prevVelocityX < 0)
93                        taistelija.Animation.Start();
94                }
95                if (taistelija.Velocity.X >= -STOP_LIMIT_X && taistelija.Velocity.X <= STOP_LIMIT_X) taistelija.Animation.Stop();
96
97                prevVelocityX = taistelija.Velocity.X;
98            }
99        }
100        base.Update(time);
101    }
102
103    void FixCamera()
104    {
105        double widthReduction = 1920.0 / Window.Width;
106        double heightReduction = 1080.0 / Window.Height;
107
108        double multiplier = Math.Max(widthReduction, heightReduction);
109
110        Camera.ZoomFactor = 1 / multiplier;
111    }
112
113    /// <summary>
114    /// Pimennetään ruutua pikku hiljaa.
115    /// Oletusnopeus 0.01.
116    /// </summary>
117    public void PimennaRuutua(double nopeus)
118    {
119        Timer ajastin = new Timer();
120        ajastin.Interval = 0.1;
121        ajastin.Timeout += delegate
122        {
123            Level.AmbientLight -= nopeus;
124            if (Level.AmbientLight <= 0.0)
125            {
126                ajastin.Stop();
127                ajastin.Reset();
128            }
129        };
130        ajastin.Start();
131    }
132
133    /// <summary>
134    /// Pimennetään ruutua pikku hiljaa.
135    /// Oletusnopeus 0.01.
136    /// </summary>
137    public void PimennaRuutua(double nopeus, Action onFinished)
138    {
139        Timer ajastin = new Timer();
140        ajastin.Interval = 0.1;
141        ajastin.Timeout += delegate
142        {
143            Level.AmbientLight -= nopeus;
144            if (Level.AmbientLight <= 0.0)
145            {
146                ajastin.Stop();
147                ajastin.Reset();
148                if (onFinished != null)
149                    onFinished();
150            }
151        };
152        ajastin.Start();
153    }
154
155    /// <summary>
156    /// Kirkastetaan ruutua pikku hiljaa.
157    /// </summary>
158    public void KirkastaRuutua(double nopeus, double tavoite)
159    {
160        Timer ajastin = new Timer();
161        ajastin.Interval = 0.1;
162        ajastin.Timeout += delegate
163        {
164            //if (Level.AmbientLight > 0.1) return;
165            Level.AmbientLight += nopeus;
166            if (Level.AmbientLight > tavoite)
167            {
168                ajastin.Stop();
169                ajastin.Reset();
170            }
171        };
172        ajastin.Start();
173    }
174
175    /// <summary>
176    /// Kirkastetaan ruutua pikku hiljaa.
177    /// </summary>
178    public void KirkastaRuutua(double nopeus, double tavoite, Action onFinished)
179    {
180        Timer ajastin = new Timer();
181        ajastin.Interval = 0.1;
182        ajastin.Timeout += delegate
183        {
184            //if (Level.AmbientLight > 0.1) return;
185            Level.AmbientLight += nopeus;
186            if (Level.AmbientLight > tavoite)
187            {
188                ajastin.Stop();
189                ajastin.Reset();
190                if (onFinished != null)
191                    onFinished();
192            }
193        };
194        ajastin.Start();
195    }
196
197
198    /// <summary>
199    /// Piirretään valojuovia.
200    /// </summary>
201    /// <param name="position">Valojuovan tämänhetkinen sijainti.</param>
202    /// <param name="color">Valojuovan väri.</param>
203    /// <param name="lifetimeInSeconds">Kauanko valojuova pysyy kentällä.</param>
204    void DrawTracers(Vector position, Color color, double lifetimeInSeconds, double brightnessFactor)
205    {
206        color.AlphaComponent = (byte)(32 * brightnessFactor); // 64 toimii
207        GameObject tracer = new GameObject(2, 2);
208        tracer.Shape = Shape.Circle;
209        tracer.Color = color;
210        tracer.Position = position;
211        tracer.MaximumLifetime = TimeSpan.FromSeconds(lifetimeInSeconds);
212        Add(tracer);
213    }
214    /// <summary>
215    /// Piirretään valojuovia.
216    /// </summary>
217    /// <param name="tracingObject">Olio, josta valojuovat tulevat.</param>
218    /// <param name="color">Valojuovan väri.</param>
219    /// <param name="lifetimeInSeconds">Kauanko valojuova pysyy kentällä.</param>
220    /// <param name="brightnessFactor">Valojuovan kirkkaus.</param>
221    void DrawTracers(PhysicsObject tracingObject, Color color, double lifetimeInSeconds, double brightnessFactor)
222    {
223        color.AlphaComponent = (byte)(32 * brightnessFactor); // 64 toimii
224        GameObject tracer = new GameObject(90, 2);
225        tracer.Shape = Shape.Circle;
226        tracer.Color = color;
227        tracer.Position = tracingObject.Position;
228        tracer.Angle = tracingObject.Angle;
229        tracer.MaximumLifetime = TimeSpan.FromSeconds(lifetimeInSeconds);
230        Add(tracer);
231    }
232
233    void AloitusAnimaatio()
234    {
235        Level.Background.Color = Color.Black;
236        Level.AmbientLight = 0.0;
237        GameObject tausta = new GameObject(ajAlku);
238        Add(tausta);
239        KirkastaRuutua(0.05, 1.0);
240        H2Oopening.Play();
241        Keyboard.Listen(Key.Escape, ButtonState.Pressed, delegate {
242            stSequenceSkipped = true;
243            H2Oopening.Stop();
244            AloitaPeli();
245        }, null);
246
247
248        Timer.SingleShot(7.0, delegate {
249            if (!stSequenceSkipped)
250            {
251                PimennaRuutua(0.1, delegate
252                {
253                    if (!stSequenceSkipped)
254                        AloitaPeli();
255                });
256            }
257        });
258    }
259
260    void LataaContent()
261    {
262        chuckinkavely = LoadAnimation("pelaaja_anim");
263        chuckinKavelyFlipped = Animation.Mirror(chuckinkavely);
264        jounibossArrive = LoadAnimation("jouniboss_anim");
265        asemiesLiikkuu = LoadAnimation("asemiesliikkuu");
266    }
267
268    #endregion
269
270
271    void Liikuta(PhysicsObject pelaaja, double suunta)
272    {
273        pelaaja.Velocity = new Vector(suunta, pelaaja.Velocity.Y);
274
275        if (!pelaaja.Animation.IsPlaying)
276            pelaaja.Animation.Resume();
277    }
278
279    void LiikutaYlos(PhysicsObject pelaaja)
280    {
281        // pelaaja.Tag = "hyppy"; // PYRY MITÄ...rip
282
283        pelaaja.Hit(new Vector(0, HYPPYVOIMA * pelaaja.Mass));
284
285        Sound pelaajaHyppyAani = hyppy.CreateSound();
286        pelaajaHyppyAani.Pitch = 0.1;
287        Timer.SingleShot(0.1, delegate { pelaajaHyppyAani.Play(); });
288   
289    }
290
291    void LuoKentta()
292    {
293        SmoothTextures = false;
294        // IsFullScreen = true;
295        Gravity = new Vector(0, -2500);
296        // Synkataan taustakuvan ja colortilemapin pikselit
297        Level.Background.Image = LoadImage("kentta" + kenttaNro.ToString());
298
299        Level.Width = Screen.Width;
300        double kerroin = (double)Level.Background.Image.Width / Level.Background.Image.Height;
301        Level.Height = Level.Width / kerroin;
302        Level.Background.FitToLevel();
303
304        Image pohjaLevynKuva = LoadImage("kentta" + kenttaNro.ToString() + "pohja");
305
306        ColorTileMap pohjaLevy = new ColorTileMap(pohjaLevynKuva);
307        pohjaLevy.SetTileMethod(Color.Gold, LuoPohja);
308        pohjaLevy.SetTileMethod(Color.Cyan, Luotaistelija);
309        pohjaLevy.SetTileMethod(Color.DarkGray, LuoTormaavaVihollinen);
310        pohjaLevy.SetTileMethod(Color.Gray, LuoAmpuvaVihollinen);
311        pohjaLevy.SetTileMethod(Color.Red, LuoTriggerPalikka);
312        pohjaLevy.SetTileMethod(Color.HotPink, LuoAnttiJussi);
313        pohjaLevy.Optimize(Color.Gold);
314        pohjaLevy.Optimize(Color.Red);
315
316        // oletuksena 1 pikseli = 1 unit
317        const double BASE_SIZE = 1.0;
318        double widthMultiplier = Level.Width / pohjaLevynKuva.Width;
319        double heightMultiplier = Level.Height / pohjaLevynKuva.Height;
320        pohjaLevy.Execute(BASE_SIZE * widthMultiplier, BASE_SIZE * heightMultiplier);
321
322        PhysicsObject vasenreuna = Level.CreateLeftBorder();
323        vasenreuna.X -= 75;
324        vasenreuna.Tag = "vasenreuna";
325        vasenreuna.CollisionIgnoreGroup = 1; // ettei Jouni törmää
326        PhysicsObject oikeareuna = Level.CreateRightBorder();
327        oikeareuna.Tag = "oikeareuna";
328
329        Varjo(taistelija);
330        TeeKenttaKohtaisetAsiat(kenttaNro);
331    }
332
333    void Luotaistelija(Vector paikka, double leveys, double korkeus)
334    {
335        taistelija = new Elava(150, 150, 100.0);
336        taistelija.Shape = Shape.Rectangle;
337        taistelija.Animation = new Animation(chuckinkavely);
338        taistelija.Animation.Start();
339        taistelija.Tag = "pelaaja";
340        taistelija.Position = paikka;
341        taistelija.Kuoli += PelaajaKuoli;
342
343        AddCollisionHandler(taistelija, "vasenreuna", SeuraavaKentta);
344        //AddCollisionHandler<PhysicsObject, PhysicsObject>(taistelija, "vihollinen", delegate {
345        //    taistelija.Damagea(VIHOLLISEN_TORMAYSDMG);
346        //});
347
348        taistelija.Mass = 10.0;
349        Add(taistelija);
350        Camera.Follow(taistelija);
351        Camera.StayInLevel = true;
352
353        taistelijanAse = new AssaultRifle(20, 10);
354        taistelijanAse.FireRate = 20;
355        taistelijanAse.InfiniteAmmo = true;
356        taistelijanAse.Power.Value = 750;
357        taistelijanAse.Power.DefaultValue = 750;
358        taistelijanAse.AttackSound = ampuminen;
359        taistelija.Add(taistelijanAse);
360
361        LuoElamaPalkki();
362    }
363
364    void LuoElamaPalkki()
365    {
366        ProgressBar elamat = new ProgressBar(532 / 1.5, 49 / 1.5);
367        elamat.BindTo(taistelija.Elamat);
368        elamat.Left = Screen.Left + 40;
369        elamat.Top = Screen.Top - 40;
370        elamat.Image = ePalkkiTyhja;
371        elamat.BarImage = ePalkkiTaysi;
372        Add(elamat);
373    }
374
375    void LuoTriggerPalikka(Vector paikka, double leveys, double korkeus)
376    {
377        PhysicsObject trigger = new PhysicsObject(leveys, korkeus);
378        trigger.IsVisible = false;
379        trigger.IgnoresCollisionResponse = true;
380        trigger.Tag = "trigger";
381        trigger.Collided += delegate(IPhysicsObject t, IPhysicsObject kohde)
382        {
383            if (tActionTriggered) return;
384            if (kohde.Tag.ToString() == "trigger") return;
385
386            if (TriggerAction != null)
387                TriggerAction();
388
389            tActionTriggered = true;
390        };
391        trigger.Position = paikka;
392        trigger.MakeStatic();
393        Add(trigger);
394    }
395
396    GameObject Varjo(GameObject shadowCaster)
397    {
398        GameObject varjo = new GameObject(70, 30);
399        varjo.Image = taistelijanvarjo;
400        Add(varjo, -1);
401
402        Timer ajastin = new Timer();
403        ajastin.Interval = 1.0 / 60.0;
404        ajastin.Timeout += delegate
405        {
406            varjo.X = shadowCaster.X;
407            varjo.Y = EtsiVarjonY(shadowCaster);
408        };
409        ajastin.Start();
410
411        return varjo;
412    }
413
414    /// <summary>
415    /// Etsii suoraan pelaajan alla olevan lattiapalikan Y-koordinaatin.
416    /// </summary>
417    /// <returns></returns>
418    double EtsiVarjonY(GameObject shadowCaster)
419    {
420        Vector rayDown = new Vector(0.0, -2000.0);
421        List<GameObject> possibleObjects = GetObjects(x => x != shadowCaster && x is PhysicsObject);
422        List<GameObject> objectsBelow = new List<GameObject>();
423
424        for (int i = 0; i < possibleObjects.Count; i++)
425        {
426            if (possibleObjects[i].IsBlocking(new Vector(shadowCaster.X, shadowCaster.Bottom), new Vector(shadowCaster.X, shadowCaster.Bottom) + rayDown))
427            {
428                objectsBelow.Add(possibleObjects[i]);
429            }
430        }
431
432        if (objectsBelow.Count == 0)
433            return double.MinValue;
434
435        double minDistance = double.MaxValue;
436        int minIndex = -1;
437
438        for (int i = 0; i < objectsBelow.Count; i++)
439        {
440            double currentDistance = Math.Abs(shadowCaster.Bottom - objectsBelow[i].Top);
441            if (currentDistance < minDistance)
442            {
443                minDistance = currentDistance;
444                minIndex = i;
445            }
446        }
447
448        return objectsBelow[minIndex].Top;
449    }
450
451
452    void SeuraavaKentta(PhysicsObject tormaaja, PhysicsObject tormatty)
453    {
454        if (!paaseekoSeuraavaanKenttaan) return;
455
456        ClearAll();
457        taistelija = null;
458        TriggerAction = null;
459        tActionTriggered = false;
460
461        kenttaNro++;
462
463        if (kenttaNro > VIIMEINEN_KENTTA)
464        {
465            VoititPelin();
466        }
467
468        else
469        {
470            LuoKentta();
471            AsetaOhjaimet();
472        }
473    }
474
475    void TeeKenttaKohtaisetAsiat(int kentta)
476    {
477        switch (kentta)
478        {
479            case 10:
480                TriggerAction += delegate { LuoJouniBoss(new Vector(Screen.Left - jouniBoss.Width / 2 - 20, Screen.Bottom + (jouniBoss.Height / 2) - 100), Screen.Left + jouniBoss.Width / 2); };
481                break;
482            case 18:
483                taistelija.Size *= 0.5;
484                break;
485            default:
486                break;
487        }
488    }
489
490    void LuoPohja(Vector paikka, double leveys, double korkeus)
491    {
492        PhysicsObject pala = PhysicsObject.CreateStaticObject(leveys, korkeus);
493        pala.Position = paikka;
494        pala.IsVisible = false;
495        Add(pala);
496    }
497
498    void LuoChromaCase(ItemType forceItem)
499    {
500        Mouse.IsCursorVisible = true;
501
502        List<GameObject> pItems = new List<GameObject>();
503        GameObject knife = new GameObject(LoadImage("rareitem_knife"));
504        knife.Tag = new object[2] {(object)50.0, (object)ItemType.Knife};
505        pItems.Add(knife);
506
507        GameObject avain = new GameObject(LoadImage("rareitem_avain_small"));
508        avain.Tag = new object[2] { (object)50.0, (object)ItemType.Key };
509        pItems.Add(avain);
510       
511
512        //for (int i = 0; i < 40; i++)
513        //{
514        //    GameObject obj = new GameObject(50, 50);
515        //    obj.Color = RandomGen.NextColor();
516        //    obj.Tag = 50.0;
517        //    pItems.Add(obj);
518        //}
519
520        GameObject cCaseDialog = new GameObject(cCaseD); // koko debug
521        Add(cCaseDialog);
522
523        Mouse.ListenOn(cCaseDialog, MouseButton.Left, ButtonState.Pressed, delegate
524        {
525            cCaseDialog.Destroy();
526
527            GameObject cCaseFront = new GameObject(cCaseF);
528
529            if (forceItem == ItemType.Knife)
530            {
531                ChromaCase cCase = new ChromaCase(pItems, cCaseFront, knife, 20);
532                cCase.Add(new Vector(0.0, Level.Bottom + cCaseFront.Height / 2), 2);
533                cCase.ItemReceived += delegate(GameObject o) { GotItemFromCase(o); };
534                cCase.ItemRelativePosition = new Vector((472 - 467.5), (455 - 204));
535                cCase.Start();
536            }
537            else
538            {
539                ChromaCase cCase = new ChromaCase(pItems, cCaseFront, avain, 20);
540                cCase.Add(new Vector(0.0, Level.Bottom + cCaseFront.Height / 2), 2);
541                cCase.ItemReceived += delegate(GameObject o) { GotItemFromCase(o); };
542                cCase.ItemRelativePosition = new Vector((472 - 467.5), (455 - 204));
543                cCase.Start();
544            }
545        }, null);
546    }
547
548    void GotItemFromCase(GameObject o)
549    {
550        ItemType gotType = (ItemType)(((object[])o.Tag)[1]);
551
552        switch (gotType)
553        {
554            case ItemType.Knife:
555                GameObject inspect = new GameObject(karambitInspect);
556                inspect.Position = Camera.ScreenToWorld(Screen.Center);
557                karambitfadeSound.Play();
558                Timer.SingleShot(karambitfadeSound.Duration.Seconds + 1, delegate
559                {
560                    inspect.Destroy();
561                });
562                Add(inspect);
563                break;
564            case ItemType.Key:
565                break;
566            default:
567                break;
568        }
569    }
570
571    /// <summary>
572    /// Asetetaan pelaajalle ohjaimet.
573    /// </summary>
574    void AsetaOhjaimet()
575    {
576        Keyboard.Listen(Key.A, ButtonState.Down, Liikuta, null, taistelija, -NOPEUS);
577        Keyboard.Listen(Key.D, ButtonState.Down, Liikuta, null, taistelija, NOPEUS);
578        Keyboard.Listen(Key.W, ButtonState.Pressed, LiikutaYlos, null, taistelija);
579        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
580        Keyboard.Listen(Key.Space, ButtonState.Down, Ammu, null);
581        Keyboard.Listen(Key.LeftShift, ButtonState.Pressed, delegate { walkBackwards = true; }, null);
582        Keyboard.Listen(Key.LeftShift, ButtonState.Released, delegate { walkBackwards = false; }, null);
583
584    }
585
586    void Ammu()
587    {
588        if (taistelijanAse == null) 
589            return;
590
591        PhysicsObject ammus = taistelijanAse.Shoot();
592
593        if (ammus == null) 
594            return;
595        ammus.Size *= 0.2;
596
597        ammus.Hit(new Vector(0.0, RandomGen.NextDouble(-WEAPON_INACCURACY, WEAPON_INACCURACY)));
598        ammus.IsUpdated = true;
599        ammus.NeedsUpdateCall = true;
600        ammus.CanRotate = false;
601        ammus.Updated += delegate(PhysicsObject a) 
602        { 
603             DrawTracers(a, Color.Yellow, 0.2, 2.0); 
604        };
605
606        AddCollisionHandler(ammus, "vihollinen", AmmusOsuuViholliseen);
607        AddCollisionHandler(ammus, "jouni", AmmusOsuuViholliseen);
608
609        AddCollisionHandler<PhysicsObject, PhysicsObject>(ammus, delegate(PhysicsObject a, PhysicsObject k) { ammus.Destroy(); });
610    }
611
612    void AmmusOsuuViholliseen(PhysicsObject ammus, PhysicsObject kohde)
613    {
614        Elava vihu = kohde as Elava;
615
616        if (vihu == null) return;
617
618        vihu.Damagea(ASEEN_DMG);
619    }
620
621    void PelaajaKuoli()
622    {
623        kenttaNro -= kenttaNro % 3; // 3 kentän välein checkpoint
624
625        if (kenttaNro < 1)
626            kenttaNro = 1;
627
628        paaseekoSeuraavaanKenttaan = true;
629
630        taistelija = null;
631        TriggerAction = null;
632        tActionTriggered = false;
633
634
635        ClearAll();
636        LuoKentta();
637        AsetaOhjaimet();
638    }
639
640    void VoititPelin()
641    {
642
643    }
644}
Note: See TracBrowser for help on using the repository browser.