source: 2010/23/hniemi/oksa/ShootEmUp/ShootEmUp/Peli.cs @ 1010

Revision 1010, 21.0 KB checked in by hniemi, 10 years ago (diff)

Ampuminen toimii

Line 
1using System;
2using Jypeli;
3using Jypeli.ScreenObjects;
4using Jypeli.Assets;
5using System.Collections.Generic;
6
7
8namespace ShootEmUp
9{
10    public class Peli : PhysicsGame
11    {
12        #region Julistukset
13       
14       
15        //Liikkumisnopeudet
16        private const double NOPEUS = 300;
17        private const int OLETUSASE = 0;
18        private Vector nopeusPysty = new Vector(0,NOPEUS);
19        private Vector nopeusVaaka = new Vector(NOPEUS, 0);
20
21        //Kentän rakenne
22        private Alus pelaajaAlus;
23        private PhysicsObject vasenLaita;
24        private PhysicsObject oikeaLaita;
25        private PhysicsObject pohja;
26        private PhysicsObject katto;
27        private PhysicsObject exitZone;
28
29        private GameObject[] tahdet;
30
31        //Viholliset
32        private const int VIHOLLISKUVIA = 4;
33
34        //Statistiikka
35        private int kentannro = 0;
36        private IntMeter score = new IntMeter(0);
37        private IntMeter lives = new IntMeter(3);
38        private TextDisplay[] aseNimet;
39        private Weapon[] weapons;
40
41        private bool bossmode = false;
42
43        #endregion
44
45        /// <summary>
46        /// Aloittaa pelin
47        /// </summary>
48        protected override void Begin()
49        {
50            LataaKentta(kentannro);
51        }
52
53        /// <summary>
54        /// Päivityssilmukka, hoitaa tällä hetkellä manuaalisesti vain
55        /// taustan liikuttamisen
56        /// </summary>
57        /// <param name="time"></param>
58        protected override void Update(Time time)
59        {
60            if (tahdet != null)
61            {
62                for (int i = 0; i < tahdet.Length; i++)
63                {
64                    tahdet[i].Y -= 30;
65                    if (tahdet[i].Y < Level.Bottom - 40) tahdet[i].Y = Level.Top + 100;
66                }
67            }
68
69            base.Update(time);
70        }
71
72        #region Kentän lataaminen
73
74        /// <summary>
75        /// Tulee lataamaan numeroa vastaavan kentän
76        /// Kentän tiedot siis tallennettaisiin level1.txt, level2.txt...
77        /// </summary>
78        /// <param name="kentanNumero">Ei vielä käytössä</param>
79        void LataaKentta(int kentanNumero)
80        {
81            ClearAll();
82            Level.Width = 600;
83            Level.Height = 800;
84
85            Camera.Move(new Vector(250, 0));
86            //Camera.Zoom(0.2);
87           
88            //Laidat
89            LisaData tieto = new LisaData();
90            tieto.Tyyppi = "seina";
91            tieto.Rajahtaa = true;
92            tieto.Damage = 5;
93
94            PhysicsObject[] kulmat = new PhysicsObject[4];
95
96            for (int i = 0; i < kulmat.Length; i++)
97            {
98                kulmat[i] = PhysicsObject.CreateStaticObject(60, 60);
99                kulmat[i].Image = LoadImage("seina/seinaKulma");
100                kulmat[i].Tag = tieto;
101                kulmat[i].Angle = Angle.Degrees(i * 90);
102                Add(kulmat[i]);
103            }
104            kulmat[3].Position = new Vector(Level.Left - 30, Level.Top+30);
105            kulmat[2].Position = new Vector(Level.Right + 30, Level.Top + 30);
106            kulmat[0].Position = new Vector(Level.Left - 30, Level.Bottom - 30);
107            kulmat[1].Position = new Vector(Level.Right + 30, Level.Bottom - 30);
108
109
110            //Seinät
111            Level.BackgroundColor = Color.Black;
112
113            vasenLaita = Level.CreateLeftBorder();
114            vasenLaita.Image = LoadImage("seina/seinaOikea");
115            vasenLaita.Angle = Angle.Degrees(270);
116            vasenLaita.Tag = tieto;
117
118            oikeaLaita = Level.CreateRightBorder();
119            oikeaLaita.Image = LoadImage("seina/seinaOikea");
120            oikeaLaita.Angle = Angle.Degrees(90);
121            oikeaLaita.Tag = tieto;
122
123            pohja = Level.CreateBottomBorder();
124            pohja.Image = LoadImage("seina/seinaOikea");
125            pohja.Angle = Angle.Degrees(0);
126            pohja.Size = new Vector(pohja.Width - 120, pohja.Height);
127            pohja.Tag = tieto;
128
129            katto = Level.CreateTopBorder();
130            katto.Image = LoadImage("seina/seinaOikea");
131            katto.Angle = Angle.Degrees(180);
132            katto.Size = new Vector(katto.Width - 120, katto.Height);
133            katto.Tag = tieto;
134
135            //Exit-alueen tekeminen.
136            exitZone = PhysicsObject.CreateStaticObject(Level.Width, 200);
137            exitZone.Position = new Vector(Level.Center.X, Level.Bottom - exitZone.Size.Y / 2 - 5);
138            exitZone.Tag = tieto;
139            exitZone.IsVisible = false;
140            Add(exitZone);
141
142           
143            LuoPelaaja();
144            LataaHUD();
145            LataaKontrollit(pelaajaAlus);
146            LataaTausta(kentanNumero);
147            LataaViholliset(20, 4,10);
148           
149        }
150
151        /// <summary>
152        /// Luo näytölle tarvittavat mittarit
153        /// </summary>
154        void LataaHUD()
155        {
156            ValueDisplay[] naytot = new ValueDisplay[3];
157            for (int i = 0; i < naytot.Length; i++)
158            {
159                naytot[i] = new ValueDisplay();
160                Add(naytot[i]);
161                naytot[i].TextColor = Color.White;
162                naytot[i].ValueColor = Color.Yellow;
163                naytot[i].Position = new Vector(Level.Right + 40, Level.Top - 80 - (30*i));
164            }
165
166            naytot[0].BindTo(pelaajaAlus.HpMeter);
167            naytot[1].BindTo(score);
168            naytot[2].BindTo(lives);
169            naytot[0].Text = "HP: ";
170            naytot[1].Text = "SCORE: ";
171            naytot[2].Text = "LIVES: ";
172
173            aseNimet = new TextDisplay[3];
174            for (int i = 0; i < aseNimet.Length; i++)
175            {
176                aseNimet[i] = new TextDisplay();
177                aseNimet[i].TextColor = Color.White;
178                aseNimet[i].Position = new Vector(Level.Right + 40, Level.Top - 200 - (30 * i));
179                Add(aseNimet[i]);
180            }
181            aseNimet[OLETUSASE].TextColor = Color.Yellow;
182            aseNimet[0].Text = "Beam";
183            aseNimet[1].Text = "Missile";
184            aseNimet[2].Text = "Photon";
185
186            Timer purkkaAjastin = new Timer();
187            purkkaAjastin.Interval = 0.01;
188            purkkaAjastin.Trigger += Purkkakorjaus;
189            Add(purkkaAjastin);
190            purkkaAjastin.Start(1);
191           
192        }
193
194        void Purkkakorjaus(Timer sender)
195        {
196            VaihdaAsetta(1);
197        }
198
199        /// <summary>
200        /// Lataa taustalle tähdet
201        /// </summary>
202        /// <param name="kentanNumero"></param>
203        void LataaTausta(int kentanNumero)
204        {
205            tahdet = new GameObject[15];
206            for (int i = 0; i < tahdet.Length; i++)
207            {
208                GameObject tahti = new GameObject(3, 3);
209                tahti.Color = Color.White;
210                tahti.Position = new Vector(RandomGen.NextDouble(Level.Left, Level.Right),
211                                            RandomGen.NextDouble(Level.Top +20, Level.Top + 2000));
212                tahdet[i] = tahti;
213
214                Add(tahti);
215            }
216        }
217
218        /// <summary>
219        /// Luo pelaajan ja sijoittaa sen kentälle.
220        /// Asettaa pelaajalle myös aseen.
221        /// </summary>
222        void LuoPelaaja()
223        {
224            pelaajaAlus = new Alus(60, 55, 10);
225            pelaajaAlus.Shape = Shapes.Triangle;
226           
227            pelaajaAlus.Animation = new Animation(LoadImages("sankarialus/sankarialusThrust1", "sankarialus/sankarialusThrust2"));
228            pelaajaAlus.Animation.Start();
229
230            LisaData tieto = new LisaData();
231            tieto.Tyyppi = "oma";
232            tieto.Rajahtaa = true;
233            tieto.Damage = 5;
234            pelaajaAlus.Tag = tieto;
235
236            pelaajaAlus.Angle += Angle.Degrees(90);
237
238            pelaajaAlus.IgnoresCollisionResponse = false;
239            pelaajaAlus.Y = Level.Bottom + 40;
240            pelaajaAlus.KineticFriction = 1.0;
241            pelaajaAlus.Mass = 100000;
242
243            weapons = new Weapon[3];
244
245            //LoadImage("sade");
246
247            weapons[0] = new Beam(5, 35, LoadImage("sade"));
248            ((ShmupWeapon)weapons[0]).ProjectileCollision = AmmusOsuu;
249            weapons[0].Position = new Vector(0, -40);
250            weapons[1] = new Missile(15, 30, LoadImage("ohjus"));
251            ((ShmupWeapon)weapons[1]).ProjectileCollision = AmmusOsuu;
252
253            weapons[2] = new Photon(15, 15, LoadImage("photon"));
254            ((ShmupWeapon)weapons[2]).ProjectileCollision = AmmusOsuu;
255
256            for (int i = 0; i < weapons.Length; i++)
257            {
258                weapons[i].IsVisible = false;
259                pelaajaAlus.Add(weapons[i]);
260            }
261
262            Add(pelaajaAlus);
263           
264           
265            AddCollisionHandler(pelaajaAlus, PelaajaTormaa);
266        }
267
268
269        #endregion
270        #region Kontrollit ja liikkuminen
271        /// <summary>
272        /// Asettaa kontrollit ohjaamaan haluttua alusta
273        /// </summary>
274        /// <param name="pelaaja">Alus, jota halutaan ohjata</param>
275        void LataaKontrollit(Alus pelaaja)
276        {
277            Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Lopettaa pelin");
278            Keyboard.Listen(Key.Up, ButtonState.Down, Liikuta, "Liikuttaa alusta ylös", pelaaja, nopeusPysty);
279            Keyboard.Listen(Key.Up, ButtonState.Released, pelaaja.StopVertical, null);
280            Keyboard.Listen(Key.Down, ButtonState.Down, Liikuta, "Liikuttaa alusta alas", pelaaja, -nopeusPysty);
281            Keyboard.Listen(Key.Down, ButtonState.Released, pelaaja.StopVertical, null);
282            Keyboard.Listen(Key.Left, ButtonState.Down, Liikuta, "Liikuttaa alusta vasemmalle", pelaaja, -nopeusVaaka);
283            Keyboard.Listen(Key.Left, ButtonState.Released, pelaaja.StopHorizontal, null);
284            Keyboard.Listen(Key.Right, ButtonState.Down, Liikuta, "Liikuttaa alusta oikealle", pelaaja, nopeusVaaka);
285            Keyboard.Listen(Key.Right, ButtonState.Released, pelaaja.StopHorizontal, null);
286            Keyboard.Listen(Key.LeftControl, ButtonState.Down, Ammu, "Lopettaa pelin", pelaajaAlus);
287            Keyboard.Listen(Key.D1, ButtonState.Pressed, VaihdaAsetta, "Valitsee säde-aseen", 1);
288            Keyboard.Listen(Key.D2, ButtonState.Pressed, VaihdaAsetta, "Valitsee ohjuksen", 2);
289            Keyboard.Listen(Key.D3, ButtonState.Pressed, VaihdaAsetta, "Valitsee fotoniaseen", 3);
290        }
291
292        /// <summary>
293        /// Liikuttaa alusta haluttuun suuntaan
294        /// </summary>
295        /// <param name="alus">Liikutettava alus</param>
296        /// <param name="suunta">Liikutettava suunta</param>
297        void Liikuta(Alus alus, Vector suunta)
298        {
299            if (-NOPEUS < alus.Velocity.Y && alus.Velocity.Y < NOPEUS && suunta.Y != 0)
300            {
301                alus.Velocity += suunta;
302            }
303            if (-NOPEUS < alus.Velocity.X && alus.Velocity.X < NOPEUS && suunta.X != 0)
304            {
305                alus.Velocity += suunta;
306            }
307        }
308
309        void VaihdaAsetta(int aseenNumero)
310        {
311            if (aseenNumero > 0 && aseenNumero < 4)
312            {
313                pelaajaAlus.SetWeapon(weapons[aseenNumero-1]);
314                for (int i = 0; i < aseNimet.Length; i++)
315                {
316                    aseNimet[i].TextColor = Color.White;
317                }
318                aseNimet[aseenNumero-1].TextColor = Color.Yellow;
319            }
320        }
321
322        /// <summary>
323        /// Ampuu aluksella
324        /// </summary>
325        /// <param name="alus">Alus joka ampuu</param>
326        void Ammu(Alus alus)
327        {
328            alus.Shoot();
329            //Add(alus.Shoot());
330        }
331
332        #endregion
333        #region Viholliset
334        /// <summary>
335        /// Lataa viholliset
336        /// TODO: Kentän numeron huomioiminen
337        ///
338        /// Jos bossmode on päällä, lähettää vain loppupomon.
339        /// </summary>
340        void LataaViholliset(int maara, double min, double max)
341        {
342            List<AikaTapahtuma> vihollistenTuloajat = new List<AikaTapahtuma>();
343
344            if (!bossmode)
345            {
346                for (int i = 0; i < maara; i++)
347                {
348                    vihollistenTuloajat.Add(new AikaTapahtuma(2 + (i * 5), LahetaSatunnainenVihollislaivue, 4, 10));
349                }
350                vihollistenTuloajat.Add(new AikaTapahtuma(2 + (maara * 5), LahetaLoppupomo, 1, 20));
351            }
352            else
353            {
354                vihollistenTuloajat.Add(new AikaTapahtuma(0, LahetaLoppupomo, 1, 20));
355            }
356            foreach (AikaTapahtuma tapahtuma in vihollistenTuloajat)
357            {
358                Timer ajastin = new Timer();
359                ajastin.Tag = tapahtuma.Lahtopaikka;
360                ajastin.Interval = tapahtuma.Aika;
361                ajastin.Trigger += tapahtuma.Tapahtuma;
362                Add(ajastin);
363                ajastin.Start(1);
364            }
365        }
366
367        /// <summary>
368        /// Luo alukset ja lähettää ne matkaan
369        /// </summary>
370        /// <param name="sender">Timerin tagissa on lähtökoordinaatti</param>
371        /// <param name="lahetysX">X-koordinaatti, josta muodostelma lähtee</param>
372        void LahetaLoppupomo(Timer sender)
373        {
374            double taso = ((Vector)sender.Tag).X;
375
376            List<Alus> alukset = new List<Alus>();
377            Image vihollisenKuva = LoadImage("loppuvastus" + 1);
378            alukset.Add(LuoVihollinen(vihollisenKuva, 400));
379            alukset[0].Position = new Vector(0, Level.Top + 200);
380            alukset[0].Angle = Angle.Degrees(270);
381            Add(alukset[0]);
382
383            //ase.ProjectileCollision = AmmusOsuu;
384
385            Timer Purkkakorjaus = new Timer();
386            Purkkakorjaus.Tag = alukset[0];
387            Purkkakorjaus.Interval = 0.1;
388            Purkkakorjaus.Trigger += Purkkakorjaus2;
389            Add(Purkkakorjaus);
390            Purkkakorjaus.Start();
391
392            //Lisää ampuma-ajastimen
393            Timer ampumaAjastin = new Timer();
394            ampumaAjastin.Interval = 0.7;
395            ampumaAjastin.Trigger += alukset[0].Shoot;
396            Add(ampumaAjastin);
397            ampumaAjastin.Start();
398
399            List<Vector> reitti = new List<Vector>();
400            reitti.Add(new Vector(-200, Level.Top - 100 ));
401            reitti.Add(new Vector(200, Level.Top - 100));
402
403            Muodostelma muodostelma = new Muodostelma(alukset, reitti, LuoLahettaja());
404            muodostelma.MovingSpeed = 100;
405            muodostelma.Start();
406        }
407
408        void Purkkakorjaus2(Timer sender)
409        {             
410            //Aseen säätö
411
412            Photon ase = new Photon(10, 10, LoadImage("photon"));
413            Add(ase);
414            ase.Data.Damage = 20;
415            ase.Data.Rajahtaa = false;
416            ase.Data.Tyyppi = "vihollinen";
417            ((Alus)sender.Tag).Add(ase);
418            ((Alus)sender.Tag).SetWeapon(ase);
419        }
420
421        /// <summary>
422        /// Arpoo ja lähettää satunnaisen vihollislaivueen
423        /// Laivueessa on tällä hetkellä 10 alusta
424        /// Aluksen kuva arvotaan tiedostoista, joiden nimi on "vihollinen#.png"
425        /// </summary>
426        /// <param name="sender"></param>
427        void LahetaSatunnainenVihollislaivue(Timer sender)
428        {
429            List<Alus> alukset = new List<Alus>();
430            Image vihollisenKuva = LoadImage("vihollinen" + RandomGen.NextInt(1,VIHOLLISKUVIA));
431
432            int min = (int)((Vector)sender.Tag).X;
433            int max = (int)((Vector)sender.Tag).Y;
434            int koko = RandomGen.NextInt(min, max);
435
436            for (int i = 0; i < koko; i++)
437            {
438                alukset.Add(LuoVihollinen(vihollisenKuva, 40));
439                Add(alukset[i]);
440                Angle alas = new Angle();
441                alas.Degree = 270;
442                alukset[i].Angle = Angle.Degrees(270);
443                alukset[i].Position = new Vector(0, Level.Top + 200);
444                AddCollisionHandler(alukset[i], VihollinenTormaa);
445            }
446
447            IList<Vector> reitti = ArvoReitti(RandomGen.NextInt(0,5));
448            Muodostelma muodostelma = new Muodostelma(alukset, reitti, LuoLahettaja());
449            muodostelma.MovingSpeed = 200;
450            muodostelma.Start();
451        }
452
453        /// <summary>
454        /// Arpoo koneelle reitin, joka lähteee ylhäältä ja päätyy alas
455        /// </summary>
456        /// <param name="valipisteet">Välipisteiden määrä, 0 -></param>
457        /// <returns></returns>
458        List<Vector> ArvoReitti(int valipisteet)
459        {
460            List<Vector> reitti = new List<Vector>();
461            reitti.Add(new Vector(RandomGen.NextDouble(Level.Left + 30, Level.Right - 30),Level.Top + 80));
462            for (int i = 0; i < valipisteet; i++)
463            {
464                reitti.Add(new Vector(RandomGen.NextDouble(Level.Left + 30, Level.Right - 30),
465                                     (RandomGen.NextDouble(Level.Bottom + 30, Level.Top - 100))));
466            }
467            reitti.Add(new Vector(RandomGen.NextDouble(Level.Left + 30, Level.Right - 30), Level.Bottom - 35));
468            return reitti;
469        }
470
471        Alus LuoVihollinen(Image kuva, int hp)
472        {
473           
474            Alus vihollinen = new Alus(kuva.Width/5, kuva.Height/5, hp);
475            vihollinen.Image = kuva;
476            LisaData tieto = new LisaData();
477            tieto.Tyyppi = "vihollinen";
478            tieto.Rajahtaa = true;
479            tieto.Damage = 5;
480            vihollinen.Tag = tieto;
481            return vihollinen;
482        }
483
484        /// <summary>
485        /// Luo ajastimen
486        /// Lisää myös ajastimen, joten voidaan kutsua suoraan Muodostelman muodostajassa.
487        /// </summary>
488        /// <returns></returns>
489        Timer LuoLahettaja()
490        {
491            Timer ajastin = new Timer();
492            ajastin.Interval = 0.5;
493            Add(ajastin);
494            return ajastin;
495        }
496        #endregion
497        #region Tapahtumat
498        /// <summary>
499        /// Pelaajan törmäyksen käsittelijä
500        ///
501        /// Katsoo myös, että pelaaja ei juutu seiniin
502        /// </summary>
503        /// <param name="tormaaja"></param>
504        /// <param name="kohde"></param>
505        void PelaajaTormaa(PhysicsObject tormaaja, PhysicsObject kohde)
506        {
507            if (((LisaData)kohde.Tag).Tyyppi == "vihollinen") 
508            {
509                ((Alus)tormaaja).TakeHit(5);
510                if (kohde is Alus) ((Alus)kohde).TakeHit(20);
511            }
512
513            if (kohde == vasenLaita)
514            {
515                tormaaja.X = Level.Left + tormaaja.Height / 2 + 1;
516                tormaaja.StopHorizontal();
517            }
518
519            if (kohde == oikeaLaita)
520            {
521                tormaaja.X = Level.Right - tormaaja.Height / 2 - 1;
522                tormaaja.StopHorizontal();
523            }
524            if (kohde == katto)
525            {
526                tormaaja.Y = Level.Top - tormaaja.Width / 2 - 1;
527                tormaaja.StopVertical();
528            }
529            if (kohde == pohja)
530            {
531                tormaaja.Y = Level.Bottom + tormaaja.Width/2 +1;
532                tormaaja.StopVertical();
533            }
534
535        }
536
537        /// <summary>
538        /// Mitä tapahtuu, kun vihollinen tulee ns. poistumisalueelle
539        /// </summary>
540        /// <param name="tormaaja"></param>
541        /// <param name="kohde"></param>
542        void VihollinenTormaa(PhysicsObject tormaaja, PhysicsObject kohde)
543        {
544            if (kohde == exitZone) Remove(tormaaja);
545           
546        }
547
548        void AmmusOsuu(PhysicsObject ammus, PhysicsObject toinen)
549        {
550
551            if (toinen.Tag.ToString() == "seina" || ((LisaData)toinen.Tag).Tyyppi != ((LisaData)ammus.Tag).Tyyppi)
552            {
553                ammus.Destroy();
554                if (((LisaData)ammus.Tag).Rajahtaa)
555                {
556                    Explosion rajahdys = new Explosion(100);
557                    rajahdys.Position = toinen.Position;
558                    Add(rajahdys);
559                }
560
561                if (((LisaData)toinen.Tag).Tyyppi == "vihollinen")
562                {
563                    if (toinen is Alus) 
564                    {
565                        ((Alus)toinen).TakeHit(((LisaData)ammus.Tag).Damage);
566                        if (toinen.IsDestroyed()) score.Value += 300;
567                    }
568                   
569                }
570            }
571
572
573        }
574        #endregion
575    }
576
577    public class AikaTapahtuma 
578    {
579        public int Aika;
580        public Timer.TriggerHandler Tapahtuma;
581        private Vector lahtopaikka;
582
583        public Vector Lahtopaikka
584        {
585            get{ return lahtopaikka; }
586        }
587
588        public AikaTapahtuma(int aika, Timer.TriggerHandler tapahtuma, double param1, double param2)
589        {
590            this.Aika = aika;
591            this.Tapahtuma = tapahtuma;
592            this.lahtopaikka = new Vector(param1, param2);
593        }
594    }
595}
Note: See TracBrowser for help on using the repository browser.