source: 2015/24/ohjaajat/Dungeon/Dungeon/Dungeon/Dungeon.cs @ 6099

Revision 6099, 32.9 KB checked in by empaheik, 4 years ago (diff)

Kultuurihuoneet eriarvoisia. Barbaarien määrä ja ilmestymistiheys vaihtelee vähän.

RevLine 
[5927]1using System;
2using System.Linq;
3using System.Collections.Generic;
4using Jypeli;
5using Jypeli.Assets;
6using Jypeli.Controls;
7using Jypeli.Effects;
8using Jypeli.Widgets;
9using Point = Microsoft.Xna.Framework.Point;
10
[6005]11/* Tässä on jotain dokumentaation tapaista:
12 *
13 * Layerit
14 *   3 - Kaivuunuoli ja partikkeliefektit
15 *   2 - Partikkelien varjot
16 *   1 - Huoneiden katto
17 *   0 - Huoneiden seinät ja barbaarit
18 *  -1 - Päivitykset
19 *  -2 - Huone (eli lattiat siis)
[6046]20 * 
21 * Ideoita:
22 *  - Pahempia vihollisia, joihin ei tehoa piikkiansat
23 *    vaan pitää ostaa kalliimpia ansoja niitä varten.
[6093]24 *  - Kultuurihuoneita, jotka tuottavat eriäviä määriä
25 *    kultuuria tai kestävät yhden barbaarin iskun.
[6005]26*/
27
28/// <summary>
29/// Päivitys joka voi olla huoneessa.
30/// </summary>
[6034]31public abstract class Upgrade : GameObject
[6005]32{
33    public int Price { get; set; }
34
[6040]35    protected Upgrade()
[6005]36        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
37    {
38    }
39
40    /// <summary>
41    /// Tätä kutsutaan kun päivitys on rakennettu huoneeseen.
42    /// </summary>
43    public virtual void Built(Dungeon peli) { }
[6035]44
45    /// <summary>
[6042]46    /// Tätä kutsutaan kun barbaari tulee kylään.
[6035]47    /// </summary>
48    public virtual void Invasion(Dungeon peli, Barbaari barbaari, Room huone) { }
[6042]49
50    /// <summary>
51    /// Kutsutaan joka syklin alussa.
52    /// </summary>
53    public virtual void SykliPaivitys() { }
[6005]54}
55
56class TrapUpgrade : Upgrade
57{
58    public int Damage { get; set; }
[6035]59
[6043]60    public bool Active
61    {
[6042]62        get { return LatausMittari.Value == LatausMittari.MaxValue; }
63    }
64
65    // Jos täynnä, niin ansa on aktiivinen.
66    public IntMeter LatausMittari { get; set; }
67
68    public TrapUpgrade()
69    {
70        LatausMittari = new IntMeter(4, 0, 4);
71        LatausMittari.UpperLimit += delegate
72        {
73            // Askelletaan vikasta framesta ekaan.
74            Animation.Step();
75        };
76    }
77
[6035]78    public override void Invasion(Dungeon peli, Barbaari barbaari, Room huone)
79    {
[6042]80        if (!Active) return;
81
[6093]82        barbaari.Tenacity.Value -= ((TrapUpgrade)(huone.Upgrade)).Damage;
83
[6037]84        peli.Splatter(huone.Position);
[6039]85
[6042]86        // Barbaarin tappo pudottaa latausmittarin nollaan.
87        LatausMittari.Value = LatausMittari.MinValue;
[6039]88
[6042]89        Animation.StopOnLastFrame = true;
90        Animation.Start(1);
91    }
92
93    public override void SykliPaivitys()
94    {
95        base.SykliPaivitys();
96        if (LatausMittari.Value < LatausMittari.MaxValue)
[6039]97        {
[6043]98            LatausMittari.Value++;
[6039]99        }
[6035]100    }
[6005]101}
102
103class CultureUpgrade : Upgrade
104{
105    // Tämän päivityksen antama kultuurin määrä.
106    public IntMeter Culture { get; set; }
[6099]107    public int Max { get; set; } //Kultuurimittarin maksimiarvo
[6005]108
109    // Label joka näyttää päivityksen antaman kultuurin määrän.
110    public Label KultuuriNaytto { get; set; }
111
112    public override void Built(Dungeon peli)
113    {
114        base.Built(peli);
115
[6099]116        Culture = new IntMeter(0, 0, Max);
[6005]117
118        // Luodaan kultuurin ilmaisin.
119        KultuuriNaytto = new Label("asd");
120        KultuuriNaytto.TextColor = Color.HotPink;
121        KultuuriNaytto.Color = Color.Black;
[6045]122        KultuuriNaytto.Position = peli.Camera.WorldToScreen(this.Position + new Vector(0, Dungeon.RUUDUN_KOKO * 0.5));
[6005]123        KultuuriNaytto.BindTo(Culture);
124        peli.Add(KultuuriNaytto);
125
126        // Näytetään kultuurin määrä kun hiiri on päivityksen päällä.
127        var kuuntelija = peli.Mouse.ListenMovement(0.1, _ => KultuuriNaytto.IsVisible = peli.Mouse.IsCursorOn(this), null);
128
129        this.Destroyed += delegate
130        {
131            KultuuriNaytto.Destroy();
132            kuuntelija.Destroy();
133        };
134    }
[6035]135
136    public override void Invasion(Dungeon peli, Barbaari barbaari, Room huone)
137    {
138        this.Destroy();
[6042]139        huone.Upgrade = null;
140        if (peli.KultuuriHuoneidenPaikat().Count < 1)
[6035]141        {
142            peli.LopetaPeli();
143        }
144    }
[6005]145}
146
[6034]147public class Room : GameObject
[5927]148{
149    // Sijainti pelin ruudukossa.
150    public Point Location { get; set; }
151
152    // Päällä näkyvä "katto" kun huone ei ole vielä kaivettu.
153    public GameObject Roof { get; set; }
154
155    // Neljä seinää, jotka on GameObjekteja.
156    public Dictionary<Direction, GameObject> Walls { get; set; }
157
[6005]158    // Huoneen sisältämä päivitys.
159    public Upgrade Upgrade { get; set; }
[5966]160
[5927]161    private bool dug; // Onko huone kaivettu?
162    public bool Dug
163    {
164        get { return dug; }
165        set
166        {
167            dug = value;
168            Roof.IsVisible = !Dug;
169        }
170    }
171
172    public Room(Point paikka)
173        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
174    {
175        Walls = new Dictionary<Direction, GameObject>();
176        Location = paikka;
177    }
178}
179
[6007]180public class Barbaari : GameObject
181{
[6031]182    public List<Point> Reitti { get; set; }
[6035]183
[6042]184    public Point Kohde { get; set; }
[6040]185
186    public Point Location { get; set; }
187
[6093]188    public IntMeter Tenacity { get; set; }
189
[6007]190    public Barbaari(double width, double height)
[6093]191        : this(width, height, 0, new Image[1])
[6031]192    {
193        Reitti = new List<Point>();
194    }
[6093]195
196    public Barbaari(double width, double height, int tenacity, Image[] animaatio) : base(width, height)
197    {
[6096]198        this.Animation = new Animation(animaatio) { FPS = 8 };
[6093]199        this.Tenacity = new IntMeter(tenacity, 0, 2);
200
201    }
[6007]202}
203
[5927]204public class Dungeon : PhysicsGame
205{
206    public const int RUUDUN_KOKO = 64;
207
[6091]208    public static Func<int, int, string, Image[]> LoadImages2 = (a, b, fmt) =>
209        LoadImages((from i in Enumerable.Range(a, b) select string.Format(fmt, i)).ToArray());
210
[5966]211    #region Kuvat
[5927]212    Image lattiaKuva = LoadImage("floor");
213    Image seinaKuva = LoadImage("wall");
214    Image reikaSeinaKuva = LoadImage("wallhole");
215    Image kiviKuva = LoadImage("rock");
[6034]216    Image[] kultuuriKuvat = LoadImages("nyan", "es", "spurdo");
[6091]217    private Image[] piikkiAnsaKuvat = LoadImages2(1, 7, "piikit/piikit{0:0000}");
218    private Image[] murskausAnsaKuvat = LoadImages2(1, 9, "smash/smash{0:0000}");
219    public Image[] vihuKuvat = LoadImages2(1, 10, "vihu/v{0:0000}");
220    public Image[] kirvesVihuKuvat = LoadImages2(1, 10, "kirvesvihu/kv{0:0000}");
[6083]221    Image[] ansaKuvat;
[6093]222    List<Animation> ansaAnimaatiot = new List<Animation>();
[6040]223    Image partikkeliKuva = LoadImage("partikkeli");
[6038]224    Image taideVeri = LoadImage("taideveri");
[5970]225    #endregion
[5927]226
[6099]227    int[] hinnat = { 75, 200, 300, 100 };
[6097]228    int[] vahingot = { 1, 2 };
[6083]229    int[] ansaHinnat = { 400, 800 };
[6099]230    int[] kultuuriTuotot = { 100, 200, 400 };
[6039]231    private int barbaariMaara = 2;
[5966]232
[6041]233    private Label kierrosIlmaisin;
[6093]234    //private bool kierrosKaynnissa;
235    private int kierros;
236
237    public int KierrosKaynnissa
[6041]238    {
239        get
240        {
[6093]241            return kierros;
[6041]242        }
243        set
244        {
[6093]245            kierros = value;
246            kierrosIlmaisin.Text = "Vaihe: " + (kierros % 2 == 0 ? "Barbaari-invaasio" : "Rakennusvaihe");
[6041]247        }
248    }
[6039]249
[5927]250    Room[,] huoneet;
[6042]251    //public List<Room> kohteet = new List<Room>();
[6099]252    public List<Barbaari> barbaarit;
[5966]253    Room spawn;
[6099]254    Timer barbaariAjastin;
255    Timer sykliAjastin;
[6005]256    Upgrade ostamassa;
[5927]257    Point digStart; // Huoneen sijainti, josta kaivuu aloitetaan.
258    bool digging = false;
259
[5967]260    GameObject digArrow;
261    GameObject digArrowHead;
262
[6099]263    IntMeter kultuuri = new IntMeter(0, 0, 2000);
[5966]264
[6099]265    const int MASSI = 1500;
[6034]266    const int VAAKA_HUONEET = 12;
267    const int PYSTY_HUONEET = 8;
[5966]268
[6005]269    // Paljonko peliruudukko on siirtynyt origosta.
[6045]270    Vector huoneSiirtyma = new Vector(-200, 0);
[6005]271
[6084]272    private MainMenu menu;
273
[5927]274    public override void Begin()
275    {
[6093]276        ClearAll();
[6099]277
278        kultuuri.Value = MASSI;
279        kierros = 0;
280        barbaariAjastin = new Timer();
281        barbaarit = new List<Barbaari>();
282
[6088]283        SmoothTextures = false;
[6084]284        IsMouseVisible = true;
[6092]285
[6095]286        //SetWindowSize(1024, 768); // Riippuu Jypelin versiosta.
[6092]287        Window.Width = 1024;
288        Window.Height = 768;
289
[6084]290        ansaKuvat = new Image[] {piikkiAnsaKuvat[0], murskausAnsaKuvat[0]};
[6093]291        ansaAnimaatiot.Add(new Animation(piikkiAnsaKuvat));
292        ansaAnimaatiot.Add(new Animation(murskausAnsaKuvat));
[6084]293        menu = new MainMenu(this, "New game", "Highscores", "Help", "Quit");
294        menu.Painikkeet[0].Clicked += AloitaPeli;
295        menu.Painikkeet[3].Clicked += Exit;
296    }
[6045]297
[6084]298    void AloitaPeli()
299    {
[5927]300        ClearAll();
[6092]301        MediaPlayer.Play("In_The_Dark_Flashes");
[5966]302        Kontrollit();
303        UlkoAsuRoskaa();
304        Kauppa();
[5968]305        Nuoli();
[5927]306
307        // Luodaan huoneet ruutuihin.
[6034]308        huoneet = new Room[VAAKA_HUONEET, PYSTY_HUONEET];
[5927]309        foreach (var paikka in RuutujenPaikat())
310        {
311            var huone = CreateRoom(paikka);
312            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, () => RoomPressed(huone), null);
313            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Released, () => RoomReleased(huone), null);
[6048]314            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, AsetaPaivitys, "Asetetaan ostettu päivitys paikoilleen", huone);
315            Mouse.Listen(MouseButton.Right, ButtonState.Pressed, delegate { ostamassa = null; }, "Perutaan ostos");
316            Mouse.ListenOn(huone, MouseButton.Right, ButtonState.Pressed, PoistaPaivitys, "Poistetaan asetettu päivitys", huone);
[5927]317            huoneet[paikka.X, paikka.Y] = huone;
318        }
319
[5965]320        LuoSpawn();
321
[6099]322        sykliAjastin = new Timer { Interval = 1.0 };
[6031]323        sykliAjastin.Timeout += Sykli;
324        sykliAjastin.Start();
325
[6040]326        barbaariAjastin.Timeout += LuoBarbaareja;
[6099]327        barbaariAjastin.Interval = sykliAjastin.Interval;   //TODO: säätöjä tähän, barbaarien määrään ja superbarbaarien todennäköisyyteen, kunnes peli tuntuu mielekkäältä
[6045]328
329        Level.Width = 1300;
330        Camera.ZoomToLevel();
[5966]331    }
332
[5968]333    void Nuoli()
[5966]334    {
[5968]335        digArrow = new GameObject(5, 5);
336        digArrowHead = new GameObject(15, 15);
337        digArrowHead.Shape = Shape.Triangle;
338        digArrowHead.IsVisible = digArrow.IsVisible = false;
339        Add(digArrow, 3);
340        Add(digArrowHead, 3);
341    }
[5966]342
[5968]343    void UlkoAsuRoskaa()
344    {
[5966]345        Level.Background.Color = Color.Black;
346
[6041]347        kierrosIlmaisin = new Label("asd");
348        kierrosIlmaisin.TextColor = Color.White;
349        kierrosIlmaisin.Y = Screen.Top - 150;
350        Add(kierrosIlmaisin);
351        KierrosKaynnissa = KierrosKaynnissa; // Aiheuttaa labelin päivittymisen.
352
[5966]353        Label rahat = new Label();
[6039]354        rahat.BindTo(kultuuri);
[6045]355        rahat.Position = new Vector(Screen.Right - 200, Screen.Bottom + 50);
356        //rahat.Position = new Vector(Level.Right + Level.Width * 0.2, Level.Bottom + Level.Height * 0.1);
[5966]357        rahat.TextColor = Color.White;
358        rahat.IntFormatString = "Käytettävää kulttuuria: {0:D3}";
359        Add(rahat);
360    }
361
[6035]362    public void LopetaPeli()
363    {
364        ClearAll();
365        GameObject spurdo = new GameObject(Screen.Width, Screen.Height);
366        spurdo.Image = kultuuriKuvat[2];
367        Add(spurdo);
368
369        Label havisit = new Label("Hävisit muuten belin");
370        havisit.Color = Color.HotPink;
371        havisit.Size = new Vector(300, 300);
[6093]372        havisit.Position = new Vector(Level.Right - havisit.Width, Level.Top - havisit.Height * 0.5);
373        Add(havisit, 2);
[6035]374    }
375
[5966]376    void Kauppa()
377    {
[6005]378        for (int i = 0; i < kultuuriKuvat.Length; i++)
[5966]379        {
[6005]380            PushButton kuva = new PushButton(kultuuriKuvat[i]);
381            kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
[6045]382            kuva.X = Window.ClientBounds.Width / 2 - 200;
383            kuva.Y = Window.ClientBounds.Height / 2 - (100 + RUUDUN_KOKO * i);
384            //kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - (i * RUUDUN_KOKO)));
385            //kuva.Position = new Vector(Window.ClientBounds.Right, 0);
[6005]386            Add(kuva);
387
388            int indeksi = i; // Alla oleva delegaatti vaatii uuden indeksi muuttujan toimiakseen.
389            kuva.Clicked += delegate
390            {
[6099]391                ostamassa = LuoKultuuriPaivitys(kultuuriKuvat[indeksi], hinnat[indeksi], kultuuriTuotot[indeksi]);   // TODO: tuotto[indeksi]
[6005]392            };
[6067]393             
[6040]394            Add(new Label
395            {
396                Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
397                TextColor = Color.White,
398                Text = hinnat[i].ToString()
399            });
[6035]400        }
[6034]401
[6099]402        for (int i = 0; i < ansaKuvat.Length; i++) 
[6035]403        {
[6036]404            PushButton kuva = new PushButton(ansaKuvat[i]);
[6035]405            kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
[6036]406            kuva.Color = Color.Gray;
[6045]407            kuva.X = Window.ClientBounds.Width / 2 - 200;
408            kuva.Y = Window.ClientBounds.Height / 2 - (100 + RUUDUN_KOKO * (kultuuriKuvat.Count() + i));
409            //kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - ((kultuuriKuvat.Count() + i) * RUUDUN_KOKO)));
[6035]410            Add(kuva);
[6036]411
412            int indeksi = i;
413            kuva.Clicked += delegate
414            {
[6099]415                ostamassa = LuoAnsaPaivitys(ansaKuvat[indeksi], ansaHinnat[indeksi], ansaAnimaatiot[indeksi], vahingot[indeksi]);
[6036]416            };
417
[6040]418            Add(new Label
419            {
420                Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
421                TextColor = Color.White,
[6043]422                Text = ansaHinnat[i].ToString()
[6040]423            });
[6099]424        } 
[5966]425    }
426
[6097]427    private void LuoAnsaHuoneenPainike(Image image, int hinta, Animation animation, int paikka, int vahinko)
[6036]428    {
[6093]429        PushButton kuva = new PushButton(image);
430        kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
431        kuva.Color = Color.Gray;
432        kuva.X = Window.ClientBounds.Width / 2 - 200;
433        kuva.Y = Window.ClientBounds.Height / 2 - (100 + RUUDUN_KOKO * (kultuuriKuvat.Count() + paikka));
434        //kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - ((kultuuriKuvat.Count() + i) * RUUDUN_KOKO)));
435        Add(kuva);
436
437        kuva.Clicked += delegate
438        {
[6097]439            ostamassa = LuoAnsaPaivitys(image, hinta, animation, vahinko);
[6093]440        };
441
442        Add(new Label
443        {
444            Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
445            TextColor = Color.White,
446            Text = hinta.ToString()
447        });
448    }
449
450
451
[6097]452    Upgrade LuoAnsaPaivitys(Image kuva, int hinta, Animation animaatio, int vahinko)
[6093]453    {
[6040]454        return new TrapUpgrade
455        {
456            Image = kuva,
457            Size = new Vector(0.5, 0.5) * RUUDUN_KOKO,
458            Price = hinta,
[6097]459            Damage = vahinko,
[6093]460            Animation = new Animation(animaatio)
[6040]461        };
[6036]462    }
463
[6099]464    Upgrade LuoKultuuriPaivitys(Image kuva, int hinta, int kultuuriMaara)
[6005]465    {
[6040]466        return new CultureUpgrade
467        {
468            Image = kuva,
469            Size = new Vector(0.5, 0.5) * RUUDUN_KOKO,
[6099]470            Price = hinta,
471            Max = kultuuriMaara
[6040]472        };
[6005]473    }
474
[5966]475    void LuoBarbaareja()
476    {
[6099]477        Barbaari barbaari = ((RandomGen.NextInt((int)(kierros * 0.90)) + 3 > kierros) ? new Barbaari(RUUDUN_KOKO * 0.4, RUUDUN_KOKO * 0.4, 1, vihuKuvat) : new Barbaari(RUUDUN_KOKO * 0.4, RUUDUN_KOKO * 0.4, 2, kirvesVihuKuvat));
[6093]478        barbaari.Tenacity.LowerLimit += delegate
479        {
480            barbaarit.Remove(barbaari);
481            barbaari.Destroy();
482        };
483        //Barbaari barbaari = new Barbaari(RUUDUN_KOKO * 0.4, RUUDUN_KOKO * 0.4, 0);
[5966]484        barbaari.Color = Color.Red;
485        barbaari.Position = spawn.Position;
[6093]486        barbaari.Location = spawn.Location;
487        //barbaari.Animation = new Animation(vihuKuvat) { FPS = 10 };
[5970]488        barbaari.Animation.Start();
[5966]489        Add(barbaari);
[6031]490        barbaarit.Add(barbaari);
[6093]491           
[6007]492        EtsiBarbaarinReitti(barbaari);
[5966]493    }
494
[6007]495    void EtsiBarbaarinReitti(Barbaari barbaari)
496    {
[6042]497        var kohteet = KultuuriHuoneidenPaikat();
[6034]498        barbaari.Kohde = kohteet[RandomGen.NextInt(kohteet.Count)];
[6042]499        barbaari.Reitti = FindPath(barbaari.Kohde, (barbaari.Location.Equals(spawn.Location)) ? spawn.Location : barbaari.Location);
[6031]500    }
[6007]501
[6042]502    public List<Point> KultuuriHuoneidenPaikat()
503    {
504        return RuutujenPaikat().Select(GetRoom).Where(r => r.Upgrade != null && r.Upgrade is CultureUpgrade).Select(r => r.Location).ToList();
505    }
506
[6031]507    void Sykli()
508    {
[6042]509        // Päivitetään huoneiden päivityksiä.
510        RuutujenPaikat().Select(GetRoom).Where(r => r.Upgrade != null).ToList().ForEach(r => r.Upgrade.SykliPaivitys());
511
512        // Päivitetään barbaareja.
[6031]513        foreach (var barbaari in barbaarit)
514        {
515            if (barbaari.Reitti.Count == 0)
516            {
[6042]517                EtsiBarbaarinReitti(barbaari);  //Etsitään uusi reitti poiston sijaan.
518                continue;
[6031]519            }
520
521            Point seuraavaPaikka = barbaari.Reitti[0];
522            barbaari.Reitti.RemoveAt(0);
[6040]523            Barbaari b = barbaari;
524            barbaari.MoveTo(huoneet[seuraavaPaikka.X, seuraavaPaikka.Y].Position, 100, () => SyklinPaatteeksi(b, seuraavaPaikka));
[6031]525        }
[6041]526
527        // Tarkistetaan onko barbaariaalto jo ohi.
[6093]528        if (KierrosKaynnissa % 2 == 0 && barbaarit.Count == 0 && barbaariAjastin.Times == barbaariAjastin.Times.MinValue)
[6041]529        {
[6093]530            KierrosKaynnissa++;
[6043]531
532            // Annetaan pelaajalle kultuuripisteet.
533            foreach (var huone in KultuuriHuoneidenPaikat().Select(GetRoom))
534            {
535                CultureUpgrade upg = huone.Upgrade as CultureUpgrade;
536                if (upg == null)
537                    continue;
[6045]538
[6043]539                kultuuri.Value += upg.Culture;
540                Label ilmoitus = new Label("+" + upg.Culture);
541                ilmoitus.TextColor = Color.HotPink;
542                ilmoitus.Color = Color.Black;
543                ilmoitus.Position = Camera.WorldToScreen(huone.Position);
544                Add(ilmoitus);
545
546                double kohdeY = ilmoitus.Y + 50;
547                var liikutusAjastin = new Timer();
548                liikutusAjastin.Interval = 0.02;
549                liikutusAjastin.Timeout += delegate
550                {
[6045]551                    ilmoitus.Y += (kohdeY - ilmoitus.Y) * 0.05;
[6043]552                };
553                liikutusAjastin.Start();
554
555                ilmoitus.LifetimeLeft = TimeSpan.FromSeconds(2.0);
556                ilmoitus.Destroyed += liikutusAjastin.Stop;
557            }
[6041]558        }
[6007]559    }
560
[6031]561    void SyklinPaatteeksi(Barbaari barbaari, Point uusiPaikka)
562    {
563        // Barbaari saapui juuri uusiPaikka kohdassa olevaan huoneeseen.
564        // Tässä pitäisi katsoa mitä huoneessa tapahtuu.
[6034]565        barbaari.Location = uusiPaikka;
566
567        Room huone = huoneet[uusiPaikka.X, uusiPaikka.Y];
568
[6035]569        if (huone.Upgrade != null)
[6034]570        {
[6035]571            huone.Upgrade.Invasion(this, barbaari, huone);
[6034]572        }
[6031]573    }
574
[5966]575    void Kontrollit()
576    {
577        IsMouseVisible = true;
[6093]578        //Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Näytä valikko");
579        //Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
[6099]580        Keyboard.Listen(Key.Escape, ButtonState.Pressed, delegate { ClearAll(); Begin(); }, "Aloita uudestaan");    //Ei toimi vielä
[5966]581
582        Keyboard.Listen(Key.Space, ButtonState.Pressed, SeuraavaAalto, "Anna kivan barbaariaallon tulla");
[5927]583    }
584
[6047]585    void SeuraavaAalto()       
[5966]586    {
[6093]587        if (KultuuriHuoneidenPaikat().Count == 0 || KierrosKaynnissa % 2 == 0) return;
[6040]588
[6099]589        barbaariAjastin.Interval = RandomGen.NextInt((int)sykliAjastin.Interval, 3);
[6040]590        barbaariAjastin.Start(barbaariMaara);
[6099]591        barbaariMaara = RandomGen.NextInt((int)(1 + kierros * 0.20), kierros);
[6093]592        KierrosKaynnissa++;
[5966]593    }
594
[5965]595    void LuoSpawn()
596    {
[5966]597        spawn = huoneet[(int)(huoneet.GetLength(0) * 0.5), 0];
598        spawn.Dug = true;
[5965]599
[6005]600        Direction oviSuunta = Direction.Down;
[5966]601        spawn.Walls[oviSuunta].Image = reikaSeinaKuva;
602
[6047]603        spawn.Upgrade = new TrapUpgrade();      //TODO: Parempi tapa varmistaa, että spawniin ei pysty rakentamaan mitään? Oma upgradetyyppi?
604        TrapUpgrade upg = spawn.Upgrade as TrapUpgrade;
605        upg.LatausMittari = new IntMeter(0, 0, 0);
606
[5966]607        Light valo = new Light();
608        valo.Position = spawn.Position;
609        valo.Intensity = 1;
610        valo.Distance = 40;
611        Add(valo);
[5965]612    }
613
[5927]614    void RoomPressed(Room huone)
615    {
616        digStart = huone.Location;
617        digging = true;
[5967]618        digArrowHead.IsVisible = digArrow.IsVisible = true;
[5927]619    }
620
621    void RoomReleased(Room kohdeHuone)
622    {
623        digging = false;
[5967]624        digArrowHead.IsVisible = digArrow.IsVisible = false;
[6040]625        if (!CanDig()) return;
[6035]626
[6040]627        int dx = kohdeHuone.Location.X - digStart.X;
628        int dy = kohdeHuone.Location.Y - digStart.Y;
629        Point[] kaivettavatPaikat = RuudutSuoralta(digStart, dx, dy).ToArray();
630        for (int i = 0; i < kaivettavatPaikat.Length - 1; i++)
631        {
632            Dig(GetRoom(kaivettavatPaikat[i]), GetRoom(kaivettavatPaikat[i + 1]));
[5927]633        }
[6040]634
635        // Päivitetään huoneiden kultuuri-infot.
636        PaivitaHuoneidenKultuurit();
[5927]637    }
638
[6006]639    void Dig(Room alku, Room kohde)
640    {
641        // Hienot partikkeliefektit.
642        if (!alku.Dug)
643            LuoKiviPartikkelit(alku.Position);
644        if (!kohde.Dug)
645            LuoKiviPartikkelit(kohde.Position);
646
[6092]647        // Merkataan huoneet kaivetuksi ja maksetaan siitä kivasti.
[6006]648        alku.Dug = kohde.Dug = true;
[6092]649        kultuuri.Value -= 50;
[6006]650
651        // Reiät seinään.
652        Direction oviSuunta = (kohde.Position - alku.Position).Angle.MainDirection;
653        Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
654        alku.Walls[oviSuunta].Image = reikaSeinaKuva;
655        kohde.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
656    }
657
[5927]658    Room CreateRoom(Point paikka)
659    {
660        Room huone = new Room(paikka);
661        huone.Image = lattiaKuva;
662        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
[6005]663        huone.Position += huoneSiirtyma;
[5927]664        foreach (var suunta in Suunnat())
665            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
[6005]666        Add(huone, -2);
[5927]667        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
668        huone.Roof.Image = kiviKuva;
669        huone.Roof.Position = huone.Position;
[5967]670        Add(huone.Roof, 1);
[5966]671
[6048]672        //Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, AsetaPaivitys, "Asetetaan ostettu päivitys paikoilleen", huone);
673        //Mouse.Listen(MouseButton.Right, ButtonState.Pressed, delegate { ostamassa = null; }, "Perutaan ostos");
674        //Mouse.ListenOn(huone, MouseButton.Right, ButtonState.Pressed, PoistaPaivitys, "Poistetaan asetettu päivitys", huone);
[5966]675
[5927]676        return huone;
677    }
678
[6035]679    private void PoistaPaivitys(Room huone)
680    {
681        if (huone.Upgrade != null)
682        {
[6047]683            kultuuri.Value += (int)(huone.Upgrade.Price * 0.5);
[6035]684            huone.Upgrade.Destroy();
[6047]685            huone.Upgrade = null;
[6035]686        }
687    }
688
[6005]689    void AsetaPaivitys(Room huone)
[5966]690    {
[6047]691        if (ostamassa != null && huone.Dug && kultuuri.Value >= ostamassa.Price && huone.Upgrade == null) //Varmistetaan, että kahta päivitystä ei laiteta päällekäin
[5966]692        {
[6039]693            kultuuri.Value -= ostamassa.Price;
[6005]694
695            // Lisätään päivitys huoneeseen.
696            huone.Upgrade = ostamassa;
697            Add(huone.Upgrade, -1);
698            huone.Upgrade.Position = huone.Position;
699            huone.Upgrade.Built(this);
700
701            ostamassa = null;
702            PaivitaHuoneenKultuuri(huone);
[5966]703        }
704    }
705
[6005]706    void PaivitaHuoneidenKultuurit()
707    {
[6040]708        RuutujenPaikat().Select(GetRoom).ToList().ForEach(PaivitaHuoneenKultuuri); // :D ;___;; MIKSI <- koska pystyn
[6005]709    }
710
[6099]711    void PaivitaHuoneenKultuuri(Room room)  //TODO: muokkauksia tuohon kultuurinarvonvaihtoon polun pituuden perusteella kunnes peli tuntuu oikeasti miellyttäviltä.
[6005]712    {
713        if (room != null && room.Upgrade != null && room.Upgrade is CultureUpgrade)
714        {
715            var upg = room.Upgrade as CultureUpgrade;
716
717            List<Point> polku = FindPath(room.Location, spawn.Location);
[6099]718            upg.Culture.Value = Math.Max(0, upg.Culture.MaxValue - (int)(upg.Culture.MaxValue * 0.10 * polku.Count));
[6005]719        }
720    }
721
[5927]722    GameObject CreateWall(Vector paikka, Direction suunta)
723    {
[5964]724        GameObject wall = new GameObject(RUUDUN_KOKO + 2, RUUDUN_KOKO + 2);
[5927]725        wall.Position = paikka;
726        wall.Image = seinaKuva;
727        wall.Angle = suunta.Angle;
[5967]728        Add(wall, 0);
[5927]729        return wall;
730    }
731
732    bool CanDig()
733    {
734        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
[6093]735        if (kohdeHuone == null || KierrosKaynnissa % 2 == 0)
[5967]736        {
737            return false;
738        }
[6006]739
[5927]740        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
741        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
[6006]742        return (dx > 0 && dy == 0) || (dy > 0 && dx == 0);
[5927]743    }
744
[5967]745    #region Reitinlöytö
746
[5969]747    List<Point> FindPath(Point alku, Point loppu)
[5967]748    {
[5969]749        if (GetRoom(alku) == null || GetRoom(loppu) == null)
750            return new List<Point>();
751
[5967]752        bool[,] walkable = new bool[huoneet.GetLength(0), huoneet.GetLength(1)];
753        foreach (var paikka in RuutujenPaikat())
754        {
755            walkable[paikka.X, paikka.Y] = huoneet[paikka.X, paikka.Y].Dug;
756        }
[6007]757        var finder = new AStar.PathFinder(new AStar.SearchParameters(loppu, alku, walkable), OviTarkistus);
[5969]758        return finder.FindPath();
[5967]759    }
760
[5969]761    bool OviTarkistus(Point a, Point b)
762    {
763        Room ra = GetRoom(a);
764        Room rb = GetRoom(b);
765        Direction suunta = (new Vector(b.X, b.Y) - new Vector(a.X, a.Y)).Angle.MainDirection;
766        if (ra != null && rb != null)
767        {
768            return ra.Walls[suunta].Image == reikaSeinaKuva && rb.Walls[Direction.Inverse(suunta)].Image == reikaSeinaKuva;
769        }
770        return false;
771    }
772
[5967]773    #endregion
774
[5927]775    #region Extra Juttuja
776
777    IEnumerable<Direction> Suunnat()
778    {
779        yield return Direction.Left;
780        yield return Direction.Right;
781        yield return Direction.Up;
782        yield return Direction.Down;
783    }
784
785    IEnumerable<Point> RuutujenPaikat()
786    {
787        return from y in Enumerable.Range(0, huoneet.GetLength(1))
788               from x in Enumerable.Range(0, huoneet.GetLength(0))
789               select new Point(x, y);
790    }
791
[6006]792    /// <summary>
793    /// Palauttaa ruutuja suoralta pätkältä dx ja dy verran alkaen pisteestä "alku".
794    /// dx tai dy pitää olla nolla.
795    /// </summary>
796    IEnumerable<Point> RuudutSuoralta(Point alku, int dx, int dy)
797    {
798        if (dx != 0)
799        {
800            for (int i = 0; i < Math.Abs(dx) + 1; i++)
801            {
802                yield return new Point(alku.X + i * Math.Sign(dx), alku.Y);
803            }
804            yield break;
805        }
806        if (dy != 0)
807        {
808            for (int i = 0; i < Math.Abs(dy) + 1; i++)
809            {
810                yield return new Point(alku.X, alku.Y + i * Math.Sign(dy));
811            }
812        }
813    }
814
[5927]815    Room GetRoom(Point paikka)
816    {
817        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
818        {
819            return huoneet[paikka.X, paikka.Y];
820        }
821        return null;
822    }
823
824    /// <summary>
825    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
826    /// </summary>
827    Point MuunnaJypelista(Vector paikka)
828    {
[6005]829        Vector siirrettyOrigo = (paikka - huoneSiirtyma) + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
[5927]830        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
831        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
832        return new Point((int)valmis.X, (int)valmis.Y);
833    }
834
[6041]835    public void LuoLentavaPartikkeli(Vector alkupaikka, Image kuva, double koko, int maara, bool veri = false)
[6005]836    {
837        // Feikki 3D partikkeli juttu.
838        // Heittää ilmaan GameObjekteja joiden alla on varjo.
[6040]839
840        // VAROITUS: SISÄLTÄÄ JÄRKYTTÄVÄÄ KOODIA
841
842        for (int i = 0; i < maara; i++)
[6005]843        {
[6040]844            GameObject partikkeli = new GameObject(koko, koko);
845            partikkeli.Image = kuva;
846            partikkeli.Position = alkupaikka + RandomGen.NextVector(0.0, RUUDUN_KOKO * 0.4);
847            Add(partikkeli, 3);
[6005]848
[6040]849            GameObject varjo = new GameObject(koko, koko / 2.0);
850            varjo.Position = partikkeli.Position;
[6005]851            varjo.Shape = Shape.Circle;
852            varjo.Color = Color.Lerp(Color.Black, Color.Transparent, 0.5);
853            Add(varjo, 2);
854
[6040]855            Vector paikka = partikkeli.Position;
[6005]856            Vector nopeus = RandomGen.NextVector(0.2, 3.0);
857            nopeus.Y *= 0.3;
858            double g = -0.2; // painovoima
859            double z = 0.0; // sijainti z-akselilla
860            double vz = RandomGen.NextDouble(3.5, 4.5); // nopeus z-akselilla
861            double angularVelocity = RandomGen.NextDouble(-1.0, 1.0) * 8;
862
[6040]863            var verenLuontiAjastin = veri ? new Timer() : null;
864
865            var ajastin = new Timer();
[6005]866            ajastin.Interval = 0.02;
867            ajastin.Timeout += delegate
868            {
869                vz += g;
870                z += vz;
871                paikka += nopeus;
[6040]872                partikkeli.Position = paikka + new Vector(0.0, 1.0) * z;
873                partikkeli.Angle += Angle.FromDegrees(angularVelocity);
[6005]874                varjo.Position = paikka;
875
876                if (z < 0.0)
877                {
878                    ajastin.Stop();
[6040]879                    partikkeli.Destroy();
[6005]880                    varjo.Destroy();
[6040]881                    if (verenLuontiAjastin != null)
882                        verenLuontiAjastin.Stop();
[6005]883                }
884            };
885            ajastin.Start();
886
[6040]887            if (verenLuontiAjastin != null)
888            {
889                verenLuontiAjastin.Interval = 0.1;
890                verenLuontiAjastin.Timeout += delegate
891                {
892                    GameObject veriPartikkeli = new GameObject(3, 3);
893                    veriPartikkeli.Color = Color.DarkRed;
894                    Add(veriPartikkeli, 2);
[6037]895
[6040]896                    Vector veriPaikka = paikka;
897                    double veriZ = z;
898                    double veriVz = 0.0;
[6037]899
[6040]900                    var veriPaivitysAjastin = new Timer();
901                    veriPaivitysAjastin.Interval = 0.02;
902                    veriPaivitysAjastin.Timeout += delegate
903                    {
904                        veriVz += g;
905                        veriZ += veriVz;
[6041]906                        veriPartikkeli.Position = veriPaikka + new Vector(0.0, 1.0) * veriZ;
[6037]907
[6040]908                        if (veriZ < 0.0)
909                        {
910                            veriPaivitysAjastin.Stop();
911                            veriPartikkeli.Destroy();
912                        }
913                    };
914                    veriPaivitysAjastin.Start();
915                };
916                verenLuontiAjastin.Start();
917            }
[6037]918        }
919    }
920
[6040]921    void LuoKiviPartikkelit(Vector alkupaikka)
922    {
923        LuoLentavaPartikkeli(alkupaikka, partikkeliKuva, 25, 6);
924    }
925
926    public void Splatter(Vector alkupaikka)
927    {
928        LuoLentavaPartikkeli(alkupaikka, taideVeri, 8, 10, true);
929    }
930
[6005]931    protected override void Update(Time time)
932    {
933        if (digging)
934        {
935            Color vari = CanDig() ? Color.White : Color.Red;
936            Vector alku = huoneet[digStart.X, digStart.Y].Position;
937            Vector loppu = Mouse.PositionOnWorld;
938            Vector suunta = loppu - alku;
939            double pituus = suunta.Magnitude;
940            if (pituus <= 2) pituus = 2;
941
942            digArrow.Color = vari;
943            digArrow.Position = alku + suunta * 0.5;
944            digArrow.Angle = suunta.Angle;
945            digArrow.Width = pituus;
946
947            digArrowHead.Color = vari;
948            digArrowHead.Position = alku + suunta;
949            digArrowHead.Angle = suunta.Angle - Angle.FromDegrees(90);
950        }
951
[6084]952        if (menu != null)
953            menu.Update(time);
[6005]954        base.Update(time);
955    }
956
[6045]957    /*
[6005]958    protected override void Paint(Canvas canvas)
959    {
960        canvas.BrushColor = Color.Purple;
961
962        var points = FindPath(new Point(6, 0), MuunnaJypelista(Mouse.PositionOnWorld));
963        for (int i = 0; i < points.Count - 1; i++)
964        {
965            Vector v = huoneSiirtyma + new Vector(points[i].X - huoneet.GetLength(0) / 2, points[i].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
966            Vector v2 = huoneSiirtyma + new Vector(points[i + 1].X - huoneet.GetLength(0) / 2, points[i + 1].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
967            canvas.DrawLine(v, v2);
968        }
969
970        base.Paint(canvas);
971    }
[6045]972    */
[6005]973
[5927]974    #endregion
975}
Note: See TracBrowser for help on using the repository browser.