source: 2010/23/hniemi/ShootEmUp/ShootEmUp/Peli.cs @ 944

Revision 944, 16.0 KB checked in by hniemi, 10 years ago (diff)

Aseenvaihto korjattu

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 Vector nopeusPysty = new Vector(0,NOPEUS);
18        private Vector nopeusVaaka = new Vector(NOPEUS, 0);
19
20        //Kentän rakenne
21        private Alus pelaajaAlus;
22        private PhysicsObject vasenLaita;
23        private PhysicsObject oikeaLaita;
24        private PhysicsObject pohja;
25        private PhysicsObject katto;
26        private PhysicsObject exitZone;
27
28        //Viholliset
29        private const int VIHOLLISKUVIA = 3;
30
31        //Statistiikka
32        private int kentannro = 0;
33        private IntMeter score = new IntMeter(0);
34        private Weapon[] weapons;
35
36        #endregion
37
38        protected override void Begin()
39        {
40            LataaKentta(kentannro);
41        }
42
43        #region Kentän lataaminen
44
45        /// <summary>
46        /// Tulee lataamaan numeroa vastaavan kentän
47        /// Kentän tiedot siis tallennettaisiin level1.txt, level2.txt...
48        /// </summary>
49        /// <param name="kentanNumero">Ei vielä käytössä</param>
50        void LataaKentta(int kentanNumero)
51        {
52            ClearAll();
53            Level.Width = 600;
54            Level.Height = 800;
55
56            Camera.Move(new Vector(250, 0));
57
58            //Laidat
59            LisaData tieto;
60            tieto.Tyyppi = "seina";
61            tieto.Rajahtaa = true;
62            tieto.Damage = 5;
63            vasenLaita = Level.CreateLeftBorder();
64            vasenLaita.Tag = tieto;
65            oikeaLaita = Level.CreateRightBorder();
66            oikeaLaita.Tag = tieto;
67            pohja = Level.CreateBottomBorder();
68            pohja.Tag = tieto;
69            katto = Level.CreateTopBorder();
70            katto.Tag = tieto;
71
72            //Exit-alueen tekeminen.
73            exitZone = PhysicsObject.CreateStaticObject(Level.Width, 200);
74            exitZone.Position = new Vector(Level.Center.X, Level.Bottom - exitZone.Size.Y / 2 - 5);
75            exitZone.Tag = tieto;
76            Add(exitZone);
77
78            LuoPelaaja();
79            LataaKontrollit(pelaajaAlus);
80            //LataaTausta(kentanNumero);
81            LataaViholliset(20, 4,10);
82            LataaHUD();
83        }
84
85        /// <summary>
86        /// Luo näytölle tarvittavat mittarit
87        /// </summary>
88        void LataaHUD()
89        {
90            ValueDisplay hpNaytto = new ValueDisplay();
91            hpNaytto.BindTo(pelaajaAlus.HpMeter);
92            Add(hpNaytto);
93            hpNaytto.Position = new Vector(Level.Right + 40, Level.Top - 80);
94            hpNaytto.Text = "HP: ";
95
96            ValueDisplay scoreNaytto = new ValueDisplay();
97            scoreNaytto.BindTo(score);
98            Add(scoreNaytto);
99            scoreNaytto.Position = new Vector(Level.Right + 40, Level.Top - 100);
100            scoreNaytto.Text = "SCORE: ";
101
102        }
103
104        /// <summary>
105        /// Luo pelaajan ja sijoittaa sen kentälle.
106        /// Asettaa pelaajalle myös aseen.
107        /// </summary>
108        void LuoPelaaja()
109        {
110            pelaajaAlus = new Alus(60, 55, 10);
111            pelaajaAlus.Shape = Shapes.Triangle;
112           
113            pelaajaAlus.Animation = new Animation(LoadImages("sankarialus/sankarialusThrust1", "sankarialus/sankarialusThrust2"));
114            pelaajaAlus.Animation.Start();
115
116            LisaData tieto;
117            tieto.Tyyppi = "oma";
118            tieto.Rajahtaa = true;
119            tieto.Damage = 5;
120            pelaajaAlus.Tag = tieto;
121
122            pelaajaAlus.Angle += Angle.Degrees(90);
123
124            pelaajaAlus.IgnoresCollisionResponse = false;
125            pelaajaAlus.Y = Level.Bottom + 40;
126            pelaajaAlus.KineticFriction = 1.0;
127            pelaajaAlus.Mass = 100000;
128
129            weapons = new Weapon[3];
130
131            weapons[0] = new Beam(1, 1);
132            ((Beam)weapons[0]).BeamCollision = AmmusOsuu;
133            weapons[0].Position = new Vector(0, -40);
134            weapons[1] = new Missile(1, 1);
135            ((Missile)weapons[1]).MissileCollision = AmmusOsuu;
136
137            weapons[2] = new Photon(1, 1);
138            ((Photon)weapons[2]).PhotonCollision = AmmusOsuu;
139
140            for (int i = 0; i < weapons.Length; i++)
141            {
142                pelaajaAlus.Add(weapons[i]);
143            }
144
145            Add(pelaajaAlus);
146            pelaajaAlus.SetWeapon(weapons[2]);
147           
148            AddCollisionHandler(pelaajaAlus, PelaajaTormaa);
149           
150        }
151
152        #endregion
153        #region Kontrollit ja liikkuminen
154        /// <summary>
155        /// Asettaa kontrollit ohjaamaan haluttua alusta
156        /// </summary>
157        /// <param name="pelaaja">Alus, jota halutaan ohjata</param>
158        void LataaKontrollit(Alus pelaaja)
159        {
160            Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Lopettaa pelin");
161            Keyboard.Listen(Key.Up, ButtonState.Down, Liikuta, "Liikuttaa alusta ylös", pelaaja, nopeusPysty);
162            Keyboard.Listen(Key.Up, ButtonState.Released, pelaaja.StopVertical, null);
163            Keyboard.Listen(Key.Down, ButtonState.Down, Liikuta, "Liikuttaa alusta alas", pelaaja, -nopeusPysty);
164            Keyboard.Listen(Key.Down, ButtonState.Released, pelaaja.StopVertical, null);
165            Keyboard.Listen(Key.Left, ButtonState.Down, Liikuta, "Liikuttaa alusta vasemmalle", pelaaja, -nopeusVaaka);
166            Keyboard.Listen(Key.Left, ButtonState.Released, pelaaja.StopHorizontal, null);
167            Keyboard.Listen(Key.Right, ButtonState.Down, Liikuta, "Liikuttaa alusta oikealle", pelaaja, nopeusVaaka);
168            Keyboard.Listen(Key.Right, ButtonState.Released, pelaaja.StopHorizontal, null);
169            Keyboard.Listen(Key.LeftControl, ButtonState.Down, Ammu, "Lopettaa pelin", pelaajaAlus);
170            Keyboard.Listen(Key.D1, ButtonState.Pressed, VaihdaAsetta, "Valitsee säde-aseen", 1);
171            Keyboard.Listen(Key.D2, ButtonState.Pressed, VaihdaAsetta, "Valitsee ohjuksen", 2);
172            Keyboard.Listen(Key.D3, ButtonState.Pressed, VaihdaAsetta, "Valitsee fotoniaseen", 3);
173        }
174
175        /// <summary>
176        /// Liikuttaa alusta haluttuun suuntaan
177        /// </summary>
178        /// <param name="alus">Liikutettava alus</param>
179        /// <param name="suunta">Liikutettava suunta</param>
180        void Liikuta(Alus alus, Vector suunta)
181        {
182            if (-NOPEUS < alus.Velocity.Y && alus.Velocity.Y < NOPEUS && suunta.Y != 0)
183            {
184                alus.Velocity += suunta;
185            }
186            if (-NOPEUS < alus.Velocity.X && alus.Velocity.X < NOPEUS && suunta.X != 0)
187            {
188                alus.Velocity += suunta;
189            }
190        }
191
192        void VaihdaAsetta(int aseenNumero)
193        {
194            if (aseenNumero > 0 && aseenNumero < 4)
195            pelaajaAlus.SetWeapon(weapons[aseenNumero-1]);
196        }
197
198        /// <summary>
199        /// Ampuu aluksella
200        /// </summary>
201        /// <param name="alus">Alus joka ampuu</param>
202        void Ammu(Alus alus)
203        {
204            alus.Shoot();
205        }
206
207        #endregion
208        #region Viholliset
209        /// <summary>
210        /// Lataa viholliset
211        /// TODO: Kentän numeron huomioiminen
212        /// </summary>
213        void LataaViholliset(int maara, double min, double max)
214        {
215            List<AikaTapahtuma> vihollistenTuloajat = new List<AikaTapahtuma>();
216           
217            for (int i = 0; i < maara; i++)
218            {
219                vihollistenTuloajat.Add(new AikaTapahtuma(2 + (i * 5), LahetaSatunnainenVihollislaivue, 4, 10));
220            }
221            vihollistenTuloajat.Add(new AikaTapahtuma(2 + (maara * 5), LahetaLoppupomo, 1, 20));
222
223            foreach (AikaTapahtuma tapahtuma in vihollistenTuloajat)
224            {
225                Timer ajastin = new Timer();
226                ajastin.Tag = tapahtuma.Lahtopaikka;
227                ajastin.Interval = tapahtuma.Aika;
228                ajastin.Trigger += tapahtuma.Tapahtuma;
229                Add(ajastin);
230                ajastin.Start(1);
231            }
232        }
233
234        /// <summary>
235        /// Luo alukset ja lähettää ne matkaan
236        /// </summary>
237        /// <param name="sender">Timerin tagissa on lähtökoordinaatti</param>
238        /// <param name="lahetysX">X-koordinaatti, josta muodostelma lähtee</param>
239        void LahetaLoppupomo(Timer sender)
240        {
241            double taso = ((Vector)sender.Tag).X;
242
243            List<Alus> alukset = new List<Alus>();
244            Image vihollisenKuva = LoadImage("loppuvastus" + 1);
245            alukset.Add(LuoVihollinen(vihollisenKuva, 400));
246            alukset[0].Position = new Vector(0, Level.Top + 200);
247            alukset[0].Angle = Angle.Degrees(270);
248            Add(alukset[0]);
249
250            //Aseen säätö
251            Photon ase = new Photon(10, 10);
252            LisaData ammuksenData;
253            ammuksenData.Damage = 20;
254            ammuksenData.Rajahtaa = false;
255            ammuksenData.Tyyppi = "vihollinen";
256            ase.Tag = ammuksenData;
257            alukset[0].Add(ase);
258            alukset[0].SetWeapon(ase);
259            alukset[0].UsedWeapon.IsVisible = false;
260            ase.PhotonCollision = AmmusOsuu;
261
262            Timer ampumaAjastin = new Timer();
263            ampumaAjastin.Interval = 0.7;
264            ampumaAjastin.Trigger += alukset[0].TimerShoot;
265            Add(ampumaAjastin);
266            ampumaAjastin.Start();
267
268            List<Vector> reitti = new List<Vector>();
269            reitti.Add(new Vector(-200, Level.Top - 100 ));
270            reitti.Add(new Vector(200, Level.Top - 100));
271
272            Muodostelma muodostelma = new Muodostelma(alukset, reitti, LuoLahettaja());
273            muodostelma.MovingSpeed = 100;
274            muodostelma.Start();
275        }
276
277        /// <summary>
278        /// Arpoo ja lähettää satunnaisen vihollislaivueen
279        /// Laivueessa on tällä hetkellä 10 alusta
280        /// Aluksen kuva arvotaan tiedostoista, joiden nimi on "vihollinen#.png"
281        /// </summary>
282        /// <param name="sender"></param>
283        void LahetaSatunnainenVihollislaivue(Timer sender)
284        {
285            List<Alus> alukset = new List<Alus>();
286            Image vihollisenKuva = LoadImage("vihollinen" + RandomGen.NextInt(1,VIHOLLISKUVIA));
287
288            int min = (int)((Vector)sender.Tag).X;
289            int max = (int)((Vector)sender.Tag).Y;
290            int koko = RandomGen.NextInt(min, max);
291
292            for (int i = 0; i < koko; i++)
293            {
294                alukset.Add(LuoVihollinen(vihollisenKuva, 40));
295                Add(alukset[i]);
296                Angle alas = new Angle();
297                alas.Degree = 270;
298                alukset[i].Angle = Angle.Degrees(270);
299                alukset[i].Position = new Vector(0, Level.Top + 200);
300                AddCollisionHandler(alukset[i], VihollinenTormaa);
301            }
302
303            List<Vector> reitti = ArvoReitti(RandomGen.NextInt(0,5));
304            Muodostelma muodostelma = new Muodostelma(alukset, reitti, LuoLahettaja());
305            muodostelma.MovingSpeed = 100;
306            muodostelma.Start();
307        }
308
309        /// <summary>
310        /// Arpoo koneelle reitin, joka lähteee ylhäältä ja päätyy alas
311        /// </summary>
312        /// <param name="valipisteet">Välipisteiden määrä, 0 -></param>
313        /// <returns></returns>
314        List<Vector> ArvoReitti(int valipisteet)
315        {
316            List<Vector> reitti = new List<Vector>();
317            reitti.Add(new Vector(RandomGen.NextDouble(Level.Left + 30, Level.Right - 30),Level.Top + 80));
318            for (int i = 0; i < valipisteet; i++)
319            {
320                reitti.Add(new Vector(RandomGen.NextDouble(Level.Left + 30, Level.Right - 30),
321                                     (RandomGen.NextDouble(Level.Bottom + 30, Level.Top - 100))));
322            }
323            reitti.Add(new Vector(RandomGen.NextDouble(Level.Left + 30, Level.Right - 30), Level.Bottom - 35));
324            return reitti;
325        }
326
327        Alus LuoVihollinen(Image kuva, int hp)
328        {
329           
330            Alus vihollinen = new Alus(kuva.Width/5, kuva.Height/5, hp);
331            vihollinen.Image = kuva;
332            LisaData tieto;
333            tieto.Tyyppi = "vihollinen";
334            tieto.Rajahtaa = true;
335            tieto.Damage = 5;
336            vihollinen.Tag = tieto;
337            return vihollinen;
338        }
339
340        /// <summary>
341        /// Luo ajastimen
342        /// Lisää myös ajastimen, joten voidaan kutsua suoraan Muodostelman muodostajassa.
343        /// </summary>
344        /// <returns></returns>
345        Timer LuoLahettaja()
346        {
347            Timer ajastin = new Timer();
348            ajastin.Interval = 0.5;
349            Add(ajastin);
350            return ajastin;
351        }
352        #endregion
353        #region Tapahtumat
354        /// <summary>
355        /// Pelaajan törmäyksen käsittelijä
356        ///
357        /// Katsoo myös, että pelaaja ei juutu seiniin
358        /// </summary>
359        /// <param name="tormaaja"></param>
360        /// <param name="kohde"></param>
361        void PelaajaTormaa(PhysicsObject tormaaja, PhysicsObject kohde)
362        {
363            if (((LisaData)kohde.Tag).Tyyppi == "vihollinen") 
364            {
365                ((Alus)tormaaja).TakeHit(5);
366                if (kohde is Alus) ((Alus)kohde).TakeHit(20);
367            }
368
369            if (kohde == vasenLaita)
370            {
371                tormaaja.X = Level.Left + tormaaja.Height / 2 + 1;
372                tormaaja.StopHorizontal();
373            }
374
375            if (kohde == oikeaLaita)
376            {
377                tormaaja.X = Level.Right - tormaaja.Height / 2 - 1;
378                tormaaja.StopHorizontal();
379            }
380            if (kohde == katto)
381            {
382                tormaaja.Y = Level.Top - tormaaja.Width / 2 - 1;
383                tormaaja.StopVertical();
384            }
385            if (kohde == pohja)
386            {
387                tormaaja.Y = Level.Bottom + tormaaja.Width/2 +1;
388                tormaaja.StopVertical();
389            }
390
391        }
392
393        /// <summary>
394        /// Mitä tapahtuu, kun vihollinen tulee ns. poistumisalueelle
395        /// </summary>
396        /// <param name="tormaaja"></param>
397        /// <param name="kohde"></param>
398        void VihollinenTormaa(PhysicsObject tormaaja, PhysicsObject kohde)
399        {
400            if (kohde == exitZone) Remove(tormaaja);
401           
402        }
403
404        void AmmusOsuu(PhysicsObject ammus, PhysicsObject toinen)
405        {
406
407            if (toinen.Tag.ToString() == "seina" || ((LisaData)toinen.Tag).Tyyppi != ((LisaData)ammus.Tag).Tyyppi)
408            {
409                ammus.Destroy();
410                if (((LisaData)ammus.Tag).Rajahtaa)
411                {
412                    Explosion rajahdys = new Explosion(100);
413                    rajahdys.Position = toinen.Position;
414                    Add(rajahdys);
415                }
416
417                if (((LisaData)toinen.Tag).Tyyppi == "vihollinen")
418                {
419                    if (toinen is Alus) 
420                    {
421                        ((Alus)toinen).TakeHit(((LisaData)ammus.Tag).Damage);
422                        if (toinen.IsDestroyed()) score.Value += 300;
423                    }
424                   
425                }
426            }
427
428
429        }
430        #endregion
431    }
432
433    public class AikaTapahtuma 
434    {
435        public int Aika;
436        public Timer.TriggerHandler Tapahtuma;
437        private Vector lahtopaikka;
438
439        public Vector Lahtopaikka
440        {
441            get{ return lahtopaikka; }
442        }
443
444        public AikaTapahtuma(int aika, Timer.TriggerHandler tapahtuma, double param1, double param2)
445        {
446            this.Aika = aika;
447            this.Tapahtuma = tapahtuma;
448            this.lahtopaikka = new Vector(param1, param2);
449        }
450    }
451}
Note: See TracBrowser for help on using the repository browser.