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

Revision 1484, 14.3 KB checked in by hniemi, 10 years ago (diff)

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