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

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