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

Revision 1544, 19.5 KB checked in by hniemi, 9 years ago (diff)

Topten-lista poistettu koska se ei syystä X ja T toiminut muilla koneilla

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