source: 2013/30/MiskaK/MW2(My Warfare 2)/MW2(My Warfare 2)/MW2(My Warfare 2)/MW2_My_Warfare_2_.cs @ 4507

Revision 4507, 106.5 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1// MY WARFARE 2
2// ohjelmointi: Miska Kananen
3// tekstuurit: Miska Kananen, Leevi Kujanpää, Kalle Pienmäki
4// musiikit: Kalle Pienmäki
5
6using System;
7using System.Collections.Generic;
8using System.Text;
9using Jypeli;
10using Jypeli.Assets;
11using Jypeli.Controls;
12using Jypeli.Effects;
13using Jypeli.Widgets;
14using XnaPathfidingLibrary;
15using My_Warfare_2_Server;
16
17/// @author Miska Kananen
18/// @version 22.6.2013
19///
20/// <summary>
21/// My Warfare 2:n pääluokka. Peli toimii tämän luokan sisällä.
22/// </summary>
23public class MW2_My_Warfare_2_ : PhysicsGame
24{
25    #region attribuutit, kuvat ja äänet
26    #region peliattribuutit
27
28    public static MW2_My_Warfare_2_ Peli { get; private set; }
29    public Pelaaja[] pelaajat = new Pelaaja[Vakiot.PELAAJIEN_MAARA];
30    private List<GameObject> tehosteet = new List<GameObject>();
31    public GameObject[,] Kentta { get; set; }
32    private String ValittuKenttaTiedosto { get; set; }
33    private Timer AikaKentanAlusta = new Timer();
34
35    /// <summary>
36    /// Onko klassinen vai satunnainen kenttä.
37    /// </summary>
38    private bool OnkoSatunnaisKentta = false;
39
40    /// <summary>
41    /// Monestako taposta voittaa pelin.
42    /// </summary>
43    public static IntMeter MonestakoVoittaa = new IntMeter(Int32.MaxValue);
44
45    // Tämä attribuuttikönttä POIS
46    Label ammusmittariNäyttö;
47    Label ammusmittariNäyttö2;
48    // -------------------
49
50    static readonly SoundEffect aseTyhjäAani = LoadSoundEffect("dry-fire-gun");
51    static readonly SoundEffect aseLatausAani = LoadSoundEffect("Pump Shotgun");
52    static readonly SoundEffect lippaanPoistoAani = LoadSoundEffect("clip-remove");
53    static readonly SoundEffect hylsynPutoamisAani = LoadSoundEffect("gun_shell_drop");
54    static readonly SoundEffect luotiOsuu = LoadSoundEffect("bullet_hit");
55    static readonly SoundEffect luotiOsuu2 = LoadSoundEffect("bullet_hit2");
56    static readonly SoundEffect luotiOsuu3 = LoadSoundEffect("bullet_hit3");
57    static readonly SoundEffect luotiOsuu4 = LoadSoundEffect("bullet_hit4");
58    static readonly SoundEffect luotiOsuu5 = LoadSoundEffect("bullet_hit5");
59    public static readonly SoundEffect osuma1 = LoadSoundEffect("hit_1");
60
61    private Light valo = new Light();
62    #endregion
63
64    #region Kuvat
65
66    #region asekuvat
67    static readonly Image kranaatinKuva = LoadImage("Kranaatti_F1");
68    static readonly Image pistoolinMaaKuva = LoadImage("GLOCK18_maa");
69    static readonly Image rynkynMaaKuva = LoadImage("AK-74M_maa");
70    static readonly Image pumpparinMaaKuva = LoadImage("REMINGTON870_maa");
71    static readonly Image sawinMaaKuva = LoadImage("M249SAW_maa");
72    static readonly Image singonMaaKuva = LoadImage("RPG-7_maa");
73    static readonly Image snipanMaaKuva = LoadImage("SVDDRAGUNOV_maa");
74    static readonly Image kranaatinMaaKuva = LoadImage("F1FRAG_maa");
75    static readonly Image magnuminMaaKuva = LoadImage("Magnum_maa");
76    #endregion
77
78    #region kentänkuvat
79    // Kentän osat
80    static readonly Image valikonKuva = LoadImage("valikkotausta");
81    static readonly Image valikonPainikeKuva = LoadImage("menu_buttontest");
82    static GameObject menuGradient;
83    static readonly Image kivenKuva = LoadImage("kivi");
84    static readonly Image piikkilankaKuva = LoadImage("piikkilanka");
85    static readonly Image pystypiikkilankaKuva = LoadImage("piikkilankapysty");
86    static readonly Image vaakapuunKuva = LoadImage("puuvaaka");
87    static readonly Image naamioverkonKuva = LoadImage("naamioverkko");
88    static readonly Image pystypuunKuva = LoadImage("puupysty");
89    static readonly Image bussinkuva = LoadImage("bussi");
90    static readonly Image poistuvanseinänKuva = LoadImage("poistuvaseinä");
91    static readonly Image crack1 = LoadImage("crack1");
92    static readonly Image kiviRikki0 = LoadImage("kivirikki0");
93    static readonly Image kiviRikki1 = LoadImage("kivirikki1");
94    static readonly Image kiviRikki2 = LoadImage("kivirikki2");
95    static readonly Image kiviRikki3 = LoadImage("kivirikki3");
96    static readonly Image pystypuuRikki1 = LoadImage("puupystyrikki1");
97    static readonly Image pystypuuRikki2 = LoadImage("puupystyrikki2");
98    static readonly Image edustanKuva = LoadImage("edusta1");
99    static readonly Image seinäSoihdunKuva = LoadImage("seinäsoihtu");
100    static readonly Image valonKuva = LoadImage("valo1");
101    static readonly Image tynnyrinKuva = LoadImage("tynnyri");
102    static readonly Image killballPohja = LoadImage("killball_pohja");
103    static readonly Image killballKeski = LoadImage("killball_keski");
104    static readonly Image killballYla = LoadImage("killball_ylä");
105
106    static readonly Image hudKuva = LoadImage("hudtausta");
107    static readonly Image hudTäysi = LoadImage("hudtaustatäysi");
108    static readonly Image hudKuva2 = LoadImage("hudtausta2");
109    static readonly Image hudTäysi2 = LoadImage("hudtaustatäysi2");
110
111    static readonly Image laatikonKuva = LoadImage("kamaa");
112    static readonly Image laatikkoTyhjä = LoadImage("kamaatyhjä");
113    static readonly Image kamaaNäkymätön = LoadImage("kamaanäkymätön");
114    static readonly Image tyhjä = LoadImage("tyhjä");
115    static readonly Image[] laatikonAnimaatioKuvat = LoadImages("kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa", "kamaa1", "kamaa2", "kamaa3", "kamaa4");
116
117    static readonly Image zombinKuva = LoadImage("zombi");
118    static readonly Image[] zombinKuvat = LoadImages("zombi1", "zombi2", "zombi1", "zombi3");
119    static readonly Image korpinKuva = LoadImage("korppitesti");
120    #endregion
121
122    #region infinitekuvat
123    static readonly Image normaaliZombiKuva = LoadImage("zombi_tavallinen");
124    static readonly Image ampuvaZombiKuva = LoadImage("zombi_ak");
125    static readonly Image[] parasiittienKuvat = LoadImages("Parasiitti1", "Parasiitti2", "Parasiitti3");
126    static readonly Image[] parasiittienPartikkeliKuvat = LoadImages("paras_sirpale1", "paras_sirpale2", "paras_sirpale3", "paras_sirpale4", "paras_sirpale5");
127    #endregion
128
129    #endregion
130
131    #endregion
132
133    #region yleiset toiminnot
134
135    /// <summary>
136    /// Aloitetaan peli luomalla alkuvalikko.
137    /// </summary>
138    public override void Begin()
139    {
140        SoitaMusiikkia(0); // valikkotheme valikkoon
141        LuoAlkuValikko();
142    }
143
144    /// <summary>
145    /// Päivitetään pelaajiin liittyviä asioita.
146    /// </summary>
147    /// <param name="time">Aika pelin alusta ja edellisestä päivityksestä.</param>
148    protected override void Update(Time time)
149    {
150        base.Update(time);
151
152        // Päivitetään pelaajiin liittyviä juttuja.
153        for (int i = 0; i < pelaajat.Length; i++)
154        {
155            if (pelaajat[i] != null)
156            {
157                Vector suunta = (pelaajat[i].tahtain.Position - pelaajat[i].Position).Normalize();
158                pelaajat[i].Angle = suunta.Angle;
159
160                pelaajat[i].elamaPalkki.Position = new Vector(pelaajat[i].X, pelaajat[i].Y + 30);
161                pelaajat[i].infoRuutu.Position = new Vector(pelaajat[i].X, pelaajat[i].Y + 50);
162
163                // Tarkistetaan, ovatko pelaajat sallitun pelialueen ulkopuolella. Ei tarvita kentillä, joissa on piikkilangat reunoina.
164                if (OnkoSatunnaisKentta)
165                {
166                    if (pelaajat[i].Position.X > Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA || pelaajat[i].Position.Y > Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA)
167                    {
168                        pelaajat[i].infoRuutu.Text = String.Format("Palaa taistelukentälle {0:0.00} sekunnin sisällä.", pelaajat[i].aikaPoissaKentalta.Value);
169                        if (pelaajat[i].OllaankoPoissaKentalta == false) pelaajat[i].PoistuttiinKentalta();
170                    }
171                    else if (pelaajat[i].Position.X < Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA || pelaajat[i].Position.Y < Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA)
172                    {
173                        pelaajat[i].infoRuutu.Text = String.Format("Palaa taistelukentälle {0:0.00} sekunnin sisällä.", pelaajat[i].aikaPoissaKentalta.Value);
174                        if (pelaajat[i].OllaankoPoissaKentalta == false) pelaajat[i].PoistuttiinKentalta();
175                    }
176                    else
177                    {
178                        if (pelaajat[i].OllaankoPoissaKentalta == true)
179                        {
180                            pelaajat[i].infoRuutu.Text = "";
181                            pelaajat[i].PalattiinKentalle();
182                        }
183                    }
184                }
185            }
186        }
187    }
188
189    /// <summary>
190    /// Tehdään vahinkoa kohteelle.
191    /// </summary>
192    /// <param name="damagenKohde">Kohde, jota vahingoitetaan.</param>
193    /// <param name="damagenMäärä">Paljonko vahinkoa tehdään.</param>
194    void Damagea(Elava damagenKohde, double damagenMäärä)
195    {
196        damagenKohde.Elamat.Value -= damagenMäärä;
197        GameObject[] effects = Blood.AddNormalBlood(damagenKohde.Position, 3, 0.3);
198        foreach (GameObject blood in effects)
199        {
200            LisaaTehosteObjekti(blood);
201        }
202    }
203
204    /// <summary>
205    /// Tehdään vahinkoa kohteelle.
206    /// </summary>
207    /// <param name="damagenKohde">Kohde, jota vahingoitetaan.</param>
208    /// <param name="damagenMäärä">Paljonko vahinkoa tehdään.</param>
209    void Damagea(Tuhoutuva damagenKohde, double damagenMaara)
210    {
211        damagenKohde.Kesto.Value -= damagenMaara;
212    }
213
214    /// <summary>
215    /// Aloittaa pelin alusta ja palaa päävalikkoon. Poistaa kaiken tähän mennessä tehdyn.
216    /// </summary>
217    void PaaValikkoon()
218    {
219        ClearAll();
220        Camera.Reset();
221        Level.AmbientLight = 0.8;
222        SoitaMusiikkia(0); // valikkotheme valikkoon
223        LuoAlkuValikko(true);
224    }
225
226    /// <summary>
227    /// Kutsutaan, kun toinen pelaaja voittaa pelin.
228    /// </summary>
229    /// <param name="voittanutPelaaja">Pelaaja, joka voitti pelin.</param>
230    void Voitto(Pelaaja voittanutPelaaja)
231    {
232        // MediaPlayer.Play("EPIC VICTORY THEME SONG");
233        PimennaRuutua();
234        MultiSelectWindow voittoIkkuna = new MultiSelectWindow("Pelaaja " + voittanutPelaaja.Numero + " voitti pelin!\n\n" +
235            "Pelaajan 1 tapot: " + pelaajat[0].Tapot + "\n" +
236            "Pelaajan 2 tapot: " + pelaajat[1].Tapot, Color.White, "Päävalikkoon", "Lopeta peli");
237        voittoIkkuna.ItemSelected += delegate(int valinta)
238        {
239            switch (valinta)
240            {
241                case 0:
242                    PaaValikkoon();
243                    break;
244                case 1:
245                    Exit();
246                    break;
247            }
248        };
249        voittoIkkuna.Color = Color.Transparent;
250        voittoIkkuna.BorderColor = Color.Transparent;
251        voittoIkkuna.SelectionColor = Color.Green;
252        voittoIkkuna.DefaultCancel = 0;
253        voittoIkkuna.IsModal = true;
254        Add(voittoIkkuna);
255    }
256
257    /// <summary>
258    /// Kutsutaan, kun Infinite hävitään.
259    /// </summary>
260    /// <param name="havittyPeli">Peli, joka on hävitty.</param>
261    void InfiniteHavio(Infinite havittyPeli)
262    {
263        MediaPlayer.Play("ZombieGameOverFIX");
264        PimennaRuutua();
265        MultiSelectWindow havioIkkuna = new MultiSelectWindow("Peli päättyi!\nVihollisia tapettu " + havittyPeli.VihollisiaTapettu + " kpl.\nAikaa kului " + String.Format("{0:00}", havittyPeli.AikaPelinAlusta.CurrentTime) + " sekuntia.", Color.White, "Päävalikkoon", "Lopeta peli");
266        havioIkkuna.ItemSelected += delegate(int valinta)
267        {
268            switch (valinta)
269            {
270                case 0:
271                    PaaValikkoon();
272                    Infinite.OnkoPeliKaynnissa = false;
273                    break;
274                case 1:
275                    Infinite.OnkoPeliKaynnissa = false;
276                    Exit();
277                    break;
278            }
279        };
280        havioIkkuna.Color = Color.Transparent;
281        havioIkkuna.BorderColor = Color.Transparent;
282        havioIkkuna.SelectionColor = Color.Green;
283        havioIkkuna.DefaultCancel = 0;
284        havioIkkuna.IsModal = true;
285        Add(havioIkkuna);
286
287        havittyPeli.SpawnataankoVihollisia = false;
288
289        foreach (Pelaaja p in pelaajat)
290        {
291            if (p != null && p.Taskulamppu != null) p.Taskulamppu.Destroy();
292        }
293
294        foreach (Vihollinen vihu in havittyPeli.VihollisetKentalla)
295        {
296            vihu.Destroy();
297        }
298    }
299
300    /// <summary>
301    /// Asettaa ikkunan koon halutuksi ja palaa päävalikkoon.
302    /// </summary>
303    /// <param name="leveys">Ikkunan leveys.</param>
304    /// <param name="korkeus">Ikkunan korkeus.</param>
305    void AsetaIkkunanKoko(int leveys, int korkeus)
306    {
307        SetWindowSize(leveys, korkeus);
308        PaaValikkoon();
309    }
310
311    /// <summary>
312    /// Pimennetään ruutua pikku hiljaa.
313    /// </summary>
314    void PimennaRuutua()
315    {
316        Timer ajastin = new Timer();
317        ajastin.Interval = 0.1;
318        ajastin.Timeout += delegate { Level.AmbientLight -= 0.01; };
319        ajastin.Start();
320    }
321
322    /// <summary>
323    /// Soitetaan musiikkia.
324    /// 0:Menu Background Theme
325    /// 1:Dark Lurk
326    /// 2:Zombin taustamusiikki
327    /// 3:OrcsCome
328    /// 4:OrcsCome Special
329    /// 5:MoozE-Radwind
330    /// </summary>
331    /// <param name="valinta">Mikä biisi soitetaan.</param>
332    void SoitaMusiikkia(int valinta)
333    {
334        MediaPlayer.IsRepeating = true;
335        switch (valinta)
336        {
337            case 0:
338                MediaPlayer.Play("Menu_BackGround");
339                break;
340            case 1:
341                MediaPlayer.Play("DarkLurk");
342                break;
343            case 2:
344                MediaPlayer.Play("zombi_taustamusa_1");
345                break;
346            case 3:
347                MediaPlayer.Play("OrcsCome");
348                break;
349            case 4:
350                MediaPlayer.Play("OrcsCome_special");
351                break;
352            case 5:
353                MediaPlayer.Play("03 MoozE - Radwind Pt1");
354                break;
355        }
356    }
357
358    /// <summary>
359    /// Piirretään valojuovia.
360    /// </summary>
361    /// <param name="position">Valojuovan tämänhetkinen sijainti.</param>
362    /// <param name="color">Valojuovan väri.</param>
363    /// <param name="lifetimeInSeconds">Kauanko valojuova pysyy kentällä.</param>
364    void DrawTracers(Vector position, Color color, double lifetimeInSeconds, double brightnessFactor)
365    {
366        color.AlphaComponent = (byte)(32 * brightnessFactor); // 64 toimii
367        GameObject tracer = new GameObject(2, 2);
368        tracer.Shape = Shape.Circle;
369        tracer.Color = color;
370        tracer.Position = position;
371        tracer.MaximumLifetime = TimeSpan.FromSeconds(lifetimeInSeconds);
372        Add(tracer);
373    }
374
375    /// <summary>
376    /// Piirretään valojuovia.
377    /// </summary>
378    /// <param name="tracingObject">Olio, josta valojuovat tulevat.</param>
379    /// <param name="color">Valojuovan väri.</param>
380    /// <param name="lifetimeInSeconds">Kauanko valojuova pysyy kentällä.</param>
381    /// <param name="brightnessFactor">Valojuovan kirkkaus.</param>
382    void DrawTracers(PhysicsObject tracingObject, Color color, double lifetimeInSeconds, double brightnessFactor)
383    {
384        color.AlphaComponent = (byte)(32 * brightnessFactor); // 64 toimii
385        GameObject tracer = new GameObject(60, 2);
386        tracer.Shape = Shape.Circle;
387        tracer.Color = color;
388        tracer.Position = tracingObject.Position;
389        tracer.Angle = tracingObject.Angle;
390        tracer.MaximumLifetime = TimeSpan.FromSeconds(lifetimeInSeconds);
391        Add(tracer);
392    }
393
394    void LisaaTehosteObjekti(GameObject tehoste)
395    {
396        tehosteet.Add(tehoste);
397        if (tehosteet.Count > Vakiot.TEHOSTEOBJEKTIEN_MAX_MAARA)
398        {
399            tehosteet[0].Destroy();
400            tehosteet.RemoveAt(0);
401        }
402
403    }
404
405    #endregion
406
407    #region kenttä
408
409    /// <summary>
410    /// Luodaan kenttä ja kaikki siihen liittyvä, kuten pelaajat.
411    /// </summary>
412    /// <param name="kenttaTyyppi">Kentän luomistapa. 0: kenttä kuvasta, 1: satunnaisgeneroitu kenttä, 2: tyhjä kenttä.</param>
413    /// <param name="pelaajienMaara">Montako pelaajaa peliin tulee.</param>
414    void LuoKentta(int kenttaTyyppi, int pelaajienMaara, bool onkoInfinite)
415    {
416        Mouse.IsCursorVisible = false;
417        bool onkoSandbox = false;
418        AikaKentanAlusta.Reset();
419        AikaKentanAlusta.Start();
420        MessageDisplay.BackgroundColor = Color.Transparent;
421        MessageDisplay.TextColor = Color.White;
422        MessageDisplay.MessageTime = TimeSpan.FromSeconds(1.5);
423        Level.Size = new Vector(Vakiot.KENTAN_LEVEYS * Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_KORKEUS * Vakiot.KENTAN_RUUDUN_KORKEUS);
424        Level.AmbientLight = 0.8;
425        Add(valo);
426        menuGradient.Destroy();
427        menuGradient = null;
428
429        Vector pelaajan1spawni = new Vector(-700.0, 0.0);
430        Vector pelaajan2spawni = new Vector(700.0, 0.0);
431        List<Vector> vaihtoehtoisetSpawnit = new List<Vector>();
432        switch (kenttaTyyppi)
433        {
434            case 0:
435                ColorTileMap ruudut = ColorTileMap.FromLevelAsset(ValittuKenttaTiedosto);
436                Kentta = new GameObject[ruudut.ColumnCount, ruudut.RowCount];
437                ruudut.SetTileMethod(Color.Black, LuoKentanOsa, piikkilankaKuva, "piikkilanka", 5);
438                ruudut.SetTileMethod(Color.Gray, LuoTuhoutuvaKentanOsa, kivenKuva, "kivi", 20, 1.0, 1.0);
439                ruudut.SetTileMethod(Color.DarkRed, LuoLapiMentavaKentanOsa, kivenKuva, "valekivi", 1.0, 1.0);
440                ruudut.SetTileMethod(Color.Orange, LuoTuhoutuvaKentanOsa, pystypuunKuva, "puu", 10, 0.3, 1.0);
441                ruudut.SetTileMethod(Color.Red, LuoKentanOsa, pystypiikkilankaKuva, "piikkilanka", 5);
442                ruudut.SetTileMethod(Color.Brown, LuoTuhoutuvaKentanOsa, vaakapuunKuva, "puu", 10, 1.0, 0.3);
443                ruudut.SetTileMethod(Color.ForestGreen, LuoKentanOsa, naamioverkonKuva, "naamioverkko", 1);
444                ruudut.SetTileMethod(Color.Purple, LuoLaatikko);
445                ruudut.SetTileMethod(Color.Yellow, LuoLapiMentavaKentanOsa, seinäSoihdunKuva, "seinäsoihtu", 1.0, 1.0);
446                ruudut.SetTileMethod(Color.Olive, LuoLapiMentavaKentanOsa, valonKuva, "valo", 6.0, 6.0);
447                ruudut.SetTileMethod(Color.Rose, LuoTynnyri);
448                ruudut.SetTileMethod(Color.BloodRed, delegate(Vector p, double w, double h, IntPoint posInLevel) 
449                { 
450                    if (Infinite.CurrentGame != null)
451                        Infinite.CurrentGame.LisaaFixedSpawni(p);
452                });
453                ruudut.SetTileMethod(Color.BrightGreen, delegate(Vector p, double w, double h, IntPoint posInLevel)
454                {
455                    pelaajan1spawni = p;
456                });
457                ruudut.SetTileMethod(Color.Azure, delegate(Vector p, double w, double h, IntPoint posInLevel)
458                {
459                    pelaajan2spawni = p;
460                });
461                ruudut.SetTileMethod(Color.Gold, delegate(Vector p, double w, double h, IntPoint posInLevel) 
462                {
463                    vaihtoehtoisetSpawnit.Add(p);             
464                });
465
466                //ruudut.Optimize(Color.Gray);
467                ruudut.Execute(50, 50);
468                LuoPilvet((onkoInfinite && pelaajienMaara == 1));
469
470                break;
471            case 1:
472                string[] satunnaisKenttäTiedosto = LuoSatunnainenKenttäTiedosto(Vakiot.KENTAN_LEVEYS, Vakiot.KENTAN_KORKEUS);
473                TileMap satunnaisKenttä = TileMap.FromStringArray(satunnaisKenttäTiedosto);
474                satunnaisKenttä.SetTileMethod('1', LuoTuhoutuvaKentanOsa, kivenKuva, "kivi", 20, 1.0, 1.0);
475                satunnaisKenttä.Optimize();
476                satunnaisKenttä.Execute(Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_RUUDUN_KORKEUS);
477
478                string[] pickupTiedosto = LuoSatunnainenPickupTiedosto(satunnaisKenttäTiedosto, Vakiot.PICKUPIEN_MAARA);
479                TileMap pickupit = TileMap.FromStringArray(pickupTiedosto);
480                pickupit.SetTileMethod('1', LuoKerattavaEsine);
481                pickupit.Execute(Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_RUUDUN_KORKEUS);
482                LuoPilvet(false);
483                break;
484            case 2:
485                onkoSandbox = true;
486                break;
487        }
488
489        #region pelaajien spawnaus ja asettelu
490
491        bool kaytetaankoTaskuLamppua = false;
492
493        if (onkoInfinite)
494        {
495            if (pelaajienMaara == 1) kaytetaankoTaskuLamppua = true;
496        }
497
498        pelaajat[0] = LuoPelaaja(pelaajan1spawni, 43.5, 21.75, 1, Aseet.pelaaja1pistooliKuva, Color.Green, AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta, new Vector(Screen.Left + 130, Screen.Top - 70), kaytetaankoTaskuLamppua);
499        Add(pelaajat[0], 1);
500        pelaajat[0].SpawnausPaikat.AddRange(vaihtoehtoisetSpawnit);
501
502        AmmusMittari();
503        pelaajat[1] = LuoPelaaja(pelaajan2spawni, 43.5, 21.75, 2, Aseet.pelaaja2pistooliKuva, Color.Red, AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta, new Vector(Screen.Right - 130, Screen.Top - 70), kaytetaankoTaskuLamppua);
504        pelaajat[1].SpawnausPaikat.AddRange(vaihtoehtoisetSpawnit);
505
506
507        if (!onkoInfinite)
508        {
509            pelaajat[0].Voitti += Voitto;
510            pelaajat[0].Kuoli += delegate { pelaajat[1].Tapot.Value++; };
511            pelaajat[1].Voitti += Voitto;
512            pelaajat[1].Kuoli += delegate { pelaajat[0].Tapot.Value++; };
513        }
514
515        if (pelaajienMaara == 2)
516        {
517            Add(pelaajat[1], 1);
518            pelaajat[1].tahtain.Position = pelaajat[1].Position + new Vector(-200.0, 0.0);
519            Camera.Follow(pelaajat[0], pelaajat[1]);
520            AmmusMittari2();
521        }
522        else
523        {
524            Camera.Zoom(1);
525            Camera.Follow(pelaajat[0]);
526            pelaajat[1].elamaPalkki.IsVisible = false;
527            pelaajat[1].tahtain.IsVisible = false;
528            pelaajat[1].ValittuAseNaytto.IsVisible = false;
529            pelaajat[1].TappojenMaaraNaytto.IsVisible = false;
530        }
531
532        if (onkoSandbox) // laitetaan kaikki aseet, loputtomat ammukset ja loputtomat kranaatit
533        {
534            for (int i = 0; i < pelaajat.Length; i++)
535            {
536                pelaajat[i].LisaaAse(Aseet.LuoRynkky());
537                pelaajat[i].LisaaAse(Aseet.LuoMinigun());
538                pelaajat[i].LisaaAse(Aseet.LuoHaulikko());
539                pelaajat[i].LisaaAse(Aseet.LuoMagnum());
540                pelaajat[i].LisaaAse(Aseet.LuoSnipa());
541                pelaajat[i].LisaaAse(Aseet.LuoSinko());
542                pelaajat[i].LisaaAse(Aseet.LuoVarsijousi());
543                pelaajat[i].LisaaAse(Aseet.LuoOhjus());
544                pelaajat[i].LisaaAse(Aseet.LuoBinaryRifle());
545                pelaajat[i].LisaaAse(Aseet.LuoVintorez());
546                pelaajat[i].LisaaAse(Aseet.LuoAutomaattiHaulikko());
547
548                for (int j = 0; j < pelaajat[i].Aseet.Count; j++)
549                {
550                    pelaajat[i].Aseet[j].Ammo.MaxValue = Int32.MaxValue;
551                    pelaajat[i].Aseet[j].Ammo.Value = Int32.MaxValue;
552                    pelaajat[i].Aseet[j].MaxAmmo.MaxValue = Int32.MaxValue;
553                    pelaajat[i].Aseet[j].MaxAmmo.Value = Int32.MaxValue;
554
555                    pelaajat[i].KranaattienMaara = Int32.MaxValue;
556                }
557                ammusmittariNäyttö.IsVisible = false;
558                if (ammusmittariNäyttö2 != null)
559                    ammusmittariNäyttö2.IsVisible = false;
560            }
561        }
562        #endregion
563
564    }
565
566    /// <summary>
567    /// Luodaan kenttä onlinepelille.
568    /// </summary>
569    /// <param name="pelaajat">Pelaajat pelissä.</param>
570    /// <param name="kenttaTyyppi">Kentän tyyppi. 0: klassinen mäppi, 1: satunnaisgeneroitu mäppi, 2: tyhjä mäppi.</param>
571    void LuoOnlineKentta(List<Player> onlinePelaajat, int kenttaTyyppi)
572    {
573        Level.Background.Image = null;
574        Mouse.IsCursorVisible = false;
575        AikaKentanAlusta.Reset();
576        AikaKentanAlusta.Start();
577        MessageDisplay.BackgroundColor = Color.Transparent;
578        MessageDisplay.TextColor = Color.White;
579        MessageDisplay.MessageTime = TimeSpan.FromSeconds(1.5);
580        Level.Size = new Vector(Vakiot.KENTAN_LEVEYS * Vakiot.KENTAN_RUUDUN_LEVEYS, Vakiot.KENTAN_KORKEUS * Vakiot.KENTAN_RUUDUN_KORKEUS);
581        Level.AmbientLight = 0.8;
582        Add(valo);
583
584        foreach (Player pelaaja in onlinePelaajat)
585        {
586            Pelaaja p = new Pelaaja(43.5, 21.75, false, false);
587            p.Position = pelaaja.Position;
588            p.Angle = pelaaja.Angle;
589            p.Velocity = pelaaja.Velocity;
590            p.Elamat.Value = pelaaja.Health;
591            Add(p);
592            OnlineGame.PhysicalPlayers.Add(p);
593        }
594
595        pelaajat[0] = LuoPelaaja(new Vector(0.0, 0.0), 43.5, 21.75, 1, Aseet.pelaaja1pistooliKuva, Color.Green, AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta, new Vector(Screen.Left + 130, Screen.Top - 70), false); // false = onko taskulamppua
596        Add(pelaajat[0], 1);
597        AmmusMittari();
598        ClearControls();
599        AsetaOhjaimet();
600        SoitaMusiikkia(4); // OrcsCome Special nettipeliin
601    }
602
603    #region satunnaisgeneraatio
604
605    /// <summary>
606    /// Luodaan kentälle kerättävä esine.
607    /// </summary>
608    /// <param name="mikaLuodaan">Mikä esine luodaan, välillä 0..6.
609    /// (0:Pistooli, 1:Rynkky, 2:Haulikko, 3:Minigun, 4:Varsijousi, 5:Snipa, 6:Sinko, 7:Kranaatti)</param>
610    /// <param name="paikka">Paikka, johon esine luodaan.</param>
611    void LuoKerattavaEsine(Vector paikka, double leveys, double korkeus, IntPoint posInLevel)
612    {
613        int mikaLuodaan = RandomGen.NextIntWithProbabilities(0.20, 0.15, 0.10, 0.10, 0.10, 0.10, 0.05, 0.05, 0.15);
614        switch (mikaLuodaan)
615        {
616            // Pistooli
617            case 0:
618                Kerattava pistooli = LuoKerattava(paikka, Aseet.LuoPistooli(), pistoolinMaaKuva, 0.5);
619                pistooli.Kerattiin += JotainKerattiin;
620                Add(pistooli);
621                break;
622
623            // Rynkky
624            case 1:
625                Kerattava rynkky = LuoKerattava(paikka, Aseet.LuoRynkky(), rynkynMaaKuva);
626                rynkky.Kerattiin += JotainKerattiin;
627                Add(rynkky);
628                break;
629
630            // Haulikko
631            case 2:
632                Kerattava haulikko = LuoKerattava(paikka, Aseet.LuoHaulikko(), pumpparinMaaKuva);
633                haulikko.Kerattiin += JotainKerattiin;
634                Add(haulikko);
635                break;
636            case 3:
637                Kerattava magnum = LuoKerattava(paikka, Aseet.LuoMagnum(), magnuminMaaKuva);
638                magnum.Kerattiin += JotainKerattiin;
639                Add(magnum);
640                break;
641
642            // Minigun
643            case 4:
644                Kerattava minigun = LuoKerattava(paikka, Aseet.LuoMinigun(), sawinMaaKuva);
645                minigun.Kerattiin += JotainKerattiin;
646                Add(minigun);
647                break;
648
649            // Varsijousi
650            case 5:
651                /*Kerattava varsijousi = LuoKerattava(paikka, Aseet.LuoVarsijousi(), new Image(512, 512, Color.White));
652                varsijousi.Kerattiin += JotainKerattiin;
653                Add(varsijousi);*/
654                break;
655            // Snipa
656            case 6:
657                Kerattava snipa = LuoKerattava(paikka, Aseet.LuoSnipa(), snipanMaaKuva);
658                snipa.Kerattiin += JotainKerattiin;
659                Add(snipa);
660                break;
661
662            // Sinko
663            case 7:
664                Kerattava sinko = LuoKerattava(paikka, Aseet.LuoSinko(), singonMaaKuva);
665                sinko.Kerattiin += JotainKerattiin;
666                Add(sinko);
667                break;
668
669            case 8:
670                Kerattava kranaatti = LuoKerattava(paikka, 1, kranaatinMaaKuva, 0.8);
671                kranaatti.Kerattiin += JotainKerattiin;
672                Add(kranaatti);
673                break;
674            case 9:
675                /*Kerattava vintorez = LuoKerattava(paikka, Aseet.LuoVintorez(), vintorezMaaKuva);
676                vintorez.Kerattiin += JotainKerattiin;
677                Add(vintorez);*/
678                break;
679        }
680    }
681
682    /// <summary>
683    /// Luodaan kerättävä esine.
684    /// </summary>
685    /// <param name="paikka">Esineen paikka.</param>
686    /// <param name="mitaKerattiin">Mitä esineestä saa.</param>
687    /// <param name="kuva">Esineen kuva. Voi olla null.</param>
688    /// <param name="kuvanKoonMuutosKerroin">Paljonko kuvan kokoa muutetaan piirrettäessä. 1.0 ei tee mitään, suurempi kasvattaa ja pienempi pienentää.</param>
689    /// <returns>Esine.</returns>
690    Kerattava LuoKerattava(Vector paikka, object mitaKerattiin, Image kuva, double kuvanKoonMuutosKerroin = 1.0)
691    {
692        Kerattava k = new Kerattava(kuva.Width / 8 * kuvanKoonMuutosKerroin, kuva.Height / 8 * kuvanKoonMuutosKerroin, mitaKerattiin, paikka);
693        if (kuva != null)
694            k.Image = kuva;
695        return k;
696    }
697
698    /// <summary>
699    /// Kutsutaan, kun pelaaja törmää kerättävään esineeseen.
700    /// </summary>
701    /// <param name="p">Pelaaja, joka törmäsi.</param>
702    /// <param name="keratty">Se, mitä pelaaja sai kerättävästä esineestä.</param>
703    void JotainKerattiin(Pelaaja p, object keratty)
704    {
705        if (keratty is Ase)
706        {
707            Ase a = keratty as Ase;
708            if (!p.OnkoPelaajallaAse(a.Tag.ToString())) p.LisaaAse(a);
709            else
710            {
711                for (int i = 0; i < p.Aseet.Count; i++)
712                {
713                    if (p.Aseet[i].Tag.ToString() == a.Tag.ToString()) p.Aseet[i].MaxAmmo.Value += p.Aseet[i].Ammo.MaxValue; // jos pelaajalla on jo ase, annetaan aseeseen lippaallinen ammuksia
714                }
715            }
716        }
717        if (keratty is Int32)
718        {
719            p.KranaattienMaara++;
720        }
721    }
722
723    /// <summary>
724    /// Luodaan satunnainen String-taulukko nollista ja ykkösistä, jota voidaan käyttää kentän luontiin.
725    /// </summary>
726    /// <param name="leveys">Kentän leveys.</param>
727    /// <param name="korkeus">Kentän korkeus.</param>
728    /// <returns>Kenttä binäärimuodossa.</returns>
729    String[] LuoSatunnainenKenttäTiedosto(int leveys, int korkeus)
730    {
731        const int ARVOTTAVIA_SUKUPOLVIA = 2;
732        int[,] kentanArvot = new int[leveys, korkeus];
733        for (int i = 0; i < kentanArvot.GetLength(0); i++)
734        {
735            for (int j = 0; j < kentanArvot.GetLength(1); j++)
736            {
737                kentanArvot[i, j] = RandomGen.NextIntWithProbabilities(0.1);
738            }
739        }
740        int[,] kenttaLukuina = GameOfLife.ArvoSukupolvia(kentanArvot, leveys, korkeus, ARVOTTAVIA_SUKUPOLVIA);
741        String[] tulos = TaulukkoStringiksi(kenttaLukuina);
742        return tulos;
743    }
744
745    /// <summary>
746    /// Muunnetaan kaksiulotteinen int-taulukko string-taulukoksi.
747    /// </summary>
748    /// <param name="taulukko">Alkuperäinen int-taulukko.</param>
749    /// <returns>Int-taulukko string-taulukkona.</returns>
750    String[] TaulukkoStringiksi(int[,] taulukko)
751    {
752        String[] tulos = new String[taulukko.GetLength(1)];
753        for (int rivi = 0; rivi < taulukko.GetLength(0); rivi++)
754        {
755            for (int sarake = 0; sarake < taulukko.GetLength(1); sarake++)
756            {
757                tulos[rivi] += taulukko[rivi, sarake];
758            }
759        }
760        return tulos;
761    }
762
763    /// <summary>
764    /// Palauttaa string-lukutaulukon muunnettuna 2D-int-taulukoksi. Taulukon rivien pitää
765    /// olla samanpituisia.
766    /// </summary>
767    /// <param name="taulukko">Muunnettava taulukko.</param>
768    /// <returns>Taulukko int-muodossa.<returns>
769    int[,] TaulukkoIntiksi(String[] taulukko)
770    {
771        int[,] tulos = new int[taulukko.Length, taulukko[0].Length];
772        for (int rivi = 0; rivi < taulukko.Length; rivi++)
773        {
774            for (int sarake = 0; sarake < taulukko[0].Length; sarake++)
775            {
776                tulos[rivi, sarake] = int.Parse(taulukko[rivi][sarake].ToString());
777            }
778        }
779        return tulos;
780    }
781
782    /// <summary>
783    /// Muuntaa int-taulukon bool-taulukoksi. Luvusta 0 tulee true, muista false.
784    /// </summary>
785    /// <param name="taulukkoIntina">Muunnettava taulukko.</param>
786    /// <returns>Taulukko boolina.</returns>
787    bool[,] TaulukkoBooliksi(int[,] taulukkoIntina)
788    {
789        bool[,] tulos = new bool[taulukkoIntina.GetLength(0), taulukkoIntina.GetLength(1)];
790        for (int i = 0; i < taulukkoIntina.GetLength(0); i++)
791        {
792            for (int j = 0; j < taulukkoIntina.GetLength(1); j++)
793            {
794                if (taulukkoIntina[i, j] == 0) tulos[i, j] = true;
795                else tulos[i, j] = false;
796            }
797        }
798        return tulos;
799    }
800
801    /// <summary>
802    /// Palauttaa int-taulukon, jonka alkioiden arvot voivat olla VAIN 0 tai 1 käännettynä siten, että alkioiden
803    /// arvot ovat päinvastaiset.
804    /// </summary>
805    /// <param name="taulukko">Käännettävä taulukko.</param>
806    /// <returns>Käännetty taulukko.</returns>
807    int[,] KaannaTaulukko(int[,] taulukko)
808    {
809        for (int i = 0; i < taulukko.GetLength(0); i++)
810        {
811            for (int j = 0; j < taulukko.GetLength(1); j++)
812            {
813                if (taulukko[i, j] == 0) taulukko[i, j] = 1;
814                else taulukko[i, j] = 0;
815            }
816        }
817        return taulukko;
818    }
819
820    /// <summary>
821    /// Palauttaa niiden taulukon alkioiden indeksit, joissa on etsittävä luku.
822    /// </summary>
823    /// <param name="taulukko">Taulukko, josta lukua etsitään.</param>
824    /// <param name="mitäEtsitään">Mitä lukua etsitään.</param>
825    /// <returns>Indeksit vektorilistana.</returns>
826    List<Vector> TaulukonAlkioidenIndeksit(int[,] taulukko, int mitäEtsitään)
827    {
828        List<Vector> indeksit = new List<Vector>();
829        for (int i = 0; i < taulukko.GetLength(0); i++)
830        {
831            for (int j = 0; j < taulukko.GetLength(1); j++)
832            {
833                if (taulukko[i, j] == mitäEtsitään) indeksit.Add(new Vector(i, j));
834            }
835        }
836        return indeksit;
837    }
838
839    /// <summary>
840    /// Luodaan tiedosto pickupien luontia varten siten, ettei pickupeja mene seinien päälle.
841    /// </summary>
842    /// <param name="kentanKiinteatOsat">Kentän seinät.</param>
843    /// <returns>String-taulukko, jossa on pickupien paikat.</returns>
844    String[] LuoSatunnainenPickupTiedosto(String[] kentanKiinteatOsat, int pickupienMaara)
845    {
846        int[,] pickupienPaikat = new int[kentanKiinteatOsat.Length, kentanKiinteatOsat[0].Length];
847
848        // Ne paikat, jotka ovat tyhjiä kenttägeneraation jäljiltä.
849        int[,] pickupienMahdollisetPaikat = TaulukkoIntiksi(kentanKiinteatOsat);
850        pickupienMahdollisetPaikat = KaannaTaulukko(pickupienMahdollisetPaikat);
851        List<Vector> indeksitJoissaOnTyhjää = TaulukonAlkioidenIndeksit(pickupienMahdollisetPaikat, 1);
852
853        for (int i = 0; i < pickupienMaara; i++)
854        {
855            Vector paikka = RandomGen.SelectOne<Vector>(indeksitJoissaOnTyhjää);
856            int x = (int)paikka.X;
857            int y = (int)paikka.Y;
858            pickupienPaikat[x, y] = 1;
859        }
860        String[] pickupienPaikatStringinä = TaulukkoStringiksi(pickupienPaikat);
861        return pickupienPaikatStringinä;
862    }
863    #endregion
864
865    #region kentän osat
866
867    /// <summary>
868    /// Luo staattisen kentän osan, joka voi tuhoutua.
869    /// </summary>
870    /// <param name="paikka">Kappaleen paikka.</param>
871    /// <param name="leveys">Kappaleen leveys.</param>
872    /// <param name="korkeus">Kappaleen korkeus.</param>
873    /// <param name="kuva">Kappaleen kuva.</param>
874    /// <param name="tag">Kappaleen tagi.</param>
875    /// <param name="kesto">Kappaleen kesto.</param>
876    void LuoTuhoutuvaKentanOsa(Vector paikka, double leveys, double korkeus, IntPoint positionInLevelArray, Image kuva, string tag, int kesto, double leveydenKerroin, double korkeudenKerroin)
877    {
878        Tuhoutuva kentanosa = new Tuhoutuva(leveys * leveydenKerroin, korkeus * korkeudenKerroin, kesto);
879        kentanosa.Position = paikka;
880        kentanosa.MakeStatic();
881        kentanosa.Image = kuva;
882        kentanosa.Tag = tag;
883        kentanosa.CollisionIgnoreGroup = 1;
884        kentanosa.Kesto.LowerLimit += delegate {
885            TarkistaNaapurit(kentanosa);
886            kentanosa.Destroy();
887        };
888        kentanosa.PositionInLevelArray = positionInLevelArray;
889        Add(kentanosa);
890        Kentta[positionInLevelArray.X, positionInLevelArray.Y] = kentanosa;
891    }
892
893    /// <summary>
894    /// Luo staattisen kentän osan, joka ei voi tuhoutua.
895    /// </summary>
896    /// <param name="paikka">Kappaleen paikka.</param>
897    /// <param name="leveys">Kappaleen leveys.</param>
898    /// <param name="korkeus">Kappaleen korkeus.</param>
899    /// <param name="kuva">Kappaleen kuva.</param>
900    /// <param name="tag">Kappaleen tagi.</param>
901    /// <param name="collisionIgnoreGroup">Kappaleen törmäysryhmä.</param>
902    void LuoKentanOsa(Vector paikka, double leveys, double korkeus, IntPoint positionInLevelArray, Image kuva, string tag, int collisionIgnoreGroup)
903    {
904        PhysicsObject kentanosa = new PhysicsObject(leveys, korkeus);
905        kentanosa.Position = paikka;
906        kentanosa.MakeStatic();
907        kentanosa.Image = kuva;
908        kentanosa.Tag = tag;
909        kentanosa.CollisionIgnoreGroup = collisionIgnoreGroup;
910        kentanosa.PositionInLevelArray = positionInLevelArray;
911        Add(kentanosa);
912        Kentta[positionInLevelArray.X, positionInLevelArray.Y] = kentanosa;
913    }
914
915    /// <summary>
916    /// Luo liikkumattoman kentän osan, johon ei voi törmätä.
917    /// </summary>
918    /// <param name="paikka">Kappaleen paikka.</param>
919    /// <param name="leveys">Kappaleen leveys.</param>
920    /// <param name="korkeus">Kappaleen korkeus.</param>
921    /// <param name="kuva">Kappaleen kuva.</param>
922    /// <param name="tag">Kappaleen tagi.</param>
923    void LuoLapiMentavaKentanOsa(Vector paikka, double leveys, double korkeus, IntPoint positionInLevelArray, Image kuva, string tag, double leveydenKerroin, double korkeudenKerroin)
924    {
925        GameObject kentanosa = new GameObject(leveys * leveydenKerroin, korkeus * korkeudenKerroin);
926        kentanosa.Image = kuva;
927        kentanosa.Tag = tag;
928        kentanosa.Position = paikka;
929        kentanosa.PositionInLevelArray = positionInLevelArray;
930        Add(kentanosa, 1);
931        Kentta[positionInLevelArray.X, positionInLevelArray.Y] = kentanosa;
932    }
933
934    /// <summary>
935    /// Luodaan liikkuva kentän osa.
936    /// </summary>
937    /// <param name="paikka">Paikka.</param>
938    /// <param name="leveys">Leveys.</param>
939    /// <param name="korkeus">Korkeus.</param>
940    /// <param name="kuva">Kuva.</param>
941    /// <param name="tag">Tagi.</param>
942    /// <param name="shape">Muoto.</param>
943    /// <returns>Kentän osa.</returns>
944    PhysicsObject LuoLiikkuvaKentanOsa(Vector paikka, double leveys, double korkeus, Image kuva, string tag, Shape shape)
945    {
946        PhysicsObject kentanosa = new PhysicsObject(leveys, korkeus);
947        kentanosa.Position = paikka;
948        kentanosa.Tag = tag;
949        if (kuva != null) kentanosa.Image = kuva;
950        kentanosa.Shape = shape;
951        Add(kentanosa);
952        return kentanosa;
953    }
954
955    /// <summary>
956    /// Luodaan räjähtävä tynnyri.
957    /// </summary>
958    /// <param name="paikka">Tynnyrin paikka.</param>
959    /// <param name="leveys">Tynnyrin leveys.</param>
960    /// <param name="korkeus">Tynnyrin korkeus.</param>
961    void LuoTynnyri(Vector paikka, double leveys, double korkeus, IntPoint posInLevel)
962    {
963        Tuhoutuva tynnyri = new Tuhoutuva(leveys / 1.5, korkeus / 1.5, 1);
964        tynnyri.Image = tynnyrinKuva;
965        tynnyri.Position = paikka;
966        tynnyri.Shape = Shape.Circle;
967        //tynnyri.Mass = 600;
968        tynnyri.LinearDamping = 0.90;
969        tynnyri.AngularDamping = 0.90;
970        tynnyri.Angle = RandomGen.NextAngle();
971        tynnyri.Kesto.LowerLimit += delegate
972        {
973            Partikkelit.AddExplosionEffect(tynnyri.Position, 600);
974            //Flame f = Partikkelit.CreateFlames(tynnyri.Position, 30);
975            //Add(f);
976
977            Explosion rajahdys = new Explosion(200);
978            rajahdys.Position = tynnyri.Position;
979            rajahdys.Image = tyhjä;
980            rajahdys.Sound = Aseet.singonAani;
981            rajahdys.Force = 400;
982            rajahdys.Speed = 1000;
983            rajahdys.ShockwaveColor = Color.Black;
984            rajahdys.ShockwaveReachesObject += delegate(IPhysicsObject paineaallonKohde, Vector shokki) { RajahdysOsuu(paineaallonKohde, shokki, tynnyri.Position, Aseet.SINGON_MAKSIMI_DAMAGE); };
985            Add(rajahdys);
986            tynnyri.Destroy();
987        };
988        Add(tynnyri);
989        //tynnyri.Hit(RandomGen.NextVector(100.0, 1000.0));
990    }
991
992    /// <summary>
993    /// Luodaan kentän päälle pilviä, jotka liikkuvat hiljalleen.
994    /// </summary>
995    void LuoPilvet(bool onkoInfinite)
996    {
997        GameObject pilvet = new GameObject(8192, 8192);
998        if (onkoInfinite) pilvet.Image = LoadImage("himmeatpilvet");
999        else pilvet.Image = LoadImage("pilvet2");
1000        pilvet.Tag = "pilvet";
1001        Add(pilvet, 2);
1002        Layers[2].RelativeTransition = new Vector(2.0, 2.0);
1003        RandomMoverBrain rb = new RandomMoverBrain(0.3);
1004        pilvet.Brain = rb;
1005        rb.WanderRadius = 1000;
1006        rb.ChangeMovementSeconds = 10.0;
1007        rb.TurnWhileMoving = false;
1008    }
1009
1010    /// <summary>
1011    /// Luodaan laatikko, josta voi kerätä kamaa.
1012    /// </summary>
1013    /// <param name="paikka">Laatikon paikka.</param>
1014    /// <param name="leveys">Laatikon leveys.</param>
1015    /// <param name="korkeus">Laatikon korkeus.</param>
1016    void LuoLaatikko(Vector paikka, double leveys, double korkeus, IntPoint posInLevel)
1017    {
1018        Laatikko laatikko = new Laatikko(leveys, korkeus);
1019        laatikko.Animation = new Animation(laatikonAnimaatioKuvat);
1020        laatikko.Animation.Start();
1021        laatikko.MakeStatic();
1022        laatikko.Animation.FPS = 10;
1023        laatikko.Position = paikka;
1024        laatikko.Tag = "laatikko";
1025        AddCollisionHandler(laatikko, AnnaKamaa);
1026        Add(laatikko);
1027    }
1028
1029    void LuoKillBall(Vector paikka)
1030    {
1031        PhysicsObject killball = LuoLiikkuvaKentanOsa(paikka, 200.0, 200.0, killballPohja, "killball", Shape.Circle);
1032        killball.AngularDamping = 1.0;
1033        killball.AngularVelocity = 5.0;
1034
1035        PhysicsObject killballKeskiOsa = new PhysicsObject(200.0, 200.0);
1036        killballKeskiOsa.Image = killballKeski;
1037        killballKeskiOsa.MakeStatic();
1038        killballKeskiOsa.Shape = Shape.Circle;
1039        killballKeskiOsa.AngularDamping = 1.0;
1040        killballKeskiOsa.AngularVelocity = -6.0;
1041        killball.Add(killballKeskiOsa);
1042
1043        PhysicsObject killballYlaOsa = new PhysicsObject(200.0, 200.0);
1044        killballYlaOsa.Image = killballYla;
1045        killballYlaOsa.MakeStatic();
1046        killballYlaOsa.Shape = Shape.Circle;
1047        killballYlaOsa.AngularDamping = 1.0;
1048        killballYlaOsa.AngularVelocity = 8.0;
1049        killballKeskiOsa.Add(killballYlaOsa);
1050
1051        AddCollisionHandler<PhysicsObject, Pelaaja>(
1052            killball, delegate(PhysicsObject kb, Pelaaja pelaaja)
1053        {
1054            Damagea(pelaaja, 20);
1055            PlaySound("KillBall_Kill");
1056        });
1057    }
1058
1059    void TarkistaNaapurit(Tuhoutuva t)
1060    {
1061        try
1062        {
1063            if (Kentta[t.PositionInLevelArray.X - 1, t.PositionInLevelArray.Y] is GameObject) MuutaKiinteaksi(t.PositionInLevelArray.X - 1, t.PositionInLevelArray.Y);
1064            if (Kentta[t.PositionInLevelArray.X + 1, t.PositionInLevelArray.Y] is GameObject) MuutaKiinteaksi(t.PositionInLevelArray.X + 1, t.PositionInLevelArray.Y);
1065            if (Kentta[t.PositionInLevelArray.X, t.PositionInLevelArray.Y - 1] is GameObject) MuutaKiinteaksi(t.PositionInLevelArray.X, t.PositionInLevelArray.Y - 1);
1066            if (Kentta[t.PositionInLevelArray.X, t.PositionInLevelArray.Y + 1] is GameObject) MuutaKiinteaksi(t.PositionInLevelArray.X, t.PositionInLevelArray.Y + 1);
1067        }
1068        catch (IndexOutOfRangeException)
1069        {
1070            // ei tehdä mitään
1071        }
1072    }
1073
1074    void MuutaKiinteaksi(int x, int y)
1075    {
1076        GameObject muutettava = Kentta[x, y];
1077
1078        switch (muutettava.Tag.ToString())
1079        {
1080            case "kivi":
1081                LuoTuhoutuvaKentanOsa(muutettava.Position, muutettava.Width, muutettava.Height, muutettava.PositionInLevelArray, muutettava.Image, muutettava.Tag.ToString(), 20, 1.0, 1.0);
1082                muutettava.Destroy();
1083                break;
1084            default:
1085                break;
1086        }
1087    }
1088
1089    #endregion
1090
1091    #endregion
1092
1093    #region valikot
1094    /// <summary>
1095    /// Luodaan pelille alkuvalikko.
1096    /// </summary>
1097    /// <param name="isEverythingCleared">Jos kutsutaan ClearAllin jälkeen.</param>
1098    void LuoAlkuValikko(bool isEverythingCleared = false)
1099    {
1100        MW2_My_Warfare_2_.Peli = this;
1101        AsetustenKaytto.LataaAsetukset();
1102        Infinite.OnkoPeliKaynnissa = false;
1103        AnimatedMultiSelectWindow valikko = new AnimatedMultiSelectWindow("MY WARFARE 2", valikonPainikeKuva,
1104        "Uusi peli", "Multiplayer", "Asetukset", "Lopeta peli");
1105        valikko.ItemSelected += PainettiinAlkuValikonNappia;
1106        valikko.Color = Color.Transparent;
1107        valikko.BorderColor = Color.Transparent;
1108        valikko.MovementSpeed = 450;
1109        Level.Background.Image = valikonKuva;
1110        Level.BackgroundColor = Color.Black;
1111        Level.AmbientLight = 1.0;
1112        valikko.DefaultCancel = 4;
1113        Add(valikko);
1114
1115        if (menuGradient == null || menuGradient.IsDestroyed || !menuGradient.IsAddedToGame || isEverythingCleared) // jos null tai poistettu pelistä tai jos tullaan ClearAllin kautta
1116        {
1117            menuGradient = new GameObject(1920, 1080);
1118            menuGradient.Image = LoadImage("menu_gradient");
1119            Add(menuGradient);
1120        }
1121    }
1122
1123    /// <summary>
1124    /// Alkuvalikon nappien painalluksen käsittely.
1125    /// </summary>
1126    /// <param name="valinta">Painettu nappi.</param>
1127    void PainettiinAlkuValikonNappia(int valinta)
1128    {
1129        switch (valinta)
1130        {
1131            case 0:
1132                LuoPelimuodonValintaValikko();
1133                break;
1134            case 1:
1135                LuoOnlineValikko();
1136                break;
1137            case 2:
1138                LuoAsetusIkkuna();
1139                break;
1140            case 3:
1141                Exit();
1142                break;
1143        }
1144    }
1145
1146    void LuoOnlineValikko()
1147    {
1148        AnimatedMultiSelectWindow onlineValikko = new AnimatedMultiSelectWindow("Valitse pelimuoto", valikonPainikeKuva, "Liity peliin", "Syötä IP", "Syötä portti", "Syötä salasana", "Takaisin");
1149        onlineValikko.ItemSelected += PainettiinOnlineValikonNappia;
1150        onlineValikko.Color = Color.Transparent;
1151        onlineValikko.BorderColor = Color.Transparent;
1152        Level.Background.Image = valikonKuva;
1153        Level.BackgroundColor = Color.Black;
1154        onlineValikko.DefaultCancel = 2;
1155        //onlineValikko.Position = new Vector(0, Screen.Top - 100);
1156        Add(onlineValikko);
1157
1158    }
1159
1160    void PainettiinOnlineValikonNappia(int valinta)
1161    {
1162        switch (valinta)
1163        {
1164            case 0:
1165                OnlineGame.JoinGame(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(OnlineGame.ServerIP.ToString()), OnlineGame.ServerPort));
1166                LuoOnlineKentta(OnlineGame.CurrentGame.ConnectedPlayers, 2);
1167
1168                break;
1169            case 1:
1170                InputWindow ipIkkuna = new InputWindow("Syötä serverin IP:");
1171                ipIkkuna.Color = Color.Transparent;
1172                ipIkkuna.InputBox.BorderColor = Color.Green;
1173                ipIkkuna.InputBox.Cursor.Color = Color.Green;
1174                ipIkkuna.MaxCharacters = 15;
1175                ipIkkuna.OKButton.Clicked += delegate
1176                {
1177                    OnlineGame.ServerIP.Clear();
1178                    OnlineGame.ServerIP.Append(ipIkkuna.InputBox.Text);
1179                    LuoOnlineValikko();
1180                };
1181                Add(ipIkkuna);
1182                break;
1183            case 2:
1184                InputWindow porttiIkkuna = new InputWindow("Syötä serverin portti:");
1185                porttiIkkuna.Color = Color.Transparent;
1186                porttiIkkuna.InputBox.BorderColor = Color.Green;
1187                porttiIkkuna.InputBox.Cursor.Color = Color.Green;
1188                porttiIkkuna.MaxCharacters = 5;
1189                porttiIkkuna.OKButton.Clicked += delegate
1190                {
1191                    OnlineGame.ServerPort = int.Parse(porttiIkkuna.InputBox.Text);
1192                    LuoOnlineValikko();
1193                };
1194                Add(porttiIkkuna);
1195
1196                break;
1197            case 3:
1198                InputWindow salasanaIkkuna = new InputWindow("Syötä serverin portti:");
1199                salasanaIkkuna.Color = Color.Transparent;
1200                salasanaIkkuna.InputBox.BorderColor = Color.Green;
1201                salasanaIkkuna.InputBox.Cursor.Color = Color.Green;
1202                salasanaIkkuna.OKButton.Clicked += delegate
1203                {
1204                    OnlineGame.ServerPassword.Clear();
1205                    OnlineGame.ServerPassword.Append(salasanaIkkuna.InputBox.Text);
1206                    LuoOnlineValikko();
1207                };
1208                Add(salasanaIkkuna);
1209                break;
1210            case 4:
1211                LuoAlkuValikko();
1212                break;
1213        }
1214    }
1215
1216    /// <summary>
1217    /// Asetukset, kuten fullscreen-valinta, antialiasing ja resoluutio.
1218    /// </summary>
1219    void LuoAsetusIkkuna()
1220    {
1221        AsetustenKaytto.LataaAsetukset();
1222        Mouse.IsCursorVisible = true;
1223        MultiSelectWindow paluu = new MultiSelectWindow("Asetukset", "Tallenna ja palaa päävalikkoon", "Palauta oletusasetukset");
1224        paluu.ItemSelected += delegate(int valinta)
1225        {
1226            switch (valinta)
1227            {
1228                case 0:
1229                    AsetustenKaytto.TallennaAsetukset();
1230                    PaaValikkoon();
1231                    break;
1232                case 1:
1233                    AsetustenKaytto.PalautaOletusAsetukset();
1234                    AsetustenKaytto.TallennaAsetukset();
1235                    PaaValikkoon();
1236                    break;
1237            }
1238        };
1239        paluu.Color = Color.Transparent;
1240        paluu.BorderColor = Color.Transparent;
1241        paluu.SelectionColor = Color.Green;
1242        Level.Background.Image = valikonKuva;
1243        Level.BackgroundColor = Color.Black;
1244        paluu.DefaultCancel = 0;
1245        paluu.Position = new Vector(0, Screen.Top - 100);
1246        Add(paluu);
1247
1248        OnOffButton fullscreenNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoFullscreen);
1249        fullscreenNappi.Position = new Vector(0.0, paluu.Y - 100);
1250        Add(fullscreenNappi);
1251        fullscreenNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoFullscreen = fullscreenNappi.IsPressed; this.IsFullScreen = AsetustenKaytto.Asetukset.OnkoFullscreen; };
1252
1253        Label fullscreenTeksti = new Label("Fullscreen:");
1254        fullscreenTeksti.Position = new Vector(fullscreenNappi.X - 100, fullscreenNappi.Y);
1255        Add(fullscreenTeksti);
1256
1257        OnOffButton antialiasingNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoAntialiasing);
1258        antialiasingNappi.Position = new Vector(0.0, fullscreenNappi.Y - 50);
1259        Add(antialiasingNappi);
1260        antialiasingNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoAntialiasing = antialiasingNappi.IsPressed; Game.SmoothTextures = AsetustenKaytto.Asetukset.OnkoAntialiasing; };
1261
1262        Label antialiasingTeksti = new Label("Antialiasing:");
1263        antialiasingTeksti.Position = new Vector(antialiasingNappi.X - 100, antialiasingNappi.Y);
1264        Add(antialiasingTeksti);
1265
1266        Label resoluutiotOtsikko = new Label("Resoluutio:");
1267        resoluutiotOtsikko.Position = new Vector(antialiasingTeksti.X, antialiasingTeksti.Y - 50);
1268        Add(resoluutiotOtsikko);
1269
1270        PushButton resoluutio800x600 = new PushButton(20, 20);
1271        resoluutio800x600.Position = new Vector(100.0, resoluutiotOtsikko.Y - 50);
1272        Add(resoluutio800x600);
1273        resoluutio800x600.Clicked += delegate { AsetaIkkunanKoko(800, 600); };
1274
1275        Label resoluutio800x600Teksti = new Label("800 x 600");
1276        resoluutio800x600Teksti.Position = new Vector(resoluutio800x600.X - 100, resoluutio800x600.Y);
1277        Add(resoluutio800x600Teksti);
1278
1279        PushButton resoluutio1024x768 = new PushButton(20, 20);
1280        resoluutio1024x768.Position = new Vector(100.0, resoluutio800x600.Y - 50);
1281        Add(resoluutio1024x768);
1282        resoluutio1024x768.Clicked += delegate { AsetaIkkunanKoko(1024, 768); };
1283
1284        Label resoluutio1024x768Teksti = new Label("1024 x 768");
1285        resoluutio1024x768Teksti.Position = new Vector(resoluutio1024x768.X - 100, resoluutio1024x768.Y);
1286        Add(resoluutio1024x768Teksti);
1287
1288        PushButton resoluutio1280x1024 = new PushButton(20, 20);
1289        resoluutio1280x1024.Position = new Vector(100.0, resoluutio1024x768.Y - 50);
1290        Add(resoluutio1280x1024);
1291        resoluutio1280x1024.Clicked += delegate { AsetaIkkunanKoko(1280, 1024); };
1292
1293        Label resoluutio1280x1024Teksti = new Label("1280 x 1024");
1294        resoluutio1280x1024Teksti.Position = new Vector(resoluutio1280x1024.X - 100, resoluutio1280x1024.Y);
1295        Add(resoluutio1280x1024Teksti);
1296
1297        PushButton resoluutio1600x1200 = new PushButton(20, 20);
1298        resoluutio1600x1200.Position = new Vector(100.0, resoluutio1280x1024.Y - 50);
1299        Add(resoluutio1600x1200);
1300        resoluutio1600x1200.Clicked += delegate { AsetaIkkunanKoko(1600, 1200); };
1301
1302        Label resoluutio1600x1200Teksti = new Label("1600 x 1200");
1303        resoluutio1600x1200Teksti.Position = new Vector(resoluutio1600x1200.X - 100, resoluutio1600x1200.Y);
1304        Add(resoluutio1600x1200Teksti);
1305
1306        PushButton resoluutio1920x1080 = new PushButton(20, 20);
1307        resoluutio1920x1080.Position = new Vector(100.0, resoluutio1600x1200.Y - 50);
1308        Add(resoluutio1920x1080);
1309        resoluutio1920x1080.Clicked += delegate { AsetaIkkunanKoko(1920, 1080); };
1310
1311        Label resoluutio1920x1080Teksti = new Label("1920 x 1080");
1312        resoluutio1920x1080Teksti.Position = new Vector(resoluutio1920x1080.X - 100, resoluutio1920x1080.Y);
1313        Add(resoluutio1920x1080Teksti);
1314
1315        OnOffButton pelaaja1LaserNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta);
1316        pelaaja1LaserNappi.Position = new Vector(0.0, resoluutio1920x1080.Y - 50);
1317        Add(pelaaja1LaserNappi);
1318        pelaaja1LaserNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta = !AsetustenKaytto.Asetukset.OnkoPelaajalla1Lasertahtainta; };
1319
1320        Label pelaaja1LaserTeksti = new Label("Pelaajan 1 lasertähtäin:");
1321        pelaaja1LaserTeksti.Position = new Vector(pelaaja1LaserNappi.X - 150, pelaaja1LaserNappi.Y);
1322        Add(pelaaja1LaserTeksti);
1323
1324        OnOffButton pelaaja2LaserNappi = new OnOffButton(20, 20, AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta);
1325        pelaaja2LaserNappi.Position = new Vector(0.0, pelaaja1LaserNappi.Y - 50);
1326        Add(pelaaja2LaserNappi);
1327        pelaaja2LaserNappi.Clicked += delegate { AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta = !AsetustenKaytto.Asetukset.OnkoPelaajalla2Lasertahtainta; };
1328
1329        Label pelaaja2LaserTeksti = new Label("Pelaajan 2 lasertähtäin:");
1330        pelaaja2LaserTeksti.Position = new Vector(pelaaja2LaserNappi.X - 150, pelaaja2LaserNappi.Y);
1331        Add(pelaaja2LaserTeksti);
1332
1333        PushButton kayttajaNimiNappi = new PushButton("Muuta");
1334        kayttajaNimiNappi.Color = Color.Green;
1335        kayttajaNimiNappi.Position = new Vector(0.0, pelaaja2LaserNappi.Position.Y - 50);
1336        kayttajaNimiNappi.Clicked += delegate
1337        {
1338            InputWindow kayttajanimiIkkuna = new InputWindow("");
1339            kayttajanimiIkkuna.Color = Color.Transparent;
1340            kayttajanimiIkkuna.InputBox.BorderColor = Color.Green;
1341            kayttajanimiIkkuna.InputBox.Text = AsetustenKaytto.Asetukset.KayttajaNimi;
1342            kayttajanimiIkkuna.InputBox.Cursor.Color = Color.Green;
1343            kayttajanimiIkkuna.Position = new Vector(0.0, kayttajaNimiNappi.Y - 50);
1344            kayttajanimiIkkuna.OKButton.Color = Color.Green;
1345            kayttajanimiIkkuna.OKButton.Clicked += delegate
1346            {
1347                AsetustenKaytto.Asetukset.KayttajaNimi = kayttajanimiIkkuna.InputBox.Text;
1348                AsetustenKaytto.TallennaAsetukset();
1349                LuoAsetusIkkuna();
1350            };
1351            Add(kayttajanimiIkkuna);
1352        };
1353        Add(kayttajaNimiNappi);
1354
1355        Label kayttajanimiTeksti = new Label("Käyttäjänimi: ");
1356        kayttajanimiTeksti.Position = new Vector(kayttajaNimiNappi.X - 150, kayttajaNimiNappi.Y);
1357        Add(kayttajanimiTeksti);
1358    }
1359
1360    /// <summary>
1361    /// Pelimuotovalikon luonti.
1362    /// </summary>
1363    void LuoPelimuodonValintaValikko()
1364    {
1365        AnimatedMultiSelectWindow pelimuotoValikko = new AnimatedMultiSelectWindow("Valitse pelimuoto", valikonPainikeKuva, "Deathmatch", "Infinite", "Sandbox", "Takaisin");
1366        pelimuotoValikko.ItemSelected += PainettiinPelimuotoValikonNappia;
1367        pelimuotoValikko.Color = Color.Transparent;
1368        pelimuotoValikko.BorderColor = Color.Transparent;
1369        Level.Background.Image = valikonKuva;
1370        Level.BackgroundColor = Color.Black;
1371        pelimuotoValikko.DefaultCancel = 2;
1372        Add(pelimuotoValikko);
1373    }
1374
1375    /// <summary>
1376    /// Pelimuotovalikon nappien painalluksen käsittely.
1377    /// </summary>
1378    /// <param name="valinta">Painettu nappi.</param>
1379    void PainettiinPelimuotoValikonNappia(int valinta)
1380    {
1381        switch (valinta)
1382        {
1383            case 0:
1384                LuoPelinKustomointiIkkuna();
1385                break;
1386            case 1:
1387                LuoInfinitevalikko();
1388                break;
1389            case 2:
1390                Level.Background.Image = null;
1391                ValittuKenttaTiedosto = "kenttä2"; // turha
1392                LuoKentta(2, 2, false);
1393                OnkoSatunnaisKentta = false;
1394                ClearControls();
1395                AsetaOhjaimet();
1396                AsetaSandboxOhjaimet();
1397                SoitaMusiikkia(3); // Sandbox: vanha OrcsCome
1398                break;
1399            case 3:
1400                LuoAlkuValikko();
1401                break;
1402        }
1403    }
1404
1405    /// <summary>
1406    /// Pelin kustomointi-ikkunan luonti.
1407    /// </summary>
1408    void LuoPelinKustomointiIkkuna()
1409    {
1410        List<Widget> ikkunanKomponentit = new List<Widget>();
1411
1412        MultiSelectWindow valikko = new MultiSelectWindow("Pelin kustomointi", "Klassinen mäppi", "Satunnaisgeneroitu mäppi", "Takaisin");
1413        valikko.ItemSelected += delegate(int valinta) { PainettiinPelinKustomointiIkkunanNappia(valinta, ikkunanKomponentit); };
1414        valikko.Color = Color.Transparent;
1415        valikko.SelectionColor = Color.Green;
1416        valikko.BorderColor = Color.Transparent;
1417        Level.Background.Image = valikonKuva;
1418        Level.BackgroundColor = Color.Black;
1419        valikko.DefaultCancel = 2;
1420        valikko.Position = new Vector(0.0, Screen.Top - valikko.Height);
1421        Add(valikko);
1422
1423        MonestakoVoittaa = new IntMeter(5, 1, 100);
1424
1425        Slider tapotJoillaVoittaa = new Slider(300.0, 20.0);
1426        tapotJoillaVoittaa.Position = new Vector(valikko.X, valikko.Y - 200);
1427        Add(tapotJoillaVoittaa);
1428        tapotJoillaVoittaa.BorderColor = Color.Transparent;
1429        tapotJoillaVoittaa.Color = Color.Transparent;
1430        tapotJoillaVoittaa.Knob.Color = Color.Green;
1431        tapotJoillaVoittaa.Track.Color = Color.DarkGreen;
1432        tapotJoillaVoittaa.BindTo(MonestakoVoittaa);
1433        ikkunanKomponentit.Add(tapotJoillaVoittaa);
1434
1435        Label tapotJoillaVoittaaOtsikko = new Label("Tappoja voittoon:");
1436        tapotJoillaVoittaaOtsikko.Position = new Vector(tapotJoillaVoittaa.X - tapotJoillaVoittaa.Width, tapotJoillaVoittaa.Y);
1437        Add(tapotJoillaVoittaaOtsikko);
1438        ikkunanKomponentit.Add(tapotJoillaVoittaaOtsikko);
1439
1440        Label tapotJoillaVoittaaNaytto = new Label();
1441        tapotJoillaVoittaaNaytto.BindTo(MonestakoVoittaa);
1442        tapotJoillaVoittaaNaytto.Position = new Vector(tapotJoillaVoittaa.X + tapotJoillaVoittaa.Width / 1.5, tapotJoillaVoittaa.Y);
1443        Add(tapotJoillaVoittaaNaytto);
1444        ikkunanKomponentit.Add(tapotJoillaVoittaaNaytto);
1445    }
1446
1447    /// <summary>
1448    /// Handleri pelin kustomointinäytön napeille.
1449    /// </summary>
1450    /// <param name="valinta">Valittu nappi.</param>
1451    /// <param name="poistettavatIkkunanKomponentit">Mitkä kaikki poistetaan, kun nappia painetaan.</param>
1452    void PainettiinPelinKustomointiIkkunanNappia(int valinta, List<Widget> poistettavatIkkunanKomponentit)
1453    {
1454        foreach (Widget ikkunanKomponentti in poistettavatIkkunanKomponentit)
1455        {
1456            ikkunanKomponentti.Destroy();
1457        }
1458
1459        switch (valinta)
1460        {
1461            case 0:
1462                Level.Background.Image = null;
1463                ValittuKenttaTiedosto = "kenttä2"; // kenttä2
1464                LuoKentta(0, 2, false);
1465                ClearControls();
1466                AsetaOhjaimet();
1467                SoitaMusiikkia(1); // DarkLurk deathmatchiin
1468                //Level.Background.Image = LoadImage("Pohja_testi");
1469                break;
1470            case 1:
1471                Level.Background.Image = null;
1472                ValittuKenttaTiedosto = "kenttä2";
1473                LuoKentta(1, 2, false);
1474                OnkoSatunnaisKentta = true;
1475                ClearControls();
1476                AsetaOhjaimet();
1477                SoitaMusiikkia(1); // DarkLurk deathmatchiin
1478                break;
1479            case 2:
1480                LuoPelimuodonValintaValikko();
1481                break;
1482        }
1483    }
1484
1485    /// <summary>
1486    /// Infinitevalikon luonti.
1487    /// </summary>
1488    void LuoInfinitevalikko()
1489    {
1490        List<Widget> ikkunanKomponentit = new List<Widget>();
1491        IntMeter monestakoHaviaa = new IntMeter(1, 0, 100);
1492        Level.Background.Image = null;
1493        MultiSelectWindow infinitevalikko = new MultiSelectWindow("Valitse pelaajien määrä", "Yksinpeli", "Moninpeli", "Takaisin");
1494        infinitevalikko.ItemSelected += delegate(int valinta) { PainettiinInfiniteMenunNappia(valinta, monestakoHaviaa.Value, ikkunanKomponentit); };
1495        infinitevalikko.Color = Color.Transparent;
1496        infinitevalikko.SelectionColor = Color.Green;
1497        infinitevalikko.BorderColor = Color.Transparent;
1498        infinitevalikko.Position = new Vector(0.0, Screen.Top - infinitevalikko.Height);
1499        Level.Background.Image = valikonKuva;
1500        infinitevalikko.DefaultCancel = 2;
1501        Add(infinitevalikko);
1502
1503        Slider kuolematJoillaHaviaa = new Slider(300.0, 20.0);
1504        kuolematJoillaHaviaa.Position = new Vector(infinitevalikko.X, infinitevalikko.Y - 200);
1505        Add(kuolematJoillaHaviaa);
1506        kuolematJoillaHaviaa.BorderColor = Color.Transparent;
1507        kuolematJoillaHaviaa.Color = Color.Transparent;
1508        kuolematJoillaHaviaa.Knob.Color = Color.Green;
1509        kuolematJoillaHaviaa.Track.Color = Color.DarkGreen;
1510        kuolematJoillaHaviaa.BindTo(monestakoHaviaa);
1511        ikkunanKomponentit.Add(kuolematJoillaHaviaa);
1512
1513        Label kuolematJoillaHaviaaOtsikko = new Label("Respauksia käytössä:");
1514        kuolematJoillaHaviaaOtsikko.Position = new Vector(kuolematJoillaHaviaa.X - kuolematJoillaHaviaa.Width, kuolematJoillaHaviaa.Y);
1515        Add(kuolematJoillaHaviaaOtsikko);
1516        ikkunanKomponentit.Add(kuolematJoillaHaviaaOtsikko);
1517
1518        Label kuolematJoillaHaviaaNaytto = new Label();
1519        kuolematJoillaHaviaaNaytto.BindTo(monestakoHaviaa);
1520        kuolematJoillaHaviaaNaytto.Position = new Vector(kuolematJoillaHaviaa.X + kuolematJoillaHaviaa.Width / 1.5, kuolematJoillaHaviaa.Y);
1521        Add(kuolematJoillaHaviaaNaytto);
1522        ikkunanKomponentit.Add(kuolematJoillaHaviaaNaytto);
1523
1524    }
1525
1526    /// <summary>
1527    /// Infinitevalikon napin painalluksen käsittely.
1528    /// </summary>
1529    /// <param name="valinta">Mitä painettiin.</param>
1530    /// <param name="monestakoPoikki">Monestako peli menee poikki.</param>
1531    /// <param name="poistettavatJutut">Pitä poistetaan, kun nappia painetaan.</param>
1532    void PainettiinInfiniteMenunNappia(int valinta, int monestakoPoikki, List<Widget> poistettavatJutut)
1533    {
1534        foreach (Widget poistettava in poistettavatJutut)
1535        {
1536            poistettava.Destroy();
1537        }
1538
1539        switch (valinta)
1540        {
1541            case 0: // Infiniten yksinpeli
1542                Level.Background.Image = null;
1543                ValittuKenttaTiedosto = "Minium"; // zombimäppi1
1544                ClearControls();
1545                SoitaMusiikkia(4); // OrcsCome Special
1546                AloitaInfiniteGame(1, 0, monestakoPoikki);
1547                AsetaOhjaimet();
1548                break;
1549
1550            case 1: // Infiniten kaksinpeli
1551                Level.Background.Image = null;
1552                ValittuKenttaTiedosto = "zombimäppi1";
1553                ClearControls();
1554                SoitaMusiikkia(4); // OrcsCome Special
1555                AloitaInfiniteGame(2, 0, monestakoPoikki);
1556                AsetaOhjaimet();
1557                break;
1558            case 2:
1559                LuoPelimuodonValintaValikko();
1560                break;
1561        }
1562    }
1563
1564    /// <summary>
1565    /// Luodaan pausevalikko.
1566    /// </summary>
1567    void LuoPauseValikko()
1568    {
1569        IsPaused = true;
1570        MultiSelectWindow valikko = new MultiSelectWindow("TAUKO", "Takaisin peliin", "Päävalikkoon", "Poistu pelistä");
1571        valikko.ItemSelected += PainettiinPauseValikonNappia;
1572        valikko.Color = Color.Transparent;
1573        valikko.BorderColor = Color.Transparent;
1574        valikko.SelectionColor = Color.Green;
1575        valikko.DefaultCancel = 0;
1576        Add(valikko);
1577    }
1578
1579    /// <summary>
1580    /// Pausevalikon nappien painalluksen käsittely.
1581    /// </summary>
1582    /// <param name="valinta">Painettu nappi.</param>
1583    void PainettiinPauseValikonNappia(int valinta)
1584    {
1585        switch (valinta)
1586        {
1587            case 0:
1588                IsPaused = false;
1589                break;
1590            case 1:
1591                IsPaused = false;
1592                PaaValikkoon();
1593                break;
1594            case 2:
1595                Exit();
1596                break;
1597        }
1598    }
1599
1600    #endregion
1601
1602    #region infinite
1603
1604    /// <summary>
1605    /// Aloitetaan uusi Infinite-peli.
1606    /// </summary>
1607    /// <param name="pelaajienMaara">Montako pelaajaa peliin tulee.</param>
1608    /// <param name="kenttaTyyppi">Millaista kenttää käytetään.</param>
1609    /// <param name="monestakoRespauksestaPoikki">Monestako respauksesta peli menee poikki.-</param>
1610    void AloitaInfiniteGame(int pelaajienMaara, int kenttaTyyppi, int monestakoRespauksestaPoikki)
1611    {
1612        Infinite infinite = new Infinite(monestakoRespauksestaPoikki);
1613        LuoKentta(kenttaTyyppi, pelaajienMaara, true);
1614        LuoVihollistenMallineet(infinite);
1615        infinite.PeliPaattyi += InfiniteHavio;
1616        infinite.VihollistenSpawnausAjastin.Timeout += delegate { SpawnaaInfinitenVihollisia(infinite); };
1617        foreach (Pelaaja p in pelaajat)
1618        {
1619            p.Kuoli += infinite.PelaajaKuoli;
1620        }
1621
1622        if (kenttaTyyppi == 0)
1623        {
1624            infinite.KaytetaankoFixedSpawneja = true;
1625            //AsetaFixedSpawnitInfiniteen(infinite);
1626        }
1627        Level.AmbientLight = 0.4;
1628        if (pelaajienMaara == 1) Level.AmbientLight = 0.7; // koska taskulamppu
1629    }
1630
1631    /// <summary>
1632    /// Luodaan Infinitessä käytettävien vihollisten mallineet
1633    /// ja annetaan ne Infinite-pelimuodon spawnauslistaan.
1634    /// </summary>
1635    /// <param name="peli">Peli, johon viholliset lisätään.</param>
1636    void LuoVihollistenMallineet(Infinite peli)
1637    {
1638        // Tavallinen zombi
1639        Vihollinen zombi = new Vihollinen(normaaliZombiKuva.Width / 1.2, normaaliZombiKuva.Height / 1.2, normaaliZombiKuva, 20, 4, 100, pelaajat, false, false, this, peli);
1640        peli.LisaaVihollinenPeliin(zombi);
1641
1642        // Zombi, jolla on ase
1643        /*Vihollinen ampuvaZombi = new Vihollinen(ampuvaZombiKuva.Width / 1.2, ampuvaZombiKuva.Height / 1.2, ampuvaZombiKuva, 20, 4, 100, pelaajat, true, false, this, peli);
1644        ampuvaZombi.AmpumisTarkkuus = 6.0;
1645        ampuvaZombi.EtaisyysJoltaAmpuu = 300.0;
1646        ampuvaZombi.ValittuAse = Aseet.LuoRynkky();
1647        ampuvaZombi.ValittuAse.AanenVoimakkuus = 0.5;
1648        ampuvaZombi.TodennakoisyysSpawnata = 0.3;
1649        peli.LisaaVihollinenPeliin(ampuvaZombi);*/
1650
1651        // Itsetuhoinen parasiitti
1652        /*Vihollinen parasiitti = new Vihollinen(10, 10, RandomGen.SelectOne<Image>(parasiittienKuvat), 1, 2, 200, pelaajat, false, true, this);
1653        parasiitti.KuolemaEfektinPartikkeliKuva = RandomGen.SelectOne<Image>(parasiittienPartikkeliKuvat);
1654        peli.LisaaVihollinenPeliin(parasiitti); */
1655    }
1656
1657    /// <summary>
1658    /// Spawnataan viholliset Infiniten spawnauslistasta.
1659    /// </summary>
1660    /// <param name="peli">Peli, jonka spawnauslistasta viholliset spawnataan.</param>
1661    void SpawnaaInfinitenVihollisia(Infinite peli)
1662    {
1663        foreach (Vihollinen vihu in peli.TallaSpawnauskerrallaSpawnattavatViholliset)
1664        {
1665            vihu.Destroyed += delegate { peli.VihollisiaTapettu.Value++; };
1666            Add(vihu);
1667            if (peli.KaytetaankoFixedSpawneja && peli.VihollistenFixedSpawnit.Count != 0) vihu.Position = RandomGen.SelectOne<Vector>(peli.VihollistenFixedSpawnit);
1668            else vihu.Position = ArvoSpawnausPaikkaKentanLaidoilta(Vakiot.PALJONKO_VIHOLLISET_SPAWNAAVAT_KENTAN_RAJOJEN_ULKOPUOLELLE);
1669            peli.VihollisetKentalla.Add(vihu);
1670        }
1671    }
1672
1673    /// <summary>
1674    /// Arvotaan satunnainen paikka kentän rajojen ulkopuolelta.
1675    /// </summary>
1676    /// <param name="paljonkoLaitojenUlkopuolelle">Paljonko paikka tulee kentän rajojen ulkopuolelle.</param>
1677    /// <returns>Satunnainen paikka kentän laidoilta.</returns>
1678    Vector ArvoSpawnausPaikkaKentanLaidoilta(double paljonkoLaitojenUlkopuolelle)
1679    {
1680        //Arvotaan satunnainen vektori kentän joka laidalle, ja arvotaan joku niistä
1681        Vector[] vaihtoehdot = new Vector[4];
1682        vaihtoehdot[0] = RandomGen.NextVector(Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA - paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA,
1683            Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA - paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA); // vasen reuna
1684
1685        vaihtoehdot[1] = RandomGen.NextVector(Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA + paljonkoLaitojenUlkopuolelle,
1686            Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA + paljonkoLaitojenUlkopuolelle); // yläreuna
1687
1688        vaihtoehdot[2] = RandomGen.NextVector(Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA + paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA,
1689            Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA + paljonkoLaitojenUlkopuolelle, Vakiot.PELAAJAN_SUURIN_SALLITTU_Y_KENTALLA); // oikea reuna
1690
1691        vaihtoehdot[3] = RandomGen.NextVector(Vakiot.PELAAJAN_PIENIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA - paljonkoLaitojenUlkopuolelle,
1692            Vakiot.PELAAJAN_SUURIN_SALLITTU_X_KENTALLA, Vakiot.PELAAJAN_PIENIN_SALLITTU_Y_KENTALLA - paljonkoLaitojenUlkopuolelle); // alareuna
1693        return RandomGen.SelectOne<Vector>(vaihtoehdot); // palautetaan yksi neljästä
1694    }
1695
1696    /// <summary>
1697    /// Asetetaan Infiniten fixed-spawnit normimäppiä varten.
1698    /// </summary>
1699    /// <param name="peli"></param>
1700    void AsetaFixedSpawnitInfiniteen(Infinite peli)
1701    {
1702        peli.VihollistenFixedSpawnit.Add(new Vector(0, -900));
1703        peli.VihollistenFixedSpawnit.Add(new Vector(960, -270));
1704        peli.VihollistenFixedSpawnit.Add(new Vector(-960, -270));
1705        peli.VihollistenFixedSpawnit.Add(new Vector(0, 1640));
1706        peli.VihollistenFixedSpawnit.Add(new Vector(1300, 920));
1707        peli.VihollistenFixedSpawnit.Add(new Vector(-1300, 920));
1708    }
1709
1710    #endregion
1711
1712    #region pelaaja
1713
1714    /// <summary>
1715    /// Luodaan uusi pelaaja.
1716    /// </summary>
1717    /// <param name="paikka">Paikka, johon pelaaja luodaan ja johon se respawnaa.</param>
1718    /// <param name="leveys">Pelaajan leveys.</param>
1719    /// <param name="korkeus">Pelaajan korkeus.</param>
1720    /// <param name="numero">Pelaajan numero.</param>
1721    /// <param name="kuva">Pelaajan kuva.</param>
1722    /// <param name="kamanVari">Pelaajaan viittaavien objektien väri.</param>
1723    /// <param name="kaytetaankoLaseria">Onko pelaajalla lasertähtäin vai tavallinen piste.</param>
1724    /// <param name="hudinPaikka">Pelaajan HUD:in paikka.</param>
1725    /// <returns>Pelaaja.</returns>
1726    public Pelaaja LuoPelaaja(Vector paikka, double leveys, double korkeus, int numero, Image kuva, Color kamanVari, bool kaytetaankoLaseria, Vector hudinPaikka, bool kaytetaankoTaskulamppua)
1727    {
1728        Pelaaja pelaaja = new Pelaaja(leveys, korkeus, kaytetaankoLaseria, kaytetaankoTaskulamppua); // true: käytetäänkö taskulamppua
1729        pelaaja.CanRotate = false;
1730        pelaaja.Tag = "pelaaja";
1731        pelaaja.LisaaAse(Aseet.LuoPistooli());
1732        pelaaja.LisaaAse(Aseet.LuoNyrkki());
1733        pelaaja.Position = paikka;
1734        pelaaja.SpawnausPaikat.Add(paikka);
1735        pelaaja.Numero = numero;
1736        pelaaja.Image = kuva;
1737        pelaaja.LinearDamping = 0.80;
1738        pelaaja.objektienVari = kamanVari;
1739        pelaaja.elamaPalkki.BarColor = pelaaja.objektienVari;
1740        pelaaja.tahtain = LuoTähtäin(pelaaja.objektienVari);
1741        pelaaja.ValittuAseNaytto = LuoAseNäyttö(hudinPaikka);
1742        pelaaja.ValittuAseNaytto.Text = pelaaja.ValittuAse.AseenNimi;
1743        pelaaja.TappojenMaaraNaytto = LuoTappoNaytto(pelaaja.ValittuAseNaytto.Position);
1744        if (kaytetaankoLaseria)
1745        {
1746            pelaaja.kaytetaankoPalloTahtainta = false;
1747            //pelaaja.tahtain.IsVisible = false;
1748            //AxleJoint aj = new AxleJoint(pelaaja.tahtain, pelaaja);
1749            //aj.Softness = 2;
1750            //Add(aj);
1751        }
1752        return pelaaja;
1753    }
1754
1755    /// <summary>
1756    /// Liikutetaan pelaajaa määrättyyn suuntaan näppäimistöllä.
1757    /// </summary>
1758    /// <param name="pelaaja">Pelaaja, jota liikutetaan.</param>
1759    /// <param name="suunta">Suunta, johon pelaajaa liikutetaan.</param>
1760    void LiikutaPelaajaa(Pelaaja pelaaja, Vector suunta)
1761    {
1762        pelaaja.Move(suunta * pelaaja.Nopeus);
1763    }
1764
1765    /// <summary>
1766    /// Liikutetaan pelaajaa määrättyyn suuntaan Xbox-ohjaimella.
1767    /// </summary>
1768    /// <param name="pelaaja">Pelaaja, jota liikutetaan.</param>
1769    /// <param name="tatinTila">Xbox-ohjaimen analogitatin asento.</param>
1770    void LiikutaPelaajaaPadilla(AnalogState tatinTila, Pelaaja pelaaja)
1771    {
1772        Vector tatinAsento = tatinTila.StateVector;
1773        pelaaja.Move(tatinAsento * pelaaja.Nopeus);
1774        pelaaja.tahtain.Move(tatinAsento * pelaaja.Nopeus);
1775    }
1776
1777    // Tässä kohdassa (LiikutaTahtainta, LiikutaTahtaintaPadilla) ongelmana samat parametrit, mutta eri sisältö.
1778
1779    /// <summary>
1780    /// Liikutetaan pelaajan tähtäintä hiirellä.
1781    /// </summary>
1782    /// <param name="hiirenTila">Ei käytössä, pakollinen parametri.</param>
1783    /// <param name="pelaaja">Pelaaja, jonka tähtäintä liikutetaan.</param>
1784    void LiikutaTahtainta(AnalogState hiirenTila, Pelaaja pelaaja)
1785    {
1786        pelaaja.tahtain.X = Mouse.PositionOnWorld.X;
1787        pelaaja.tahtain.Y = Mouse.PositionOnWorld.Y;
1788    }
1789
1790    /// <summary>
1791    /// Liikutetaan pelaajan tähtäintä Xbox-ohjaimella.
1792    /// </summary>
1793    /// <param name="pelaaja">Pelaaja, jonka tähtäintä liikutetaan.</param>
1794    /// <param name="tatinTila">Xbox-ohjaimen analogitatin asento.</param>
1795    void LiikutaTahtaintaPadilla(AnalogState tatinTila, Pelaaja pelaaja)
1796    {
1797        pelaaja.tahtain.Move(tatinTila.StateVector * 1500);
1798    }
1799
1800    /// <summary>
1801    /// Luodaan uusi tähtäin.
1802    /// </summary>
1803    /// <param name="vari">Tähtäimen väri.</param>
1804    /// <returns>Tähtäin.</returns>
1805    PhysicsObject LuoTähtäin(Color vari)
1806    {
1807        PhysicsObject tähtäin = new PhysicsObject(10.0, 10.0);
1808        tähtäin.Shape = Shape.Circle;
1809        tähtäin.Color = vari;
1810        tähtäin.IgnoresCollisionResponse = true;
1811        tähtäin.IgnoresExplosions = true;
1812        tähtäin.IgnoresPhysicsLogics = true;
1813        tähtäin.LinearDamping = 0.60;
1814        Add(tähtäin, 3);
1815        return tähtäin;
1816    }
1817
1818    Label LuoTappoNaytto(Vector ylemmanHudinOsanPaikka)
1819    {
1820        Label tapponaytto = new Label("Tappoja: 0");
1821        tapponaytto.TextColor = Color.White;
1822        tapponaytto.BorderColor = Color.Transparent;
1823        tapponaytto.Position = ylemmanHudinOsanPaikka - new Vector(0.0, 60.0);
1824        Add(tapponaytto);
1825        return tapponaytto;
1826    }
1827
1828    #endregion
1829
1830    #region aseiden toiminnot
1831
1832    /// <summary>
1833    /// Ammutaan pelaajan kulloinkin valittuna olevalla aseella ja
1834    /// luodaan ammukselle törmäyksenkäsittelijät.
1835    /// </summary>
1836    /// <param name="pelaaja">Pelaaja, jonka aseella ammutaan.</param>
1837    /// <param name="overridesIsReady">Annetaan aseen ampua, vaikka se ei oikeasti voisi. Jos true, ääntä ei toisteta.</param>
1838    void Ammu(Pelaaja pelaaja, bool overridesIsReady = false)
1839    {
1840        // pari tarpeellista tarkistusta
1841        if (!pelaaja.IsAddedToGame) return;
1842        if (pelaaja.ValittuAse == null) return;
1843        if (pelaaja.LadataankoAsetta) return;
1844
1845        //pelaaja.ValittuAse.IsReady = true;
1846        PhysicsObject ammus = pelaaja.ValittuAse.Shoot(overridesIsReady);
1847        if (ammus == null) return;
1848
1849        // laitetaan ammus satunnaiseen suuntaan aseen hajoaman mukaan
1850        Vector random = RandomGen.NextVector(pelaaja.ValittuAse.AseenHajoama.X, pelaaja.ValittuAse.AseenHajoama.Y);
1851        if (pelaaja == pelaajat[0])
1852        {
1853            ammusmittariNäyttö.Text = pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString();
1854            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö.Text = "";
1855            if (pelaaja.ValittuAse.HyokkaysAnimaatio1 != null)
1856            {
1857                pelaajat[0].Animation = pelaaja.ValittuAse.HyokkaysAnimaatio1;
1858                pelaajat[0].Animation.Start(1);
1859            }
1860        }
1861
1862        if (pelaaja == pelaajat[1])
1863        {
1864            ammusmittariNäyttö2.Text = pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString();
1865            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö2.Text = "";
1866            if (pelaaja.ValittuAse.HyokkaysAnimaatio2 != null)
1867            {
1868                pelaajat[1].Animation = pelaaja.ValittuAse.HyokkaysAnimaatio2;
1869                pelaajat[1].Animation.Start(1);
1870            }
1871        }
1872
1873        ammus.Hit(random);
1874        ammus.CollisionIgnoreGroup = 4;
1875        ammus.Tag = "ammus";
1876        ammus.LinearDamping = 0.99;
1877        ammus.Size = new Vector(pelaaja.ValittuAse.luodinKuva.Width, pelaaja.ValittuAse.luodinKuva.Height);
1878        ammus.Color = Color.White;
1879        ammus.Mass = 0.01;
1880        ammus.CanRotate = false;
1881
1882        // jos on meleease, ei näytetä ammusta
1883        if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammus.IsVisible = false;
1884
1885        // muuten ammutaan hylsy ja laitetaan luodille oikea kuva
1886        else
1887        {
1888            if (pelaaja.ValittuAse.TuleekoHylsya)
1889                Hylsy(pelaaja, pelaaja.ValittuAse.hylsynKuva);
1890            ammus.Image = pelaaja.ValittuAse.luodinKuva;
1891        }
1892
1893        if (pelaaja.ValittuAse.UsesTracers)
1894        {
1895            ammus.IsUpdated = true;
1896            ammus.NeedsUpdateCall = true;
1897            Color c;
1898            if (pelaaja.ValittuAse.OverrideTracerColor != Color.Transparent)
1899                c = pelaaja.ValittuAse.OverrideTracerColor;
1900            else c = pelaaja.objektienVari;
1901            ammus.Updated += delegate(PhysicsObject o) { DrawTracers(o, c, pelaaja.ValittuAse.TracerLength, pelaaja.ValittuAse.TracerBrightness); };
1902        }
1903
1904        if (pelaaja.ValittuAse.IsHoming)
1905        {
1906            ammus.IsUpdated = true;
1907            ammus.NeedsUpdateCall = true;
1908            if (pelaaja == pelaajat[0])
1909                ammus.Updated += delegate(PhysicsObject o) { HakeuduKohteeseen(o, pelaajat[1], 750); };
1910            else
1911                ammus.Updated += delegate(PhysicsObject o) { HakeuduKohteeseen(o, pelaajat[0], 750); };
1912
1913        }
1914
1915        if (pelaaja.ValittuAse.LapaiseekoMateriaaleja)
1916        {
1917            ammus.IgnoresCollisionResponse = true;
1918            ammus.Collided += delegate
1919            {
1920                Timer.SingleShot(pelaaja.ValittuAse.AseenLapaisy, delegate { ammus.IgnoresCollisionResponse = false; });
1921            };
1922        }
1923
1924        AddCollisionHandler<PhysicsObject, Pelaaja>(
1925            ammus, delegate(PhysicsObject a, Pelaaja kohdepelaaja)
1926            {
1927                Damagea(kohdepelaaja, pelaaja.ValittuAse.TuhovoimaElaviaVastaan);
1928                Partikkelit.AddParticleEffect(Partikkelit.VeriPartikkelit, new Vector(a.X, a.Y), 40);
1929                osuma1.Play();
1930                if (ammus != null) ammus.Destroy();
1931            });
1932
1933        AddCollisionHandler<PhysicsObject, Vihollinen>(
1934            ammus, delegate(PhysicsObject a, Vihollinen kohde)
1935            {
1936                Damagea(kohde, pelaaja.ValittuAse.TuhovoimaElaviaVastaan);
1937                Partikkelit.AddParticleEffect(Partikkelit.VeriPartikkelit, new Vector(a.X, a.Y), 40);
1938                osuma1.Play();
1939                if (ammus != null) ammus.Destroy();
1940            });
1941
1942        AddCollisionHandler<PhysicsObject, Tuhoutuva>(
1943            ammus, delegate(PhysicsObject a, Tuhoutuva tuhoutuva)
1944        {
1945            if (tuhoutuva.IsStatic)
1946            {
1947                //GameObject luodinJalki = new GameObject(12, 13);
1948                //luodinJalki.Image = crack1;
1949                //luodinJalki.Position = a.Position;
1950                //luodinJalki.Angle = RandomGen.NextAngle();
1951                //Add(luodinJalki, 1);
1952                //LisaaTehosteObjekti(luodinJalki);
1953                //tuhoutuva.Destroyed += delegate
1954                //{
1955                //    luodinJalki.Destroy();
1956                //    tehosteet.Remove(luodinJalki);
1957                //};
1958            }
1959
1960            if (pelaaja.ValittuAse.HaviaakoAmmusOsumasta && ammus.IgnoresCollisionResponse == false)
1961            {
1962                a.Destroy();
1963                a.NeedsUpdateCall = false;
1964                switch (RandomGen.NextInt(0, 5))
1965                {
1966                    case 0:
1967                        luotiOsuu.Play();
1968                        break;
1969                    case 1:
1970                        luotiOsuu2.Play();
1971                        break;
1972                    case 2:
1973                        luotiOsuu3.Play();
1974                        break;
1975                    case 3:
1976                        luotiOsuu4.Play();
1977                        break;
1978                    case 4:
1979                        luotiOsuu5.Play();
1980                        break;
1981                }
1982            }
1983            else if (ammus.IgnoresCollisionResponse == true) // ei tuhota
1984            {
1985                switch (RandomGen.NextInt(0, 5))
1986                {
1987                    case 0:
1988                        luotiOsuu.Play();
1989                        break;
1990                    case 1:
1991                        luotiOsuu2.Play();
1992                        break;
1993                    case 2:
1994                        luotiOsuu3.Play();
1995                        break;
1996                    case 3:
1997                        luotiOsuu4.Play();
1998                        break;
1999                    case 4:
2000                        luotiOsuu5.Play();
2001                        break;
2002                }
2003            }
2004            else
2005            {
2006                a.Velocity = new Vector(0.0, 0.0);
2007                a.IgnoresCollisionResponse = true;
2008            }
2009            //tuhoutuva.Kesto.Value -= pelaaja.ValittuAse.TuhovoimaTuhoutuviaVastaan;
2010            Damagea(tuhoutuva, pelaaja.ValittuAse.TuhovoimaTuhoutuviaVastaan);
2011        });
2012
2013        AddCollisionHandler<PhysicsObject, Tuhoutuva>(
2014            ammus, "kivi", delegate(PhysicsObject a, Tuhoutuva kivi)
2015            {
2016                Partikkelit.AddParticleEffect(Partikkelit.KiviPartikkelit, new Vector(a.X, a.Y), 30);
2017                Partikkelit.AddParticleEffect(Partikkelit.KipinaPartikkelit, new Vector(a.X, a.Y), 5);
2018            });
2019
2020        AddCollisionHandler<PhysicsObject, Tuhoutuva>(
2021            ammus, "puu", delegate(PhysicsObject a, Tuhoutuva puu)
2022            {
2023                Partikkelit.AddParticleEffect(Partikkelit.PuuPartikkelit, new Vector(a.X, a.Y), 40);
2024            });
2025        AddCollisionHandler<PhysicsObject, PhysicsObject>(
2026            ammus, "piikkilanka", delegate(PhysicsObject a, PhysicsObject piikkilanka)
2027            {
2028                Partikkelit.AddParticleEffect(Partikkelit.KipinaPartikkelit, new Vector(a.X, a.Y), 40);
2029                //ammus.Destroy();
2030            });
2031        AddCollisionHandler<PhysicsObject, PhysicsObject>(
2032            ammus, delegate(PhysicsObject a, PhysicsObject kohde)
2033            {
2034                if (ammus.IgnoresCollisionResponse == false) a.Destroy();
2035                a.NeedsUpdateCall = false;
2036            });
2037
2038    }
2039
2040    /// <summary>
2041    /// Ammutaan haulikkotyyppisellä aseella.
2042    /// </summary>
2043    /// <param name="pelaaja">Pelaaja, jonka aseella ammutaan.</param>
2044    /// <param name="ammustenMaara">Montako ammusta ammutaan.</param>
2045    void AmmuHaulikolla(Pelaaja pelaaja, int ammustenMaara)
2046    {
2047        if (!pelaaja.ValittuAse.IsReady) return;
2048
2049        pelaaja.ValittuAse.AttackSound.Play();
2050        pelaaja.ValittuAse.Ammo.Value--;
2051        Hylsy(pelaaja, pelaaja.ValittuAse.hylsynKuva);
2052
2053        for (int i = 0; i < ammustenMaara; i++)
2054        {
2055            Ammu(pelaaja, true);
2056        }
2057    }
2058
2059    /// <summary>
2060    /// Ladataan pelaajan kulloinkin valittuna oleva ase.
2061    /// </summary>
2062    /// <param name="pelaaja">Pelaaja, jonka ase ladataan.</param>
2063    void Lataa(Pelaaja pelaaja)
2064    {
2065        // Ammo.Value == valitun aseen senhetkinen lippaassa oleva ammusmäärä
2066        // Ammo.MaxValue == valitun aseen maksimimäärä ammuksia lippaassa
2067        // MaxAmmo.Value == valitun aseen kokonaisammusten maksimimäärä
2068
2069        // jos ammukset täynnä, ei tehdä mitään
2070        if (pelaaja.ValittuAse.Ammo.Value == pelaaja.ValittuAse.Ammo.MaxValue)
2071        {
2072            pelaaja.LadataankoAsetta = false;
2073            return;
2074        }
2075
2076        // montako ammusta on käytetty lippaasta
2077        int lippaastaKaytettyjaAmmuksia = pelaaja.ValittuAse.Ammo.MaxValue - pelaaja.ValittuAse.Ammo.Value;
2078        aseLatausAani.Play();
2079        if (pelaaja.ValittuAse.MaxAmmo.Value >= pelaaja.ValittuAse.Ammo.MaxValue) pelaaja.ValittuAse.Ammo.Value = pelaaja.ValittuAse.Ammo.MaxValue;
2080        else pelaaja.ValittuAse.Ammo.Value = pelaaja.ValittuAse.MaxAmmo.Value;
2081
2082        pelaaja.ValittuAse.MaxAmmo.Value -= lippaastaKaytettyjaAmmuksia;
2083
2084        if (pelaaja == pelaajat[0])
2085        {
2086            ammusmittariNäyttö.Text = pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString();
2087        }
2088        if (pelaaja == pelaajat[1])
2089        {
2090            ammusmittariNäyttö2.Text = pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString();
2091        }
2092        pelaaja.LadataankoAsetta = false;
2093    }
2094
2095    /// <summary>
2096    /// Luo hylsyn pelaajan ampuessa ja lisää sen hylsyt-taulukkoon.
2097    /// </summary>
2098    /// <param name="pelaaja">Pelaaja, jonka aseesta hylsy lentää.</param>
2099    void Hylsy(Pelaaja pelaaja, Image hylsynkuva)
2100    {
2101        PhysicsObject hylsy = new PhysicsObject(2, 5);
2102        hylsy.Image = hylsynkuva;
2103        hylsy.Position = pelaaja.Position + Vector.FromLengthAndAngle(15, pelaaja.Angle + Angle.FromDegrees(-90));
2104        hylsy.LinearDamping = 0.93;
2105        hylsy.Mass = 0.5;
2106        hylsy.Angle = pelaaja.Angle + Angle.FromDegrees(90);
2107        hylsy.AngularVelocity = RandomGen.NextDouble(-20.0, 20.0);
2108        hylsy.AngularDamping = 0.97;
2109        Add(hylsy, -3);
2110
2111        hylsy.MaximumLifetime = TimeSpan.FromSeconds(1.5);
2112        hylsy.Destroying += delegate
2113        {
2114            GameObject fakeHylsy = new GameObject(hylsy.Width, hylsy.Height); // samanlainen GameObject-hylsy samaan paikkaan lagin vähentämiseksi
2115            fakeHylsy.Image = hylsynkuva;
2116            fakeHylsy.Position = hylsy.Position;
2117            fakeHylsy.Angle = hylsy.Angle;
2118            Add(fakeHylsy, -1);
2119            LisaaTehosteObjekti(fakeHylsy);
2120        };
2121
2122        hylsy.Hit(Vector.FromLengthAndAngle(RandomGen.NextInt(150, 300), pelaaja.Angle + Angle.FromDegrees(RandomGen.NextDouble(-95, -85))));
2123        AddCollisionHandler(hylsy, HylsyOsuu);
2124        Timer.SingleShot(0.5, delegate { hylsynPutoamisAani.Play(0.7, 0.0, 0.0); });
2125    }
2126
2127    /// <summary>
2128    /// CollisionHandleri hylsylle. Soitetaan kilahdusääni, jos hylsy osuu seinään.
2129    /// </summary>
2130    /// <param name="hylsy">Hylsy.</param>
2131    /// <param name="kohde">Kohde, johon hylsy osuu.</param>
2132    void HylsyOsuu(PhysicsObject hylsy, PhysicsObject kohde)
2133    {
2134        if (kohde is Tuhoutuva)
2135            hylsynPutoamisAani.Play(0.7, 0.0, 0.0);
2136    }
2137
2138    /// <summary>
2139    /// Heitetään kranaatti, jos pelaaja on lisätty ruudulle ja pelaajalla on kranaatteja jäljellä.
2140    /// </summary>
2141    /// <param name="pelaaja">Pelaaja, joka heittää kranaatin.</param>
2142    void HeitaKranaatti(Pelaaja pelaaja)
2143    {
2144        if (!pelaaja.IsAddedToGame || pelaaja.KranaattienMaara <= 0) return;
2145        const double KRANAATIN_NOPEUS = 25000;
2146        Grenade kranaatti = new Grenade(3.0, TimeSpan.FromSeconds(1.5));
2147        kranaatti.LinearDamping = 0.95;
2148        kranaatti.AngularVelocity = RandomGen.NextDouble(-5.0, 5.0);
2149        kranaatti.AngularDamping = 0.97;
2150        kranaatti.Image = kranaatinKuva;
2151        kranaatti.Explosion.Image = null;
2152        kranaatti.Explosion.ShockwaveColor = Color.Black;
2153        kranaatti.Explosion.IsShockwaveVisible = false;
2154        kranaatti.Explosion.Sound = Aseet.singonAani;
2155        kranaatti.Explosion.Speed = 2000;
2156        kranaatti.Explosion.MaxRadius = 500;
2157        kranaatti.Explosion.ShockwaveReachesObject += delegate(IPhysicsObject kohde, Vector shokki) { RajahdysOsuu(kohde, shokki, kranaatti.Position, Aseet.KRANAATIN_MAKSIMI_DAMAGE); };
2158        kranaatti.Destroying += delegate
2159        {
2160            Partikkelit.AddExplosionEffect(kranaatti.Position, 800);
2161            valo.Position = kranaatti.Position;
2162            valo.Intensity = 2.0;
2163            valo.Distance = 100;
2164            Timer.SingleShot(0.2, delegate { valo.Intensity = 1.5; });
2165            Timer.SingleShot(0.3, delegate { valo.Intensity = 1.0; });
2166            Timer.SingleShot(0.4, delegate { valo.Intensity = 0.5; });
2167            Timer.SingleShot(0.5, delegate { valo.Intensity = 0.0; });
2168        };
2169        kranaatti.IsUpdated = true;
2170        kranaatti.NeedsUpdateCall = true;
2171        kranaatti.Updated += delegate(PhysicsObject p) { DrawTracers(kranaatti.Position, Color.Orange, 0.30, 3); };
2172        pelaaja.Throw(kranaatti, Angle.FromDegrees(0), KRANAATIN_NOPEUS, 0, 0);
2173        pelaaja.KranaattienMaara--;
2174    }
2175
2176    /// <summary>
2177    /// Annetaan pelaajalle kamaa pelaajan törmätessä laatikkoon.
2178    /// </summary>
2179    /// <param name="laatikko">Laatikko, johon törmätään.</param>
2180    /// <param name="kohde">Pelaaja, joka törmää.</param>
2181    void AnnaKamaa(PhysicsObject laatikko, PhysicsObject kohde)
2182    {
2183        if (kohde.Tag.ToString() == "pelaaja")
2184        {
2185            Pelaaja pelaaja = (kohde as Pelaaja);
2186            Laatikko laat = (laatikko as Laatikko);
2187            Func<Ase>[] aseidenLuontimetodit = { Aseet.LuoRynkky, Aseet.LuoHaulikko, Aseet.LuoMinigun, Aseet.LuoSnipa, Aseet.LuoSinko, /*Aseet.LuoVarsijousi,*/ Aseet.LuoMagnum, Aseet.LuoVintorez };
2188
2189            if (laat.OnkoKäytössä == false)
2190            {
2191                //Ei voi ottaa kamaa käytetystä laatikosta
2192                return;
2193            }
2194            for (int i = 0; i < aseidenLuontimetodit.Length; i++)
2195            {
2196                Ase ase = aseidenLuontimetodit[i]();
2197                if (!pelaaja.OnkoPelaajallaAse(ase.Tag.ToString()))
2198                {
2199                    if (AikaKentanAlusta.SecondCounter.Value > ase.aikaJolloinVoiLuoda)
2200                    {
2201                        pelaaja.LisaaAse(ase);
2202                        MessageDisplay.Add("Pelaaja " + pelaaja.Numero + " sai aseen: " + ase.AseenNimi);
2203                        return;
2204                    }
2205                }
2206            }
2207            Ase satunnainenPelaajanAse;
2208            do
2209                satunnainenPelaajanAse = RandomGen.SelectOne<Ase>(pelaaja.Aseet);
2210            while (satunnainenPelaajanAse.OnkoMeleeAse);
2211
2212            satunnainenPelaajanAse.MaxAmmo.Value = satunnainenPelaajanAse.MaxAmmo.MaxValue;
2213            MessageDisplay.Add("Pelaaja " + pelaaja.Numero + " sai ammuksia aseeseen: " + satunnainenPelaajanAse.AseenNimi);
2214            pelaaja.KranaattienMaara++;
2215            MessageDisplay.Add("Pelaaja " + pelaaja.Numero + " sai kranaatin.");
2216
2217            laatikko.Image = kamaaNäkymätön;
2218            laatikko.IgnoresCollisionResponse = true;
2219            laat.OnkoKäytössä = false;
2220            laat.LaatikonAika.Start();
2221        }
2222    }
2223
2224    /// <summary>
2225    /// Luodaan näyttö, joka näyttää valitun aseen nimen.
2226    /// </summary>
2227    /// <param name="paikka">Näytön paikka.</param>
2228    /// <returns>Näyttö.</returns>
2229    Label LuoAseNäyttö(Vector paikka)
2230    {
2231        Label asenäyttö = new Label();
2232        Add(asenäyttö);
2233        //asenäyttö.X = Screen.Left + 130;
2234        //asenäyttö.Y = Screen.Top - 70;
2235        asenäyttö.Position = paikka;
2236        asenäyttö.TextColor = Color.White;
2237        asenäyttö.BorderColor = Color.Transparent;
2238        return asenäyttö;
2239    }
2240
2241    /// <summary>
2242    /// Luodaan pelaajan 1 ammusmittari.
2243    /// </summary>
2244    void AmmusMittari()
2245    {
2246        IntMeter ammusmittari = new IntMeter(0);
2247        ammusmittariNäyttö = new Label(
2248        pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString());
2249        ammusmittariNäyttö.X = Screen.Left + 125;
2250        ammusmittariNäyttö.Y = Screen.Top - 100;
2251        ammusmittariNäyttö.TextColor = Jypeli.Color.White;
2252        ammusmittariNäyttö.BorderColor = Jypeli.Color.Transparent;
2253        Add(ammusmittariNäyttö);
2254    }
2255
2256    /// <summary>
2257    /// Luodaan pelaajan 2 ammusmittari.
2258    /// </summary>
2259    void AmmusMittari2()
2260    {
2261        IntMeter ammusmittari2 = new IntMeter(0);
2262        ammusmittariNäyttö2 = new Label(pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString());
2263        ammusmittariNäyttö2.X = Screen.Right - 125;
2264        ammusmittariNäyttö2.Y = Screen.Top - 100;
2265        ammusmittariNäyttö2.TextColor = Jypeli.Color.White;
2266        ammusmittariNäyttö2.BorderColor = Jypeli.Color.Transparent;
2267        Add(ammusmittariNäyttö2);
2268    }
2269
2270    /// <summary>
2271    /// Vaihdetaan asetta ja pelaajan kuvaa.
2272    /// </summary>
2273    /// <param name="pelaaja">Pelaaja, jonka asetta vaihdetaan.</param>
2274    /// <param name="vaihtosuunta">Suunta, johon aselistaa pyöritetään.</param>
2275    void VaihdaAsetta(Pelaaja pelaaja, int vaihtosuunta = 0)
2276    {
2277        if (pelaaja.AseidenMaara < 1) return;
2278        pelaaja.VaihdaAse(Mouse.WheelChange);
2279        pelaaja.VaihdaAse(vaihtosuunta);
2280
2281        if (pelaaja == pelaajat[0])
2282        {
2283            pelaaja.Image = pelaaja.ValittuAse.Pelaajan1AseKuva;
2284            ammusmittariNäyttö.Text = pelaajat[0].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[0].ValittuAse.MaxAmmo.Value.ToString();
2285            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö.Text = "";
2286            pelaaja.ValittuAseNaytto.Text = pelaaja.ValittuAse.AseenNimi;
2287        }
2288
2289        if (pelaaja == pelaajat[1])
2290        {
2291            pelaaja.Image = pelaaja.ValittuAse.Pelaajan2AseKuva;
2292            ammusmittariNäyttö2.Text = pelaajat[1].ValittuAse.Ammo.Value.ToString() + " / " + pelaajat[1].ValittuAse.MaxAmmo.Value.ToString();
2293            if (pelaaja.ValittuAse.OnkoMeleeAse == true) ammusmittariNäyttö2.Text = "";
2294            pelaaja.ValittuAseNaytto.Text = pelaaja.ValittuAse.AseenNimi;
2295        }
2296        pelaaja.ValittuAse.IsVisible = false;
2297    }
2298
2299    /// <summary>
2300    /// Ohjataan hakeutuvaa esinettä kohteeseen.
2301    /// </summary>
2302    /// <param name="hakeutuva">Hakeutuva esine.</param>
2303    /// <param name="kohde">Kohde, jota kohti hakeudutaan.</param>
2304    void HakeuduKohteeseen(PhysicsObject hakeutuva, PhysicsObject kohde, double nopeus)
2305    {
2306        if (hakeutuva.Brain.Owner != null) return;
2307
2308        FollowerBrain fb = new FollowerBrain(kohde);
2309        fb.Speed = nopeus;
2310        fb.TurnWhileMoving = true;
2311        hakeutuva.Brain = fb;
2312    }
2313
2314    #endregion
2315
2316    #region ohjaimet
2317
2318    /// <summary>
2319    /// Asetetaan ohjaimet.
2320    /// </summary>
2321    void AsetaOhjaimet()
2322    {
2323        // Pelaajan 1 ohjaimet
2324        Keyboard.Listen(Key.Escape, Jypeli.ButtonState.Pressed, LuoPauseValikko, "Lopeta peli");
2325        Keyboard.Listen(Key.W, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(0.0, 1.0));
2326        Keyboard.Listen(Key.S, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(0.0, -1.0));
2327        Keyboard.Listen(Key.A, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(-1.0, 0.0));
2328        Keyboard.Listen(Key.D, Jypeli.ButtonState.Down, LiikutaPelaajaa, "", pelaajat[0], new Vector(1.0, 0.0));
2329        Keyboard.Listen(Key.R, Jypeli.ButtonState.Pressed, delegate
2330        {
2331            lippaanPoistoAani.Play();
2332            pelaajat[0].LadataankoAsetta = true;
2333            if (pelaajat[0].ValittuAse.LatausAnimaatio1 != null)
2334            {
2335                pelaajat[0].Animation = new Animation(pelaajat[0].ValittuAse.LatausAnimaatio1);
2336                pelaajat[0].Animation.Start(1);
2337                pelaajat[0].Animation.FPS = pelaajat[0].Animation.FrameCount / pelaajat[0].ValittuAse.LataukseenKuluvaAika;
2338            }
2339            Timer.SingleShot(pelaajat[0].ValittuAse.LataukseenKuluvaAika, delegate { Lataa(pelaajat[0]); });
2340        }, null);
2341        Keyboard.Listen(Key.LeftShift, Jypeli.ButtonState.Pressed, delegate { pelaajat[0].Nopeus = 450.0; ;}, null);
2342        Keyboard.Listen(Key.LeftShift, Jypeli.ButtonState.Released, delegate { pelaajat[0].Nopeus = 300.0; ;}, null);
2343        Mouse.ListenWheel(delegate { VaihdaAsetta(pelaajat[0]); }, null);
2344        Mouse.Listen(MouseButton.Left, Jypeli.ButtonState.Down, delegate {
2345            if (pelaajat[0].ValittuAse.BulletsPerShot != 1) AmmuHaulikolla(pelaajat[0], pelaajat[0].ValittuAse.BulletsPerShot);
2346            else Ammu(pelaajat[0]);
2347        }, null);
2348        Mouse.Listen(MouseButton.Right, Jypeli.ButtonState.Pressed, HeitaKranaatti, null, pelaajat[0]);
2349        Mouse.ListenMovement(0.1, LiikutaTahtainta, null, pelaajat[0]);
2350
2351        Keyboard.Listen(Key.RightControl, ButtonState.Pressed, delegate { MessageDisplay.Add(pelaajat[0].Position.ToString()); }, null);
2352
2353        // Pelaajan 2 ohjaimet
2354        ControllerOne.ListenAnalog(AnalogControl.LeftStick, 0.1, LiikutaPelaajaaPadilla, null, pelaajat[1]);
2355        ControllerOne.Listen(Button.LeftStick, Jypeli.ButtonState.Pressed, delegate { pelaajat[1].Nopeus = 450.0; }, null);
2356        ControllerOne.Listen(Button.LeftStick, Jypeli.ButtonState.Released, delegate { pelaajat[1].Nopeus = 300.0; }, null);
2357        ControllerOne.ListenAnalog(AnalogControl.RightStick, 0.1, LiikutaTahtaintaPadilla, null, pelaajat[1]);
2358        ControllerOne.Listen(Button.RightTrigger, Jypeli.ButtonState.Down, delegate{
2359            if (pelaajat[1].ValittuAse.BulletsPerShot != 1) AmmuHaulikolla(pelaajat[1], pelaajat[1].ValittuAse.BulletsPerShot);
2360            else Ammu(pelaajat[1]);
2361        }, null);
2362        ControllerOne.Listen(Button.LeftTrigger, Jypeli.ButtonState.Pressed, HeitaKranaatti, null, pelaajat[1]);
2363        ControllerOne.Listen(Button.LeftShoulder, Jypeli.ButtonState.Pressed, delegate { VaihdaAsetta(pelaajat[1], -1); }, null);
2364        ControllerOne.Listen(Button.RightShoulder, Jypeli.ButtonState.Pressed, delegate { VaihdaAsetta(pelaajat[1], 1); }, null);
2365        ControllerOne.Listen(Button.X, Jypeli.ButtonState.Pressed, delegate
2366        {
2367            lippaanPoistoAani.Play(); pelaajat[1].LadataankoAsetta = true;
2368            if (pelaajat[1].ValittuAse.LatausAnimaatio1 != null)
2369            {
2370                pelaajat[1].Animation = new Animation(pelaajat[1].ValittuAse.LatausAnimaatio2);
2371                pelaajat[1].Animation.Start(1);
2372                pelaajat[1].Animation.FPS = pelaajat[1].Animation.FrameCount / pelaajat[1].ValittuAse.LataukseenKuluvaAika;
2373            }
2374            Timer.SingleShot(pelaajat[1].ValittuAse.LataukseenKuluvaAika, delegate { Lataa(pelaajat[1]); });
2375        }, null);
2376        ControllerOne.Listen(Button.A, Jypeli.ButtonState.Pressed, delegate { pelaajat[1].tahtain.Position = pelaajat[1].Position; }, null);
2377    }
2378
2379    /// <summary>
2380    /// Otetaan käyttöön sandbox-lisäohjaimet.
2381    /// </summary>
2382    void AsetaSandboxOhjaimet()
2383    {
2384        Keyboard.Listen(Key.Space, ButtonState.Pressed, delegate { LuoTuhoutuvaKentanOsa(pelaajat[0].tahtain.Position, 50, 50, null, kivenKuva, "kivi", 20, 1.0, 1.0); }, null);
2385        Keyboard.Listen(Key.K, ButtonState.Pressed, delegate { LuoKillBall(pelaajat[0].tahtain.Position); }, null);
2386        Keyboard.Listen(Key.T, ButtonState.Pressed, delegate { LuoTynnyri(pelaajat[0].tahtain.Position, 50.0, 50.0, null); }, null);
2387        ControllerOne.Listen(Button.B, ButtonState.Pressed, delegate { LuoTuhoutuvaKentanOsa(pelaajat[1].tahtain.Position, 50, 50, null, kivenKuva, "kivi", 20, 1.0, 1.0); }, null);
2388    }
2389
2390    #endregion
2391
2392    #region aseiden osumat
2393
2394    /// <summary>
2395    /// Kutsutaan, kun singon raketti osuu johonkin.
2396    /// </summary>
2397    /// <param name="ammus">Ammus, joka osuu.</param>
2398    /// <param name="kohde">Kohde, johon osutaan.</param>
2399    public void SingonAmmusRajahtaa(PhysicsObject ammus, PhysicsObject kohde)
2400    {
2401        Explosion sinkopaineaalto = new Explosion(200);
2402        sinkopaineaalto.Position = ammus.Position;
2403        sinkopaineaalto.Image = tyhjä;
2404        sinkopaineaalto.Sound = null;
2405        sinkopaineaalto.Force = 400;
2406        sinkopaineaalto.Speed = 1000;
2407        sinkopaineaalto.ShockwaveColor = Color.Black;
2408        sinkopaineaalto.ShockwaveReachesObject += delegate(IPhysicsObject paineaallonKohde, Vector shokki) { RajahdysOsuu(paineaallonKohde, shokki, ammus.Position, Aseet.SINGON_MAKSIMI_DAMAGE); };
2409
2410        Add(sinkopaineaalto);
2411        Aseet.singonAani.Play();
2412
2413        Partikkelit.AddParticleEffect(Partikkelit.RajahdysPartikkelit1, new Vector(kohde.X, kohde.Y), 500);
2414        Partikkelit.AddParticleEffect(Partikkelit.RajahdysPartikkelit2, new Vector(kohde.X, kohde.Y), 300);
2415        ammus.Destroy();
2416
2417        valo.Position = ammus.Position;
2418        valo.Intensity = 2.0;
2419        valo.Distance = 100;
2420        Timer.SingleShot(0.2, delegate { valo.Intensity = 1.5; });
2421        Timer.SingleShot(0.3, delegate { valo.Intensity = 1.0; });
2422        Timer.SingleShot(0.4, delegate { valo.Intensity = 0.5; });
2423        Timer.SingleShot(0.5, delegate { valo.Intensity = 0.0; });
2424    }
2425
2426    /// <summary>
2427    /// Lasketaan räjähdyksen aiheuttama vahinko etäisyyden mukaan.
2428    /// </summary>
2429    /// <param name="rajahdyksenKeskiPiste">Räjähdyksen keskipiste.</param>
2430    /// <param name="kohde">Kohde, johon räjähdys osuu.</param>
2431    /// <param name="maksimivahinko">Vahinko, jonka räjähdys tekee nollapisteessä.</param>
2432    /// <param name="nopeusJollaVahinkoVahenee">Nopeus, jolla räjähdyksen vahinko vähenee etäisyyden kasvaessa. Suurempi luku hidastaa, pienempi nopeuttaa.</param>
2433    /// <returns>Vahinko.</returns>
2434    double LaskeRajahdyksenDamage(Vector rajahdyksenKeskiPiste, Vector kohde, double maksimivahinko, double nopeusJollaVahinkoVahenee)
2435    {
2436        double pisteidenEtaisyys = Vector.Distance(rajahdyksenKeskiPiste, kohde) / nopeusJollaVahinkoVahenee;
2437        double damage = maksimivahinko - pisteidenEtaisyys;
2438        if (damage < 0) return 0;
2439        return damage;
2440    }
2441
2442    /// <summary>
2443    /// Törmäyksenkuuntelija räjähdyksille.
2444    /// </summary>
2445    /// <param name="kohde">Kohde, johon räjähdys osuu.</param>
2446    /// <param name="shokki">Pakollinen parametri.</param>
2447    void RajahdysOsuu(IPhysicsObject kohde, Vector shokki, Vector rajahdyksenAlkamisPiste, double maksimivahinko)
2448    {
2449        double todellinenVahinko = LaskeRajahdyksenDamage(rajahdyksenAlkamisPiste, kohde.Position, maksimivahinko, 8);
2450        if (todellinenVahinko == 0) return;
2451
2452        if (kohde is Tuhoutuva)
2453        {
2454            //Partikkelit.AddParticleEffect(Partikkelit.KiviHajoaa, new Vector(kohde.X, kohde.Y), 50);
2455            //Partikkelit.AddParticleEffect(Partikkelit.PuuHajoaa, new Vector(kohde.X, kohde.Y), 50);
2456            if (kohde != null) Damagea(kohde as Tuhoutuva, todellinenVahinko);
2457        }
2458
2459        if (kohde is Elava)
2460        {
2461            Elava kohdePelaaja = kohde as Elava;
2462            Partikkelit.AddParticleEffect(Partikkelit.VeriPartikkelit, new Vector(kohde.X, kohde.Y), 40);
2463            GameObject[] effects = Blood.AddNormalBlood(kohde.Position, 3, 0.3);
2464            foreach (GameObject blood in effects)
2465            {
2466                LisaaTehosteObjekti(blood);
2467            }
2468            Damagea(kohdePelaaja, todellinenVahinko);
2469        }
2470    }
2471    #endregion
2472}
Note: See TracBrowser for help on using the repository browser.