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

Revision 1488, 17.2 KB checked in by hniemi, 10 years ago (diff)

Tasolaskuri lisätty

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                taso.Value++;
164            }
165        }
166
167        /// <summary>
168        /// Tuhoaa kaikki palikat kentältä.
169        /// </summary>
170        void TuhoaKaikki()
171        {
172            //Tässä käydään lävitse kaikki laatikot ja asetetaan ne läpinäkyviksi.
173            for (int i = 0; i < pelikentta.Length; i++)
174            {
175                for (int j = 0; j < pelikentta[i].Length; j++)
176                {
177                    pelikentta[i][j].Color = Color.TransparentWhite;
178                }
179            }
180        }
181
182        /// <summary>
183        /// Tuhoaa indeksiä vastaavan rivin ja tiputtaa sen päällä olevia rivejä.
184        /// </summary>
185        /// <param name="rivinIndeksi">Tiputettavan rivin indeksi</param>
186        void TuhoaRivi(int rivinIndeksi)
187        {
188            if (rivinIndeksi > pelikentta.Length || rivinIndeksi < 0) return;
189            tuhotutRivit++;
190
191            for (int i = rivinIndeksi; i > 0; i--)
192            {
193                for (int j = 0; j < pelikentta[i].Length; j++)
194                {
195                    pelikentta[i][j].Color = pelikentta[i - 1][j].Color;
196                }
197            }
198
199            for (int i = 0; i < pelikentta[0].Length; i++)
200            {
201                pelikentta[0][i].Color = Color.TransparentWhite;
202            }
203        }
204
205        /// <summary>
206        /// Luo näyttöön pistenäytöt ja muut elementit.
207        /// </summary>
208        void LuoHud()
209        {
210            pistenaytto = new Label(80, 20);
211            pistenaytto.BindTo(pisteet);
212            pistenaytto.Position = new Vector(Screen.RightSafe - 200, Screen.TopSafe - 100);
213            //pistenaytto.Text = "Pisteet: ";
214            Add(pistenaytto);
215
216            tasonaytto = new Label(20, 20);
217            tasonaytto.BindTo(taso);
218            tasonaytto.Position = new Vector(Screen.RightSafe - 200, Screen.TopSafe - 125);
219            //tasonaytto.Text = "Taso: ";
220            //tasonaytto.
221            Add(tasonaytto);
222           
223
224            /*
225             * Koska ennustuskenttä on kaksiulotteinen taulukko, joudumme luomaan
226             * ensiksi taulukon sarakkeet, jotta voimme luoda rivit.
227             */
228            ennustuskentta = new GameObject[4][];
229            for (int i = 0; i < ennustuskentta.Length; i++)
230            {
231                ennustuskentta[i] = new GameObject[4];
232            }
233
234            //Tässä luodaan pelikentän "laatiko" ja sijoitetaan ne oikeille kohdilleen.
235            for (int i = 0; i < ennustuskentta.Length; i++)
236            {
237                for (int j = 0; j < ennustuskentta[i].Length; j++)
238                {
239                    ennustuskentta[i][j] = new GameObject(palikkojenSivu, palikkojenSivu, Shapes.Rectangle);
240                    ennustuskentta[i][j].Color = Color.TransparentWhite;
241                    ennustuskentta[i][j].X = Level.Right + 100 + (palikkojenSivu / 2) + j * (palikkojenSivu);
242                    ennustuskentta[i][j].Y = Screen.TopSafe -200 - (palikkojenSivu / 2) - i * (palikkojenSivu);
243                    Add(ennustuskentta[i][j]);
244                }
245            }
246        }
247
248        /// <summary>
249        /// Luo pelikentän ylhäällä määrätyistä vakioista
250        /// </summary>
251        void LuoPelikentta()
252        {
253            //Tässä säädetään pelialueen koko, jotta seinät tulevat oikeille kohdille
254            Level.Width = leveys * palikkojenSivu;// + leveys;
255            Level.Height = korkeus * palikkojenSivu;// + korkeus;
256            Level.CreateBorders(true);
257
258            /*
259             * Koska pelikenttä on kaksiulotteinen taulukko, joudumme luomaan
260             * ensiksi taulukon sarakkeet, jotta voimme luoda rivit.
261             */
262            pelikentta = new GameObject[korkeus][];
263            for (int i = 0; i < pelikentta.Length; i++)
264            {
265                pelikentta[i] = new GameObject[leveys];
266            }
267
268            //Tässä luodaan pelikentän "laatiko" ja sijoitetaan ne oikeille kohdilleen.
269            for (int i = 0; i < pelikentta.Length; i++)
270            {
271                for (int j = 0; j < pelikentta[i].Length; j++)
272                {
273                    pelikentta[i][j] = new GameObject(palikkojenSivu, palikkojenSivu, Shapes.Rectangle);
274                    pelikentta[i][j].Color = Color.TransparentWhite;
275                    pelikentta[i][j].X = Level.Left + (palikkojenSivu / 2) + j * (palikkojenSivu);
276                    pelikentta[i][j].Y = Level.Top - (palikkojenSivu / 2) - i * (palikkojenSivu);
277                    Add(pelikentta[i][j]);
278                }
279            }
280        }
281
282       
283
284        /// <summary>
285        /// Asettaa pelin aikana tarvittavat näppäimet.
286        /// </summary>
287        void AsetaPeliNappaimet()
288        {
289            Vector vasemmalle = new Vector(-1, 0);
290            Vector oikealle = new Vector(1, 0);
291            Vector alas = new Vector(0, 1);
292
293            Keyboard.Listen(Key.Escape, ButtonState.Pressed, PeliLoppui, "Keskeyttää pelin");
294            Keyboard.Listen(Key.Left, ButtonState.Pressed, Liikuta, "Liikuttaa palikkaa vasemmalle", vasemmalle);
295            Keyboard.Listen(Key.Right, ButtonState.Pressed, Liikuta, "Liikuttaa palikkaa oikealle", oikealle);
296            Keyboard.Listen(Key.Down, ButtonState.Down, Laske, "Liikuttaa palikkaa alas", tiputusajastin);
297            Keyboard.Listen(Key.Up, ButtonState.Pressed, Kaanna, "Kääntää palikkaa");
298            Keyboard.Listen(Key.Space, ButtonState.Pressed, Tiputa, "Tiputtaa palikan");
299        }
300
301        /// <summary>
302        /// Asettaa menuissa käytettävät näppäimet
303        /// </summary>
304        void AsetaMenuNappaimet()
305        {
306            Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Poistuu pelistä");
307            Keyboard.Listen(Key.F2, ButtonState.Pressed, KaynnistaPeli, "Aloittaa uuden pelin");
308        }
309
310        /// <summary>
311        /// Liikuttaa palikkaa halutun verran.
312        /// </summary>
313        /// <param name="suunta">X ja Y oltava kokonaislukuja.</param>
314        void Liikuta(Vector suunta)
315        {
316            PaivitaPalikka(aktiivinenPalikka, Color.TransparentWhite);
317
318            if (VoikoSiirtaa(suunta, aktiivinenPalikka))
319            {
320                aktiivinenPalikka.Liikuta(suunta);
321            }
322           
323            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
324        }
325
326        /// <summary>
327        /// Kääntää palikkaa
328        /// </summary>
329        void Kaanna()
330        {
331            PaivitaPalikka(aktiivinenPalikka, Color.TransparentWhite);
332
333            //Tämä kohta tarkistaa, voiko palikkaa kääntää
334            //Jos ei voi, niin poistutaan.
335            Vector[] tulevaSijainti = aktiivinenPalikka.TulevaKaanto();
336            for (int i = 0; i < tulevaSijainti.Length; i++)
337            {
338                if (!OnkoTyhja(tulevaSijainti[i])) 
339                {
340                    PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
341                    return;
342                } 
343            }
344
345            aktiivinenPalikka.Kaanna();
346            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
347        }
348
349        /// <summary>
350        /// Laskee palikkaa yhdellä. Jos palikkaa ei voi laskea,
351        /// lähettää uuden palikan.
352        /// </summary>
353        /// <param name="timer">Ei käytössä</param>
354        void Laske(Timer timer)
355        {
356            PaivitaPalikka(aktiivinenPalikka, Color.TransparentWhite);
357
358            tiputusajastin.Reset();
359            if (!VoikoSiirtaa(new Vector(0,1), aktiivinenPalikka))
360            {
361                PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
362                TuhoaTaydet();
363                LuoPalikka();
364                return;
365            }
366            aktiivinenPalikka.Liikuta(new Vector(0, 1));
367            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
368
369        }
370
371        /// <summary>
372        /// Tiputtaa palikkan kokonaan alas.
373        /// </summary>
374        void Tiputa()
375        {
376            TetrisPalikka palikka = aktiivinenPalikka;
377            while (aktiivinenPalikka == palikka) Laske(tiputusajastin);
378        }
379
380        /// <summary>
381        /// Tarkistaa, voiko palikalle suorittaa annetut siirrot
382        ///
383        /// Annetut siirrot siis lisätään niitä vastaaviin palikan
384        /// sijainteihin.
385        /// </summary>
386        /// <param name="siirrot">X- ja Y-arvot oltava kokonaislukuja</param>
387        /// <param name="palikka">Palikka, jonka suhteen tarkistetaan</param>
388        /// <returns>true, jos palikan siirtäminen on mahdollista</returns>
389        bool VoikoSiirtaa(Vector[] siirrot, TetrisPalikka palikka)
390        {
391            Vector[] sijainnit = palikka.Sijainti();
392
393            for (int i = 0; i < siirrot.Length; i++)
394            {
395                if (!OnkoTyhja(sijainnit[i] + siirrot[i])) return false;
396            }
397            return true;
398        }
399
400        /// <summary>
401        /// Tarkistaa voiko kaikkia palikan osia siirtää annetun
402        /// vektorin verran
403        /// </summary>
404        /// <param name="siirto">X- ja Y-arvo oltava kokonaislukuja</param>
405        /// <param name="palikka">Palikka, jonka suhteen tarkistetaan</param>
406        /// <returns>true, jos siirto on mahdollinen</returns>
407        bool VoikoSiirtaa(Vector siirto, TetrisPalikka palikka)
408        {
409            Vector[] siirrot = new Vector[4];
410            for (int i = 0; i < siirrot.Length; i++)
411            {
412                siirrot[i] = siirto;
413            }
414            return VoikoSiirtaa(siirrot, palikka);
415        }
416
417        /// <summary>
418        /// Tarkistaa, onko annetut paikka tyhjä
419        ///
420        /// Paikka on tyhjä, jos sen väri on Color.TransparentWhite
421        /// </summary>
422        /// <param name="paikka">X ja Y oltava kokonaislukuja</param>
423        /// <returns>true, jos paikka on tyhjä</returns>
424        bool OnkoTyhja(Vector paikka)
425        {
426            if (paikka.X > leveys-1 || paikka.X < 0) return false;
427            if (paikka.Y > korkeus-1 || paikka.Y < 0) return false;
428
429            if (pelikentta[(int)paikka.Y][(int)paikka.X].Color == Color.TransparentWhite) return true;
430            return false;
431        }
432
433        /// <summary>
434        /// Värittää paikkaa vastaavat laatikot annetulla värillä
435        /// </summary>
436        /// <param name="palikka">Tämän sijainti väritetään</param>
437        /// <param name="vari">Väri, jolla väritetään</param>
438        void PaivitaPalikka(TetrisPalikka palikka, Color vari)
439        {
440            Vector[] sijainnit = palikka.Sijainti();
441
442            for (int i = 0; i < sijainnit.Length; i++)
443            {
444                pelikentta[(int)sijainnit[i].Y][(int)sijainnit[i].X].Color = vari;
445            }
446        }
447
448        /// <summary>
449        /// Luo palikan keskelle ylälaitaa
450        ///
451        /// Tulee antamaan satunnaisen palikan
452        /// </summary>
453        void LuoPalikka()
454        {
455            //Luo uuden palikan ja siirtää ennustuspalikan aktiiviseksi
456            //ennustusPalikka = new TetrisPalikka(leveys / 2);
457            if (aktiivinenPalikka != null)
458            {
459                aktiivinenPalikka = ennustusPalikka;
460            }
461            else 
462            { 
463                aktiivinenPalikka = new TetrisPalikka(leveys / 2); 
464            }
465
466            ennustusPalikka = new TetrisPalikka(leveys / 2);
467
468            AsetaEnnustusnaytto(ennustusPalikka);
469
470            tiputusajastin.Reset();
471
472            Vector[] sijainnit = aktiivinenPalikka.Sijainti();
473            for (int i = 0; i < sijainnit.Length; i++)
474            {
475                if (!OnkoTyhja(sijainnit[i]))
476                {
477                    PeliLoppui();
478                    return;
479                }
480            }
481
482            PaivitaPalikka(aktiivinenPalikka, aktiivinenPalikka.Vari());
483        }
484
485        void AsetaEnnustusnaytto(TetrisPalikka palikka)
486        {
487            for (int i = 0; i < ennustuskentta.Length; i++)
488            {
489                for (int j = 0; j < ennustuskentta[i].Length; j++)
490                {
491                    ennustuskentta[i][j].Color = Color.TransparentWhite;
492                }
493            }
494
495            Vector[] sijainnit = palikka.Sijainti();
496            int offset = -(leveys / 2) + 1;
497
498            foreach (Vector paikka in sijainnit)
499            {
500                ennustuskentta[(int)paikka.Y ][(int)paikka.X + offset].Color = palikka.Vari();
501            }
502        }
503
504        /// <summary>
505        /// Lopettaa pelin.
506        /// - Palikkoja ei tipu
507        /// - Poistaa vanhat kontrollit
508        /// - Asettaa menunapit toimintaan
509        /// </summary>
510        void PeliLoppui()
511        {
512            tiputusajastin.Stop();
513            ClearControls();
514            AsetaMenuNappaimet();
515        }
516
517    }
518}
Note: See TracBrowser for help on using the repository browser.