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

Revision 1485, 16.6 KB checked in by hniemi, 10 years ago (diff)

Profetiallinen ennustusnäyttö lisätty.

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