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

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