source: 2010/23/hniemi/JyTris/JyTris/Peli.cs @ 1489

Revision 1489, 17.3 KB checked in by hniemi, 10 years ago (diff)
Line 
1using System;
2using Jypeli;
3using Jypeli.Widgets;
4using Jypeli.Assets;
5
6namespace JyTris
7{
8    /// <summary>
9    /// JyTris 0.2
10    ///
11    /// Peli on tetrisklooni, joka on tarkoituksena toteuttaa JyPelillä
12    /// mahdollisimman yksinkertaisesti.
13    ///
14    /// Seuraavana tulossa:
15    /// - Kuvat palikoille
16    /// - Ruutu jossa näkyy seuraava palikka
17    /// - Lisääntyvä vaikeusaste
18    /// - Efektit palikkojen tuhoutumiseen
19    /// </summary>
20    public class Peli : Game
21    {
22        const int leveys = 10;
23        const int korkeus = 26;
24        const int palikkojenSivu = 30;
25
26        GameObject[][] pelikentta;
27        GameObject[][] ennustuskentta;
28        TetrisPalikka aktiivinenPalikka;
29        TetrisPalikka ennustusPalikka;
30
31        Timer tiputusajastin;
32
33        //Statistiikka
34        double vaikeusaste = 0.9 ;
35        IntMeter pisteet = new IntMeter(0);
36        IntMeter taso = new IntMeter(0);
37        int tuhotutRivit = 0;
38
39        Label tasonaytto;
40        Label pistenaytto;
41
42        /*
43         * Introon tarvittavat muuttujat
44         */
45        Timer introajastin;
46        private int indeksi = 0;
47        private int suunta = 1;
48        private int vaihtoCounter = 0;
49
50        /// <summary>
51        /// Tekee pelin alkuvalmistelut
52        /// </summary>
53        protected override void Begin()
54        {
55            LuoPelikentta();
56            AlkuIntro();
57            AsetaMenuNappaimet();
58            LuoHud();
59            //AsetaPeliNappaimet();
60            //KaynnistaPeli();
61        }
62
63        /// <summary>
64        /// Käynnistää alkuintron
65        /// </summary>
66        void AlkuIntro()
67        {
68            introajastin = new Timer();
69            introajastin.Interval = 0.05;
70            introajastin.Trigger += IntroPyoritys;
71            introajastin.Start();
72        }
73
74        /// <summary>
75        /// Pyörittää introa
76        /// </summary>
77        /// <param name="ajastin">Ei käytössä</param>
78        void IntroPyoritys(Timer ajastin)
79        {
80            TuhoaRivi(korkeus-1);
81
82            Color randomvari = RandomGen.NextColor();
83
84            for (int i = 0; i < pelikentta[0].Length; i++)
85            {
86                pelikentta[0][i].Color = randomvari;
87            }
88            pelikentta[0][indeksi].Color = Color.Brown;
89            indeksi += suunta;
90            vaihtoCounter++;
91            if (indeksi > leveys-1 && suunta > 0)
92            {
93                indeksi = 0;
94            }
95            if (indeksi < 0 && suunta < 0)
96            {
97                indeksi = leveys - 1;
98            }
99            if (vaihtoCounter > 50)
100            {
101                vaihtoCounter = 0;
102                suunta = -suunta;
103            }
104        }
105
106        /// <summary>
107        /// Käynnistää pelin
108        ///
109        /// Luo ensimmäisen palikan ja tekee ajastimen.
110        /// Tuhoaa myös kaikki valmiina olevat palikat.
111        ///
112        /// Poistaa asetetut kontrollit ja asettaa pelikontrollit.
113        ///
114        /// Resetoi vaikeusasteen!
115        /// </summary>
116        void KaynnistaPeli()
117        {
118            pisteet.Value = 0;
119            taso.Value = 1;
120            tuhotutRivit = 0;
121            introajastin.Stop();
122            TuhoaKaikki();
123            ClearControls();
124            AsetaPeliNappaimet();
125
126            vaikeusaste = 0.9;
127            tiputusajastin = new Timer();
128            tiputusajastin.Interval = vaikeusaste;
129            tiputusajastin.Trigger += Laske;
130            tiputusajastin.Start();
131            LuoPalikka();
132        }
133
134        /// <summary>
135        /// Tuhoaa täydet rivit kentältä
136        /// </summary>
137        void TuhoaTaydet()
138        {
139            bool tyhjia;
140            int potti = 0;
141
142
143            for (int i = 0; i < pelikentta.Length; i++)
144            {
145                tyhjia = false;
146                for (int j = 0; j < pelikentta[i].Length; j++)
147                {
148                    if (pelikentta[i][j].Color == Color.TransparentWhite) tyhjia = true;
149                }
150
151                if (!tyhjia)
152                {
153                    potti += 10;
154                    TuhoaRivi(i);
155                }
156            }
157
158            pisteet.Value += (potti/10) * taso * potti;
159
160            if (tuhotutRivit > 10)
161            {
162                tuhotutRivit -= 10;
163                tiputusajastin.Interval -= 0.1;
164                taso.Value++;
165            }
166        }
167
168        /// <summary>
169        /// Tuhoaa kaikki palikat kentältä.
170        /// </summary>
171        void TuhoaKaikki()
172        {
173            //Tässä käydään lävitse kaikki laatikot ja asetetaan ne läpinäkyviksi.
174            for (int i = 0; i < pelikentta.Length; i++)
175            {
176                for (int j = 0; j < pelikentta[i].Length; j++)
177                {
178                    pelikentta[i][j].Color = Color.TransparentWhite;
179                }
180            }
181        }
182
183        /// <summary>
184        /// Tuhoaa indeksiä vastaavan rivin ja tiputtaa sen päällä olevia rivejä.
185        /// </summary>
186        /// <param name="rivinIndeksi">Tiputettavan rivin indeksi</param>
187        void TuhoaRivi(int rivinIndeksi)
188        {
189            if (rivinIndeksi > pelikentta.Length || rivinIndeksi < 0) return;
190            tuhotutRivit++;
191
192            for (int i = rivinIndeksi; i > 0; i--)
193            {
194                for (int j = 0; j < pelikentta[i].Length; j++)
195                {
196                    pelikentta[i][j].Color = pelikentta[i - 1][j].Color;
197                }
198            }
199
200            for (int i = 0; i < pelikentta[0].Length; i++)
201            {
202                pelikentta[0][i].Color = Color.TransparentWhite;
203            }
204        }
205
206        /// <summary>
207        /// Luo näyttöön pistenäytöt ja muut elementit.
208        /// </summary>
209        void LuoHud()
210        {
211            pistenaytto = new Label(80, 20);
212            pistenaytto.BindTo(pisteet);
213            pistenaytto.Position = new Vector(Screen.RightSafe - 200, Screen.TopSafe - 100);
214            //pistenaytto.Text = "Pisteet: ";
215            Add(pistenaytto);
216
217            tasonaytto = new Label(20, 20);
218            tasonaytto.BindTo(taso);
219            tasonaytto.Position = new Vector(Screen.RightSafe - 200, Screen.TopSafe - 125);
220            //tasonaytto.Text = "Taso: ";
221            //tasonaytto.
222            Add(tasonaytto);
223           
224
225            /*
226             * Koska ennustuskenttä on kaksiulotteinen taulukko, joudumme luomaan
227             * ensiksi taulukon sarakkeet, jotta voimme luoda rivit.
228             */
229            ennustuskentta = new GameObject[4][];
230            for (int i = 0; i < ennustuskentta.Length; i++)
231            {
232                ennustuskentta[i] = new GameObject[4];
233            }
234
235            //Tässä luodaan pelikentän "laatiko" ja sijoitetaan ne oikeille kohdilleen.
236            for (int i = 0; i < ennustuskentta.Length; i++)
237            {
238                for (int j = 0; j < ennustuskentta[i].Length; j++)
239                {
240                    ennustuskentta[i][j] = new GameObject(palikkojenSivu, palikkojenSivu, Shapes.Rectangle);
241                    ennustuskentta[i][j].Color = Color.TransparentWhite;
242                    ennustuskentta[i][j].X = Level.Right + 100 + (palikkojenSivu / 2) + j * (palikkojenSivu);
243                    ennustuskentta[i][j].Y = Screen.TopSafe -200 - (palikkojenSivu / 2) - i * (palikkojenSivu);
244                    Add(ennustuskentta[i][j]);
245                }
246            }
247        }
248
249        /// <summary>
250        /// Luo pelikentän ylhäällä määrätyistä vakioista
251        /// </summary>
252        void LuoPelikentta()
253        {
254            //Tässä säädetään pelialueen koko, jotta seinät tulevat oikeille kohdille
255            Level.Width = leveys * palikkojenSivu;// + leveys;
256            Level.Height = korkeus * palikkojenSivu;// + korkeus;
257            Level.CreateBorders(true);
258
259            /*
260             * Koska pelikenttä on kaksiulotteinen taulukko, joudumme luomaan
261             * ensiksi taulukon sarakkeet, jotta voimme luoda rivit.
262             */
263            pelikentta = new GameObject[korkeus][];
264            for (int i = 0; i < pelikentta.Length; i++)
265            {
266                pelikentta[i] = new GameObject[leveys];
267            }
268
269            //Tässä luodaan pelikentän "laatiko" ja sijoitetaan ne oikeille kohdilleen.
270            for (int i = 0; i < pelikentta.Length; i++)
271            {
272                for (int j = 0; j < pelikentta[i].Length; j++)
273                {
274                    pelikentta[i][j] = new GameObject(palikkojenSivu, palikkojenSivu, Shapes.Rectangle);
275                    pelikentta[i][j].Color = Color.TransparentWhite;
276                    pelikentta[i][j].X = Level.Left + (palikkojenSivu / 2) + j * (palikkojenSivu);
277                    pelikentta[i][j].Y = Level.Top - (palikkojenSivu / 2) - i * (palikkojenSivu);
278                    Add(pelikentta[i][j]);
279                }
280            }
281        }
282
283       
284
285        /// <summary>
286        /// Asettaa pelin aikana tarvittavat näppäimet.
287        /// </summary>
288        void AsetaPeliNappaimet()
289        {
290            Vector vasemmalle = new Vector(-1, 0);
291            Vector oikealle = new Vector(1, 0);
292            Vector alas = new Vector(0, 1);
293
294            Keyboard.Listen(Key.Escape, ButtonState.Pressed, PeliLoppui, "Keskeyttää pelin");
295            Keyboard.Listen(Key.Left, ButtonState.Pressed, Liikuta, "Liikuttaa palikkaa vasemmalle", vasemmalle);
296            Keyboard.Listen(Key.Right, ButtonState.Pressed, Liikuta, "Liikuttaa palikkaa oikealle", oikealle);
297            Keyboard.Listen(Key.Down, ButtonState.Down, Laske, "Liikuttaa palikkaa alas", tiputusajastin);
298            Keyboard.Listen(Key.Up, ButtonState.Pressed, Kaanna, "Kääntää palikkaa");
299            Keyboard.Listen(Key.Space, ButtonState.Pressed, Tiputa, "Tiputtaa palikan");
300        }
301
302        /// <summary>
303        /// Asettaa menuissa käytettävät näppäimet
304        /// </summary>
305        void AsetaMenuNappaimet()
306        {
307            Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Poistuu pelistä");
308            Keyboard.Listen(Key.F2, ButtonState.Pressed, KaynnistaPeli, "Aloittaa uuden pelin");
309        }
310
311        /// <summary>
312        /// Liikuttaa palikkaa halutun verran.
313        /// </summary>
314        /// <param name="suunta">X ja Y oltava kokonaislukuja.</param>
315        void Liikuta(Vector suunta)
316        {
317            PaivitaPalikka(aktiivinenPalikka, Color.TransparentWhite);
318
319            if (VoikoSiirtaa(suunta, aktiivinenPalikka))
320            {
321                aktiivinenPalikka.Liikuta(suunta);
322            }
323           
324            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
325        }
326
327        /// <summary>
328        /// Kääntää palikkaa
329        /// </summary>
330        void Kaanna()
331        {
332            PaivitaPalikka(aktiivinenPalikka, Color.TransparentWhite);
333
334            //Tämä kohta tarkistaa, voiko palikkaa kääntää
335            //Jos ei voi, niin poistutaan.
336            Vector[] tulevaSijainti = aktiivinenPalikka.TulevaKaanto();
337            for (int i = 0; i < tulevaSijainti.Length; i++)
338            {
339                if (!OnkoTyhja(tulevaSijainti[i])) 
340                {
341                    PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
342                    return;
343                } 
344            }
345
346            aktiivinenPalikka.Kaanna();
347            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
348        }
349
350        /// <summary>
351        /// Laskee palikkaa yhdellä. Jos palikkaa ei voi laskea,
352        /// lähettää uuden palikan.
353        /// </summary>
354        /// <param name="timer">Ei käytössä</param>
355        void Laske(Timer timer)
356        {
357            PaivitaPalikka(aktiivinenPalikka, Color.TransparentWhite);
358
359            tiputusajastin.Reset();
360            if (!VoikoSiirtaa(new Vector(0,1), aktiivinenPalikka))
361            {
362                PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
363                TuhoaTaydet();
364                LuoPalikka();
365                return;
366            }
367            aktiivinenPalikka.Liikuta(new Vector(0, 1));
368            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
369
370        }
371
372        /// <summary>
373        /// Tiputtaa palikkan kokonaan alas.
374        /// </summary>
375        void Tiputa()
376        {
377            TetrisPalikka palikka = aktiivinenPalikka;
378            while (aktiivinenPalikka == palikka) Laske(tiputusajastin);
379        }
380
381        /// <summary>
382        /// Tarkistaa, voiko palikalle suorittaa annetut siirrot
383        ///
384        /// Annetut siirrot siis lisätään niitä vastaaviin palikan
385        /// sijainteihin.
386        /// </summary>
387        /// <param name="siirrot">X- ja Y-arvot oltava kokonaislukuja</param>
388        /// <param name="palikka">Palikka, jonka suhteen tarkistetaan</param>
389        /// <returns>true, jos palikan siirtäminen on mahdollista</returns>
390        bool VoikoSiirtaa(Vector[] siirrot, TetrisPalikka palikka)
391        {
392            Vector[] sijainnit = palikka.Sijainti();
393
394            for (int i = 0; i < siirrot.Length; i++)
395            {
396                if (!OnkoTyhja(sijainnit[i] + siirrot[i])) return false;
397            }
398            return true;
399        }
400
401        /// <summary>
402        /// Tarkistaa voiko kaikkia palikan osia siirtää annetun
403        /// vektorin verran
404        /// </summary>
405        /// <param name="siirto">X- ja Y-arvo oltava kokonaislukuja</param>
406        /// <param name="palikka">Palikka, jonka suhteen tarkistetaan</param>
407        /// <returns>true, jos siirto on mahdollinen</returns>
408        bool VoikoSiirtaa(Vector siirto, TetrisPalikka palikka)
409        {
410            Vector[] siirrot = new Vector[4];
411            for (int i = 0; i < siirrot.Length; i++)
412            {
413                siirrot[i] = siirto;
414            }
415            return VoikoSiirtaa(siirrot, palikka);
416        }
417
418        /// <summary>
419        /// Tarkistaa, onko annetut paikka tyhjä
420        ///
421        /// Paikka on tyhjä, jos sen väri on Color.TransparentWhite
422        /// </summary>
423        /// <param name="paikka">X ja Y oltava kokonaislukuja</param>
424        /// <returns>true, jos paikka on tyhjä</returns>
425        bool OnkoTyhja(Vector paikka)
426        {
427            if (paikka.X > leveys-1 || paikka.X < 0) return false;
428            if (paikka.Y > korkeus-1 || paikka.Y < 0) return false;
429
430            if (pelikentta[(int)paikka.Y][(int)paikka.X].Color == Color.TransparentWhite) return true;
431            return false;
432        }
433
434        /// <summary>
435        /// Värittää paikkaa vastaavat laatikot annetulla värillä
436        /// </summary>
437        /// <param name="palikka">Tämän sijainti väritetään</param>
438        /// <param name="vari">Väri, jolla väritetään</param>
439        void PaivitaPalikka(TetrisPalikka palikka, Color vari)
440        {
441            Vector[] sijainnit = palikka.Sijainti();
442
443            for (int i = 0; i < sijainnit.Length; i++)
444            {
445                pelikentta[(int)sijainnit[i].Y][(int)sijainnit[i].X].Color = vari;
446            }
447        }
448
449        /// <summary>
450        /// Luo palikan keskelle ylälaitaa
451        ///
452        /// Tulee antamaan satunnaisen palikan
453        /// </summary>
454        void LuoPalikka()
455        {
456            //Luo uuden palikan ja siirtää ennustuspalikan aktiiviseksi
457            //ennustusPalikka = new TetrisPalikka(leveys / 2);
458            if (aktiivinenPalikka != null)
459            {
460                aktiivinenPalikka = ennustusPalikka;
461            }
462            else 
463            { 
464                aktiivinenPalikka = new TetrisPalikka(leveys / 2); 
465            }
466
467            ennustusPalikka = new TetrisPalikka(leveys / 2);
468
469            AsetaEnnustusnaytto(ennustusPalikka);
470
471            tiputusajastin.Reset();
472
473            Vector[] sijainnit = aktiivinenPalikka.Sijainti();
474            for (int i = 0; i < sijainnit.Length; i++)
475            {
476                if (!OnkoTyhja(sijainnit[i]))
477                {
478                    PeliLoppui();
479                    return;
480                }
481            }
482
483            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
484        }
485
486        void AsetaEnnustusnaytto(TetrisPalikka palikka)
487        {
488            for (int i = 0; i < ennustuskentta.Length; i++)
489            {
490                for (int j = 0; j < ennustuskentta[i].Length; j++)
491                {
492                    ennustuskentta[i][j].Color = Color.TransparentWhite;
493                }
494            }
495
496            Vector[] sijainnit = palikka.Sijainti();
497            int offset = -(leveys / 2) + 1;
498
499            foreach (Vector paikka in sijainnit)
500            {
501                ennustuskentta[(int)paikka.Y ][(int)paikka.X + offset].Color = palikka.Vari();
502            }
503        }
504
505        /// <summary>
506        /// Lopettaa pelin.
507        /// - Palikkoja ei tipu
508        /// - Poistaa vanhat kontrollit
509        /// - Asettaa menunapit toimintaan
510        /// </summary>
511        void PeliLoppui()
512        {
513            tiputusajastin.Stop();
514            ClearControls();
515            AsetaMenuNappaimet();
516        }
517
518    }
519}
Note: See TracBrowser for help on using the repository browser.