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

Revision 897, 15.9 KB checked in by hniemi, 10 years ago (diff)

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