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

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