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

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