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

Revision 1515, 18.9 KB checked in by hniemi, 10 years ago (diff)

Lisätty viimeinen puuttuva palikka ja tekstejä

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