source: 2010/30/tekrjant/Seikkailu/Peli.cs @ 1543

Revision 1543, 14.6 KB checked in by tekrjant, 10 years ago (diff)

Luola.

Line 
1#region MIT License
2/*
3 * Copyright (c) 2010 Tero Jäntti.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23#endregion
24
25using System;
26using System.Collections.Generic;
27using Jypeli;
28using Jypeli.Widgets;
29using Jypeli.Effects;
30using Physics2DDotNet.Ignorers;
31
32
33public class Peli : PhysicsGame
34{
35    const double PelaajanNopeus = 2.0;
36    const double PelaajanKulmanopeus = 3.0;
37
38    List<GameObject> ruohot = new List<GameObject>();
39
40    Timer energiaAmpumisAjastin = new Timer() { Interval = 0.1 };
41    ObjectIgnorer energiaIgnorer = new ObjectIgnorer();
42
43    EsineRuutu esineRuutu;
44    EsineValikko esineValikko;
45
46    PhysicsObject pelaaja;
47    Esine viimeksiKoskettuEsine;
48
49    Image[] ottiaisenKuvat = LoadImages( "ottiainen1", "ottiainen2", "ottiainen3", "ottiainen4" );
50    Image[] ottiaisenSyomisKuvat = LoadImages(
51        "ottiainen_syo1", "ottiainen_syo2", "ottiainen_syo3", "ottiainen_syo4",
52        "ottiainen_syo5", "ottiainen_syo6", "ottiainen_syo7", "ottiainen_syo8" );
53    Image ottiainenKuollutKuva = LoadImage( "ottiainen_kuollut" );
54    Image ottiainenPalanutKuva = LoadImage( "ottiainen_palanut" );
55    Image liekinKuva = LoadImage( "liekki" );
56    Image ruohoTekstuuri = LoadImage( "ruoho" );
57    Image lyhdynKuva = LoadImage( "lyhty" );
58    Image timantinKuva = LoadImage( "timantti" );
59    Image taikasauvanKuva = LoadImage( "taikasauva" );
60    Image taikasauva2Kuva = LoadImage( "taikasauva2" );
61    Image[] energiaKuvat = LoadImages( "energia1", "energia2", "energia3", "energia4" );
62
63    Lieska tuliJaLeimaus;
64    Light lyhdynValo;
65
66    Timer lyhtyAjastin;
67
68    const double ruudunLeveys = 5;
69    const double ruudunKorkeus = 5;
70
71    const int MaanTaso = 0;
72    const int TavaraTaso = 1;
73    const int OtusTaso = 2;
74
75
76    protected override void Begin()
77    {
78        LuoKentta();
79        LuoHUD();
80        AsetaOhjaimet();
81    }
82
83    void LuoHUD()
84    {
85        esineRuutu = new EsineRuutu( 200, 50 );
86        esineRuutu.X = Screen.Center.X + Screen.Width / 4;
87        esineRuutu.Y = Screen.Top - esineRuutu.Height / 2;
88        Add( esineRuutu );
89
90        esineValikko = new EsineValikko( 100, 100 );
91        esineValikko.X = 0;
92        esineValikko.Y = Screen.Bottom + esineValikko.Height / 2;
93        Add( esineValikko );
94    }
95
96    void LuoKentta()
97    {
98        ClearAll();
99        Level.BackgroundColor = Color.DarkGreen;
100        Level.Width = 20;
101        Level.Height = 20;
102
103        TileMap kartta = TileMap.FromFile( "kentat\\luola1.txt" );
104        kartta['#'] = LuoSeina;
105        kartta['.'] = LuoLattia;
106        kartta['\''] = LuoRuoho;
107        kartta.Insert( ruudunLeveys, ruudunKorkeus );
108
109        Level.AmbientLight = 0.2;
110        lyhdynValo = new Light();
111        lyhdynValo.Intensity = 0.0;
112        Add( lyhdynValo );
113
114        lyhtyAjastin = new Timer();
115        lyhtyAjastin.Interval = 0.1;
116        lyhtyAjastin.Trigger += PaivitaLyhtya;
117
118        energiaAmpumisAjastin.Trigger += AmmuEnergiaPallo;
119
120        tuliJaLeimaus = new Lieska( liekinKuva );
121        Add( tuliJaLeimaus );
122
123        PhysicsObject vasenSeina = Level.CreateLeftBorder();
124        PhysicsObject oikeaSeina = Level.CreateRightBorder();
125        PhysicsObject ylaSeina = Level.CreateTopBorder();
126        PhysicsObject alaSeina = Level.CreateBottomBorder();
127
128        //for ( int i = 0; i < 100; i++ )
129        //{
130        //    PhysicsObject omena = new PhysicsObject( 0.1, 0.1, Shapes.Circle );
131        //    omena.Tag = "ruoka";
132        //    omena.IgnoresCollisionResponse = true;
133        //    omena.X = RandomGen.NextDouble( Level.Left, Level.Right );
134        //    omena.Y = RandomGen.NextDouble( Level.Bottom, Level.Top );
135        //    omena.Color = Color.Red;
136        //    Add( omena, TavaraTaso );
137        //}
138
139        Esine taikasauva = new Esine( 0.8, 0.1, Shapes.Rectangle, EsineenTyyppi.TuliSauva );
140        taikasauva.Image = taikasauvanKuva;
141        taikasauva.X = 2;
142        taikasauva.Y = 0;
143        Add( taikasauva, TavaraTaso );
144
145        Esine energiaSauva = new Esine( 0.8, 0.1, Shapes.Rectangle, EsineenTyyppi.EnergiaSauva );
146        energiaSauva.Image = taikasauva2Kuva;
147        energiaSauva.X = -1;
148        energiaSauva.Y = -1;
149        Add( energiaSauva, TavaraTaso );
150
151        Esine lyhty = new Esine( 0.6, 0.6, Shapes.Circle, EsineenTyyppi.Lyhty );
152        lyhty.Image = lyhdynKuva;
153        lyhty.X = 2;
154        lyhty.Y = -1;
155        Add( lyhty, TavaraTaso );
156
157        pelaaja = new PhysicsObject( 0.8, 0.8, Shapes.Circle );
158        pelaaja.Color = Color.Blue;
159        pelaaja.Mass = 80;
160        pelaaja.LinearDamping = 0.96;
161        pelaaja.AngularDamping = 0.96;
162        Add( pelaaja, OtusTaso );
163
164        AddCollisionHandler( pelaaja, PelaajaOsuu );
165
166        GameObject suuntaTikku = new GameObject( 0.2, 0.1 );
167        suuntaTikku.Color = Color.Green;
168        suuntaTikku.X = 0.5;
169        pelaaja.Add( suuntaTikku );
170
171        foreach ( GameObject ruoho in ruohot )
172        {
173            Otus otti = LuoOttiainen();
174            otti.X = ruoho.X + RandomGen.NextDouble( -ruudunLeveys / 2, ruudunLeveys / 2 );
175            otti.Y = ruoho.Y + RandomGen.NextDouble( -ruudunKorkeus / 2, ruudunKorkeus / 2 );
176        }
177
178        Esine timantti = new Esine( 0.3, 0.3, Shapes.Circle, EsineenTyyppi.Timantti );
179        timantti.X = RandomGen.NextDouble( Level.Left, Level.Right );
180        timantti.Y = RandomGen.NextDouble( Level.Bottom, Level.Top );
181        timantti.Image = timantinKuva;
182        Add( timantti, TavaraTaso );
183
184        Camera.StayInLevel = true;
185        Camera.ZoomFactor = 50.0;
186        Camera.Follow( pelaaja );
187    }
188
189    GameObject LuoRuoho()
190    {
191        GameObject ruoho = new GameObject( ruudunLeveys, ruudunKorkeus );
192        ruoho.Image = ruohoTekstuuri;
193        ruohot.Add( ruoho );
194        return ruoho;
195    }
196
197    GameObject LuoLattia()
198    {
199        GameObject lattia = new GameObject( ruudunLeveys, ruudunKorkeus );
200        lattia.Color = Color.Brown;
201        return lattia;
202    }
203
204    GameObject LuoSeina()
205    {
206        PhysicsObject seina = PhysicsObject.CreateStaticObject( ruudunLeveys, ruudunKorkeus );
207        seina.Color = Color.DarkGray;
208        return seina;
209    }
210
211    void PelaajaOsuu( PhysicsObject pelaaja, PhysicsObject kohde )
212    {
213        if ( kohde is Esine )
214        {
215            viimeksiKoskettuEsine = (Esine)kohde;
216            esineRuutu.Nayta( viimeksiKoskettuEsine );
217        }
218    }
219
220    Otus LuoOttiainen()
221    {
222        Otus ottiainen = new Otus( 0.6, 0.6, new Animation( ottiaisenKuvat[0] ) );
223        ottiainen.Mass = 20;
224        ottiainen.LiikkumisAnimaatio = new Animation( ottiaisenKuvat ) { FPS = 5 };
225        ottiainen.HyokkaysAnimaatio = new Animation( ottiaisenSyomisKuvat ) { FPS = 20 };
226        ottiainen.KuollutKuva = ottiainenKuollutKuva;
227        ottiainen.PalanutKuva = ottiainenPalanutKuva;
228        ottiainen.Angle = RandomGen.NextAngle();
229        Add( ottiainen, OtusTaso );
230        return ottiainen;
231    }
232
233    void PaivitaLyhtya( Timer ajastin )
234    {
235        lyhdynValo.Position = pelaaja.Position;
236        lyhdynValo.Distance = RandomGen.NextDouble( 28, 32 );
237        lyhdynValo.Intensity = RandomGen.NextDouble( 0.8, 1.0 );
238    }
239
240    protected override void Update( Time time )
241    {
242        base.Update( time );
243    }
244
245    void AsetaOhjaimet()
246    {
247        Keyboard.Listen( Key.Escape, ButtonState.Pressed, Exit, null );
248        Keyboard.Listen( Key.F11, ButtonState.Pressed, TogglaaValaistusta, null );
249
250        Keyboard.Listen( Key.Up, ButtonState.Down, Etene, null );
251        Keyboard.Listen( Key.Up, ButtonState.Released, pelaaja.Stop, null );
252
253        Keyboard.Listen( Key.Left, ButtonState.Down, KaannaVasemmalle, null );
254        Keyboard.Listen( Key.Right, ButtonState.Down, KaannaOikealle, null );
255        Keyboard.Listen( Key.Left, ButtonState.Released, EiKaanny, null );
256        Keyboard.Listen( Key.Right, ButtonState.Released, EiKaanny, null );
257
258        Keyboard.Listen( Key.Q, ButtonState.Pressed, esineValikko.Vasemmalle, null );
259        Keyboard.Listen( Key.W, ButtonState.Pressed, esineValikko.Oikealle, null );
260        Keyboard.Listen( Key.Space, ButtonState.Pressed, KaytaValittuaEsinetta, null );
261
262        Keyboard.Listen( Key.P, ButtonState.Pressed, Keraa, null );
263    }
264
265    void TogglaaValaistusta()
266    {
267        if ( Level.AmbientLight < 0.3 )
268        {
269            Level.AmbientLight = 0.9;
270        }
271        else
272        {
273            Level.AmbientLight = 0.2;
274        }
275    }
276
277    void KaytaValittuaEsinetta()
278    {
279        Esine valittu = esineValikko.ValittuEsine;
280        if ( valittu == null )
281            return;
282
283        switch ( valittu.Tyyppi )
284        {
285            case EsineenTyyppi.TuliSauva:
286                KaytaTaikaSauvaa();
287                break;
288            case EsineenTyyppi.EnergiaSauva:
289                energiaAmpumisAjastin.Start( 5 );
290                break;
291            case EsineenTyyppi.Lyhty:
292                KaytaLamppua();
293                break;
294            case EsineenTyyppi.Timantti:
295                break;
296            default:
297                break;
298        }
299    }
300
301    void AmmuEnergiaPallo( Timer ajastin )
302    {
303        PhysicsObject energia = new PhysicsObject( 1, 1, Shapes.Circle );
304        energia.MaximumLifetime = TimeSpan.FromSeconds( 6 );
305        energia.Restitution = 1.5;
306        energia.CollisionIgnorer = energiaIgnorer;
307        AddCollisionHandler( energia, EnergiaPalloOsuu );
308
309        energia.Animation = new Animation( energiaKuvat );
310        energia.Animation.FPS = 20;
311        energia.Animation.Start();
312
313        Angle kulmanVaihtelu = RandomGen.NextAngle( Angle.Degrees( -5 ), Angle.Degrees( 5 ) );
314        Vector suunta = Vector.FromLengthAndAngle( 1, pelaaja.Angle + kulmanVaihtelu );
315        energia.Position = pelaaja.Position + suunta * 1;
316        energia.Velocity = suunta * 3;
317        energia.Angle = pelaaja.Angle;
318        Add( energia, OtusTaso );
319    }
320
321    void EnergiaPalloOsuu( PhysicsObject energia, PhysicsObject kohde )
322    {
323        if ( kohde is Otus )
324        {
325            Otus otus = (Otus)kohde;
326            // TODO: efekti.
327            otus.TeeVahinkoa( 2 );
328        }
329    }
330
331    double Etaisyys( Vector p1, Vector p2 )
332    {
333        double dx = p2.X - p1.X;
334        double dy = p2.Y - p1.Y;
335        return Math.Abs( dx * dx + dy * dy );
336    }
337
338    void Keraa()
339    {
340        if ( viimeksiKoskettuEsine == null )
341            return;
342
343        if ( ( Etaisyys( pelaaja.Position, viimeksiKoskettuEsine.Position ) - pelaaja.Width / 2 - viimeksiKoskettuEsine.Width / 2 ) > 0 )
344            return;
345
346        Remove( viimeksiKoskettuEsine );
347        esineValikko.Add( viimeksiKoskettuEsine );
348
349        switch ( viimeksiKoskettuEsine.Tyyppi )
350        {
351            case EsineenTyyppi.TuliSauva:
352                GameObject klooni = new GameObject( viimeksiKoskettuEsine.Width, viimeksiKoskettuEsine.Height );
353                klooni.Image = viimeksiKoskettuEsine.Image;
354                pelaaja.Add( klooni );
355                klooni.X = pelaaja.Width / 2 + klooni.Width / 4;
356                break;
357            case EsineenTyyppi.Lyhty:
358                break;
359            case EsineenTyyppi.Timantti:
360                Level.AmbientLight = 0.8;
361                MessageBox viesti = new MessageBox(
362                    "Peli läpi!", "Löysit timantin, pimeys poistui maasta. Onneksi olkoon!" );
363                Add( viesti );
364                break;
365            default:
366                break;
367        }
368
369        viimeksiKoskettuEsine = null;
370    }
371
372    void KaytaLamppua()
373    {
374        if ( lyhdynValo.Intensity <= 0.1 )
375        {
376           lyhtyAjastin.Start();
377        }
378        else
379        {
380            lyhtyAjastin.Stop();
381            lyhdynValo.Intensity = 0.0;
382        }
383    }
384
385    void KaytaTaikaSauvaa()
386    {
387        Vector paikka = pelaaja.Position + Vector.FromLengthAndAngle( 1, pelaaja.Angle );
388        tuliJaLeimaus.Suunta = pelaaja.Angle;
389        tuliJaLeimaus.AddEffect( paikka.X, paikka.Y, 40 );
390
391        int sateidenMaara = 5;
392        Angle pieninKulma = pelaaja.Angle + Angle.Degrees( -10 );
393        Angle suurinKulma = pelaaja.Angle + Angle.Degrees( 10 );
394        Angle sateidenVali = ( suurinKulma - pieninKulma ) / sateidenMaara;
395
396        for ( int i = 0; i < sateidenMaara; i++ )
397        {
398            Angle kulma = pieninKulma + i * sateidenVali;
399            Vector suuntaVektori = Vector.FromLengthAndAngle( 1, kulma );
400            RaySegment sadeKuvio = new RaySegment( suuntaVektori * 1.0, suuntaVektori, 5 );
401            PhysicsObject liekinSade = new PhysicsObject( sadeKuvio );
402            liekinSade.MaximumLifetime = TimeSpan.FromSeconds( 0.5 );
403            liekinSade.Position = pelaaja.Position;
404            liekinSade.Color = Color.Red;
405            liekinSade.IsVisible = false;
406            Add( liekinSade, OtusTaso );
407
408            AddCollisionHandler( liekinSade, LiekkiSadeOsuu );
409        }
410    }
411
412    void LiekkiSadeOsuu( PhysicsObject sade, PhysicsObject kohde )
413    {
414        if ( kohde is Otus && kohde != pelaaja )
415        {
416            sade.Destroy();
417            Otus otus = (Otus)kohde;
418            otus.Liekita();
419        }
420    }
421
422    void Etene()
423    {
424        pelaaja.Velocity = Vector.FromLengthAndAngle( PelaajanNopeus, pelaaja.Angle );
425    }
426
427    void KaannaVasemmalle()
428    {
429        pelaaja.AngularVelocity = PelaajanKulmanopeus;
430    }
431
432    void KaannaOikealle()
433    {
434        pelaaja.AngularVelocity = -PelaajanKulmanopeus;
435    }
436
437    void EiKaanny()
438    {
439        pelaaja.AngularVelocity = 0;
440    }
441}
Note: See TracBrowser for help on using the repository browser.