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

Revision 6040, 24.5 KB checked in by sieerinn, 5 years ago (diff)
Line 
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
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)
20*/
21
22/// <summary>
23/// Päivitys joka voi olla huoneessa.
24/// </summary>
25public abstract class Upgrade : GameObject
26{
27    public int Price { get; set; }
28
29    protected Upgrade()
30        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
31    {
32    }
33
34    /// <summary>
35    /// Tätä kutsutaan kun päivitys on rakennettu huoneeseen.
36    /// </summary>
37    public virtual void Built(Dungeon peli) { }
38
39    /// <summary>
40    /// Tätä kutsutaan kun barbaari tulee kylään
41    /// </summary>
42    public virtual void Invasion(Dungeon peli, Barbaari barbaari, Room huone) { }
43}
44
45class TrapUpgrade : Upgrade
46{
47    public int Damage { get; set; }
48
49    public override void Invasion(Dungeon peli, Barbaari barbaari, Room huone)
50    {
51        peli.barbaarit.Remove(barbaari);
52        barbaari.Destroy(); //TODO: Mitä nyt oikeasti tapahtuu, kun barbaari astuu ansaan. Meidän tapauksessa kai tapetaan saman tien.
53        peli.Splatter(huone.Position);
54
55        this.Animation.Start(1);
56
57        if (peli.barbaarit.Count < 1)
58        {
59            peli.kierrosKaynnissa = false;
60            //peli.
61        }
62    }
63}
64
65class CultureUpgrade : Upgrade
66{
67    // Tämän päivityksen antama kultuurin määrä.
68    public IntMeter Culture { get; set; }
69
70    // Label joka näyttää päivityksen antaman kultuurin määrän.
71    public Label KultuuriNaytto { get; set; }
72
73    public override void Built(Dungeon peli)
74    {
75        base.Built(peli);
76
77        Culture = new IntMeter(0, 0, 1000);
78
79        // Luodaan kultuurin ilmaisin.
80        KultuuriNaytto = new Label("asd");
81        KultuuriNaytto.TextColor = Color.HotPink;
82        KultuuriNaytto.Color = Color.Black;
83        KultuuriNaytto.Position = this.Position + new Vector(0, Dungeon.RUUDUN_KOKO * 0.5);
84        KultuuriNaytto.BindTo(Culture);
85        peli.Add(KultuuriNaytto);
86
87        // Näytetään kultuurin määrä kun hiiri on päivityksen päällä.
88        var kuuntelija = peli.Mouse.ListenMovement(0.1, _ => KultuuriNaytto.IsVisible = peli.Mouse.IsCursorOn(this), null);
89
90        this.Destroyed += delegate
91        {
92            KultuuriNaytto.Destroy();
93            kuuntelija.Destroy();
94        };
95    }
96
97    public override void Invasion(Dungeon peli, Barbaari barbaari, Room huone)
98    {
99        this.Destroy();
100        peli.kohteet.Remove(huone);
101        if (peli.kohteet.Count < 1)
102        {
103            peli.LopetaPeli();
104        }
105    }
106}
107
108public class Room : GameObject
109{
110    // Sijainti pelin ruudukossa.
111    public Point Location { get; set; }
112
113    // Päällä näkyvä "katto" kun huone ei ole vielä kaivettu.
114    public GameObject Roof { get; set; }
115
116    // Neljä seinää, jotka on GameObjekteja.
117    public Dictionary<Direction, GameObject> Walls { get; set; }
118
119    // Huoneen sisältämä päivitys.
120    public Upgrade Upgrade { get; set; }
121
122    private bool dug; // Onko huone kaivettu?
123    public bool Dug
124    {
125        get { return dug; }
126        set
127        {
128            dug = value;
129            Roof.IsVisible = !Dug;
130        }
131    }
132
133    public Room(Point paikka)
134        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
135    {
136        Walls = new Dictionary<Direction, GameObject>();
137        Location = paikka;
138    }
139}
140
141public class Barbaari : GameObject
142{
143    public List<Point> Reitti { get; set; }
144
145    public int Askel { get; set; }
146
147    public Room Kohde { get; set; }
148
149    public Point Location { get; set; }
150
151    public Barbaari(double width, double height)
152        : base(width, height)
153    {
154        Reitti = new List<Point>();
155    }
156
157}
158
159public class Dungeon : PhysicsGame
160{
161    public const int RUUDUN_KOKO = 64;
162
163    #region Kuvat
164    Image lattiaKuva = LoadImage("floor");
165    Image seinaKuva = LoadImage("wall");
166    Image reikaSeinaKuva = LoadImage("wallhole");
167    Image kiviKuva = LoadImage("rock");
168    Image[] kultuuriKuvat = LoadImages("nyan", "es", "spurdo");
169    Image[] ansaKuvat = LoadImages((from i in Enumerable.Range(1, 7) select String.Format("piikit{0:0000}", i)).ToArray());
170    Image[] vihuKuvat = LoadImages((from i in Enumerable.Range(1, 10) select String.Format("v{0:0000}", i)).ToArray());
171    Image partikkeliKuva = LoadImage("partikkeli");
172    Image taideVeri = LoadImage("taideveri");
173    #endregion
174
175    int[] hinnat = { 100, 200, 300, 100 };
176    private int barbaariMaara = 2;
177
178    public bool kierrosKaynnissa = false;
179
180    Room[,] huoneet;
181    public List<Room> kohteet = new List<Room>();
182    public List<Barbaari> barbaarit = new List<Barbaari>();
183    Room spawn;
184    Timer barbaariAjastin = new Timer();
185    Upgrade ostamassa;
186    Point digStart; // Huoneen sijainti, josta kaivuu aloitetaan.
187    bool digging = false;
188
189    GameObject digArrow;
190    GameObject digArrowHead;
191
192    IntMeter kultuuri = new IntMeter(1000, 0, 2000);
193
194    const int VAAKA_HUONEET = 12;
195    const int PYSTY_HUONEET = 8;
196
197    // Paljonko peliruudukko on siirtynyt origosta.
198    Vector huoneSiirtyma = new Vector(-300, 0);
199
200    public override void Begin()
201    {
202        ClearAll();
203        Kontrollit();
204        UlkoAsuRoskaa();
205        Kauppa();
206        Nuoli();
207
208        // Luodaan huoneet ruutuihin.
209        huoneet = new Room[VAAKA_HUONEET, PYSTY_HUONEET];
210        foreach (var paikka in RuutujenPaikat())
211        {
212            var huone = CreateRoom(paikka);
213            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, () => RoomPressed(huone), null);
214            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Released, () => RoomReleased(huone), null);
215            huoneet[paikka.X, paikka.Y] = huone;
216        }
217
218        LuoSpawn();
219
220        Timer sykliAjastin = new Timer { Interval = 2.0 };
221        sykliAjastin.Timeout += Sykli;
222        sykliAjastin.Start();
223
224        barbaariAjastin.Timeout += LuoBarbaareja;
225        barbaariAjastin.Interval = 3;
226    }
227
228    void Nuoli()
229    {
230        digArrow = new GameObject(5, 5);
231        digArrowHead = new GameObject(15, 15);
232        digArrowHead.Shape = Shape.Triangle;
233        digArrowHead.IsVisible = digArrow.IsVisible = false;
234        Add(digArrow, 3);
235        Add(digArrowHead, 3);
236    }
237
238    void UlkoAsuRoskaa()
239    {
240        Level.Background.Color = Color.Black;
241
242        Label rahat = new Label();
243        rahat.BindTo(kultuuri);
244        rahat.Position = new Vector(Level.Right + Level.Width * 0.2, Level.Bottom + Level.Height * 0.1);
245        rahat.TextColor = Color.White;
246        rahat.IntFormatString = "Käytettävää kulttuuria: {0:D3}";
247        Add(rahat);
248    }
249
250    public void LopetaPeli()
251    {
252        ClearAll();
253        GameObject spurdo = new GameObject(Screen.Width, Screen.Height);
254        spurdo.Image = kultuuriKuvat[2];
255        Add(spurdo);
256
257        Label havisit = new Label("Hävisit muuten belin");
258        havisit.Color = Color.HotPink;
259        havisit.Size = new Vector(300, 300);
260        havisit.Position = new Vector(Level.Right - havisit.Width * 0.5, Level.Top - havisit.Height * 0.5);
261        Add(havisit);
262    }
263
264    void Kauppa()
265    {
266        for (int i = 0; i < kultuuriKuvat.Length; i++)
267        {
268
269            // Ostettavat päivitykset on nyt PushButtoneita huoneiden sijaan.
270
271            PushButton kuva = new PushButton(kultuuriKuvat[i]);
272            kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
273            kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - (i * RUUDUN_KOKO)));
274            Add(kuva);
275
276            int indeksi = i; // Alla oleva delegaatti vaatii uuden indeksi muuttujan toimiakseen.
277            kuva.Clicked += delegate
278            {
279                ostamassa = LuoKultuuriPaivitys(kultuuriKuvat[indeksi], hinnat[indeksi]);
280            };
281
282            Add(new Label
283            {
284                Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
285                TextColor = Color.White,
286                Text = hinnat[i].ToString()
287            });
288        }
289
290        for (int i = 0; i < 1; i++)
291        {
292            PushButton kuva = new PushButton(ansaKuvat[i]);
293            kuva.Size = new Vector(1, 1) * RUUDUN_KOKO;
294            kuva.Color = Color.Gray;
295            kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - ((kultuuriKuvat.Count() + i) * RUUDUN_KOKO)));
296            Add(kuva);
297
298            int indeksi = i;
299            kuva.Clicked += delegate
300            {
301                ostamassa = LuoAnsaPaivitys(ansaKuvat[ansaKuvat.Length - 1], hinnat[indeksi]);
302            };
303
304            Add(new Label
305            {
306                Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0),
307                TextColor = Color.White,
308                Text = hinnat[i].ToString()
309            });
310        }
311    }
312
313    Upgrade LuoAnsaPaivitys(Image kuva, int hinta)
314    {
315        return new TrapUpgrade
316        {
317            Image = kuva,
318            Size = new Vector(0.5, 0.5) * RUUDUN_KOKO,
319            Price = hinta,
320            Animation = new Animation(ansaKuvat)
321        };
322    }
323
324    Upgrade LuoKultuuriPaivitys(Image kuva, int hinta)
325    {
326        return new CultureUpgrade
327        {
328            Image = kuva,
329            Size = new Vector(0.5, 0.5) * RUUDUN_KOKO,
330            Price = hinta
331        };
332    }
333
334    void LuoBarbaareja()
335    {
336        Barbaari barbaari = new Barbaari(RUUDUN_KOKO * 0.4, RUUDUN_KOKO * 0.4);
337        barbaari.Color = Color.Red;
338        barbaari.Position = spawn.Position;
339        barbaari.Animation = new Animation(vihuKuvat) { FPS = 10 };
340        barbaari.Animation.Start();
341        barbaari.Location = spawn.Location;
342        Add(barbaari);
343        barbaarit.Add(barbaari);
344
345        EtsiBarbaarinReitti(barbaari);
346    }
347
348    void EtsiBarbaarinReitti(Barbaari barbaari)
349    {
350        barbaari.Kohde = kohteet[RandomGen.NextInt(kohteet.Count)];
351        barbaari.Reitti = FindPath(barbaari.Kohde.Location, (barbaari.Location.Equals(spawn.Location)) ? spawn.Location : barbaari.Location);
352    }
353
354    void Sykli()
355    {
356        foreach (var barbaari in barbaarit)
357        {
358            if (barbaari.Reitti.Count == 0)
359            {
360                EtsiBarbaarinReitti(barbaari);  //Etsitään uusi reitti poiston sijaan
361            }
362
363            Point seuraavaPaikka = barbaari.Reitti[0];
364            barbaari.Reitti.RemoveAt(0);
365            Barbaari b = barbaari;
366            barbaari.MoveTo(huoneet[seuraavaPaikka.X, seuraavaPaikka.Y].Position, 100, () => SyklinPaatteeksi(b, seuraavaPaikka));
367        }
368    }
369
370    void SyklinPaatteeksi(Barbaari barbaari, Point uusiPaikka)
371    {
372        // Barbaari saapui juuri uusiPaikka kohdassa olevaan huoneeseen.
373        // Tässä pitäisi katsoa mitä huoneessa tapahtuu.
374        barbaari.Location = uusiPaikka;
375
376        Room huone = huoneet[uusiPaikka.X, uusiPaikka.Y];
377
378        if (huone.Upgrade != null)
379        {
380            huone.Upgrade.Invasion(this, barbaari, huone);
381        }
382    }
383
384    void Kontrollit()
385    {
386        IsMouseVisible = true;
387        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
388        Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
389
390        Keyboard.Listen(Key.Space, ButtonState.Pressed, SeuraavaAalto, "Anna kivan barbaariaallon tulla");
391    }
392
393    void SeuraavaAalto()
394    {
395        if (kierrosKaynnissa) return;
396
397        barbaariAjastin.Start(barbaariMaara);
398        barbaariMaara += 2;
399        kierrosKaynnissa = false;
400    }
401
402    void LuoSpawn()
403    {
404        spawn = huoneet[(int)(huoneet.GetLength(0) * 0.5), 0];
405        spawn.Dug = true;
406
407        Direction oviSuunta = Direction.Down;
408        spawn.Walls[oviSuunta].Image = reikaSeinaKuva;
409
410        Light valo = new Light();
411        valo.Position = spawn.Position;
412        valo.Intensity = 1;
413        valo.Distance = 40;
414        Add(valo);
415    }
416
417    void RoomPressed(Room huone)
418    {
419        digStart = huone.Location;
420        digging = true;
421        digArrowHead.IsVisible = digArrow.IsVisible = true;
422    }
423
424    void RoomReleased(Room kohdeHuone)
425    {
426        digging = false;
427        digArrowHead.IsVisible = digArrow.IsVisible = false;
428        if (!CanDig()) return;
429
430        int dx = kohdeHuone.Location.X - digStart.X;
431        int dy = kohdeHuone.Location.Y - digStart.Y;
432        Point[] kaivettavatPaikat = RuudutSuoralta(digStart, dx, dy).ToArray();
433        MessageDisplay.Add("" + kaivettavatPaikat.Length);
434        for (int i = 0; i < kaivettavatPaikat.Length - 1; i++)
435        {
436            Dig(GetRoom(kaivettavatPaikat[i]), GetRoom(kaivettavatPaikat[i + 1]));
437        }
438
439        // Päivitetään huoneiden kultuuri-infot.
440        PaivitaHuoneidenKultuurit();
441    }
442
443    void Dig(Room alku, Room kohde)
444    {
445        // Hienot partikkeliefektit.
446        if (!alku.Dug)
447            LuoKiviPartikkelit(alku.Position);
448        if (!kohde.Dug)
449            LuoKiviPartikkelit(kohde.Position);
450
451        // Merkataan huoneet kaivetuksi.
452        alku.Dug = kohde.Dug = true;
453
454        // Reiät seinään.
455        Direction oviSuunta = (kohde.Position - alku.Position).Angle.MainDirection;
456        Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
457        alku.Walls[oviSuunta].Image = reikaSeinaKuva;
458        kohde.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
459    }
460
461    Room CreateRoom(Point paikka)
462    {
463        Room huone = new Room(paikka);
464        huone.Image = lattiaKuva;
465        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
466        huone.Position += huoneSiirtyma;
467        foreach (var suunta in Suunnat())
468            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
469        Add(huone, -2);
470        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
471        huone.Roof.Image = kiviKuva;
472        huone.Roof.Position = huone.Position;
473        Add(huone.Roof, 1);
474
475        Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, AsetaPaivitys, "Asetetaan ostettu päivitys paikoilleen", huone);
476        Mouse.Listen(MouseButton.Right, ButtonState.Pressed, delegate { ostamassa = null; }, "Perutaan ostos");
477        Mouse.ListenOn(huone, MouseButton.Right, ButtonState.Pressed, PoistaPaivitys, "Poistetaan asetettu päivitys", huone);
478
479        return huone;
480    }
481
482    private void PoistaPaivitys(Room huone)
483    {
484        if (huone.Upgrade != null)
485        {
486            huone.Upgrade.Destroy();
487        }
488    }
489
490    void AsetaPaivitys(Room huone)
491    {
492        if (ostamassa != null && huone.Dug && kultuuri.Value >= ostamassa.Price)
493        {
494            kultuuri.Value -= ostamassa.Price;
495
496            // Lisätään päivitys huoneeseen.
497            huone.Upgrade = ostamassa;
498            Add(huone.Upgrade, -1);
499            huone.Upgrade.Position = huone.Position;
500            huone.Upgrade.Built(this);
501
502            ostamassa = null;
503            PaivitaHuoneenKultuuri(huone);
504        }
505    }
506
507    void PaivitaHuoneidenKultuurit()
508    {
509        RuutujenPaikat().Select(GetRoom).ToList().ForEach(PaivitaHuoneenKultuuri); // :D ;___;; MIKSI <- koska pystyn
510    }
511
512    void PaivitaHuoneenKultuuri(Room room)
513    {
514        if (room != null && room.Upgrade != null && room.Upgrade is CultureUpgrade)
515        {
516            var upg = room.Upgrade as CultureUpgrade;
517
518            List<Point> polku = FindPath(room.Location, spawn.Location);
519
520            // TODO: Tässä pitäisi laskea kunnolla polun pituuden perusteella kultuurin määrä, nyt
521            //       se on vain suoraan polun pituus.
522            upg.Culture.Value = polku.Count;
523
524            kohteet.Add(room);
525        }
526    }
527
528    GameObject CreateWall(Vector paikka, Direction suunta)
529    {
530        GameObject wall = new GameObject(RUUDUN_KOKO + 2, RUUDUN_KOKO + 2);
531        wall.Position = paikka;
532        wall.Image = seinaKuva;
533        wall.Angle = suunta.Angle;
534        Add(wall, 0);
535        return wall;
536    }
537
538    bool CanDig()
539    {
540        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
541        if (kohdeHuone == null)
542        {
543            return false;
544        }
545
546        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
547        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
548        return (dx > 0 && dy == 0) || (dy > 0 && dx == 0);
549    }
550
551    #region Reitinlöytö
552
553    List<Point> FindPath(Point alku, Point loppu)
554    {
555        if (GetRoom(alku) == null || GetRoom(loppu) == null)
556            return new List<Point>();
557
558        bool[,] walkable = new bool[huoneet.GetLength(0), huoneet.GetLength(1)];
559        foreach (var paikka in RuutujenPaikat())
560        {
561            walkable[paikka.X, paikka.Y] = huoneet[paikka.X, paikka.Y].Dug;
562        }
563        var finder = new AStar.PathFinder(new AStar.SearchParameters(loppu, alku, walkable), OviTarkistus);
564        return finder.FindPath();
565    }
566
567    bool OviTarkistus(Point a, Point b)
568    {
569        Room ra = GetRoom(a);
570        Room rb = GetRoom(b);
571        Direction suunta = (new Vector(b.X, b.Y) - new Vector(a.X, a.Y)).Angle.MainDirection;
572        if (ra != null && rb != null)
573        {
574            return ra.Walls[suunta].Image == reikaSeinaKuva && rb.Walls[Direction.Inverse(suunta)].Image == reikaSeinaKuva;
575        }
576        return false;
577    }
578
579    #endregion
580
581    #region Extra Juttuja
582
583    IEnumerable<Direction> Suunnat()
584    {
585        yield return Direction.Left;
586        yield return Direction.Right;
587        yield return Direction.Up;
588        yield return Direction.Down;
589    }
590
591    IEnumerable<Point> RuutujenPaikat()
592    {
593        return from y in Enumerable.Range(0, huoneet.GetLength(1))
594               from x in Enumerable.Range(0, huoneet.GetLength(0))
595               select new Point(x, y);
596    }
597
598    /// <summary>
599    /// Palauttaa ruutuja suoralta pätkältä dx ja dy verran alkaen pisteestä "alku".
600    /// dx tai dy pitää olla nolla.
601    /// </summary>
602    IEnumerable<Point> RuudutSuoralta(Point alku, int dx, int dy)
603    {
604        if (dx != 0)
605        {
606            for (int i = 0; i < Math.Abs(dx) + 1; i++)
607            {
608                yield return new Point(alku.X + i * Math.Sign(dx), alku.Y);
609            }
610            yield break;
611        }
612        if (dy != 0)
613        {
614            for (int i = 0; i < Math.Abs(dy) + 1; i++)
615            {
616                yield return new Point(alku.X, alku.Y + i * Math.Sign(dy));
617            }
618        }
619    }
620
621    Room GetRoom(Point paikka)
622    {
623        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
624        {
625            return huoneet[paikka.X, paikka.Y];
626        }
627        return null;
628    }
629
630    /// <summary>
631    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
632    /// </summary>
633    Point MuunnaJypelista(Vector paikka)
634    {
635        Vector siirrettyOrigo = (paikka - huoneSiirtyma) + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
636        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
637        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
638        return new Point((int)valmis.X, (int)valmis.Y);
639    }
640
641    public void LuoLentavaPartikkeli(Vector alkupaikka, Image kuva, double koko, int maara, bool veri=false)
642    {
643        // Feikki 3D partikkeli juttu.
644        // Heittää ilmaan GameObjekteja joiden alla on varjo.
645
646        // VAROITUS: SISÄLTÄÄ JÄRKYTTÄVÄÄ KOODIA
647
648        for (int i = 0; i < maara; i++)
649        {
650            GameObject partikkeli = new GameObject(koko, koko);
651            partikkeli.Image = kuva;
652            partikkeli.Position = alkupaikka + RandomGen.NextVector(0.0, RUUDUN_KOKO * 0.4);
653            Add(partikkeli, 3);
654
655            GameObject varjo = new GameObject(koko, koko / 2.0);
656            varjo.Position = partikkeli.Position;
657            varjo.Shape = Shape.Circle;
658            varjo.Color = Color.Lerp(Color.Black, Color.Transparent, 0.5);
659            Add(varjo, 2);
660
661            Vector paikka = partikkeli.Position;
662            Vector nopeus = RandomGen.NextVector(0.2, 3.0);
663            nopeus.Y *= 0.3;
664            double g = -0.2; // painovoima
665            double z = 0.0; // sijainti z-akselilla
666            double vz = RandomGen.NextDouble(3.5, 4.5); // nopeus z-akselilla
667            double angularVelocity = RandomGen.NextDouble(-1.0, 1.0) * 8;
668
669            var verenLuontiAjastin = veri ? new Timer() : null;
670
671            var ajastin = new Timer();
672            ajastin.Interval = 0.02;
673            ajastin.Timeout += delegate
674            {
675                vz += g;
676                z += vz;
677                paikka += nopeus;
678                partikkeli.Position = paikka + new Vector(0.0, 1.0) * z;
679                partikkeli.Angle += Angle.FromDegrees(angularVelocity);
680                varjo.Position = paikka;
681
682                if (z < 0.0)
683                {
684                    ajastin.Stop();
685                    partikkeli.Destroy();
686                    varjo.Destroy();
687                    if (verenLuontiAjastin != null)
688                        verenLuontiAjastin.Stop();
689                }
690            };
691            ajastin.Start();
692
693            if (verenLuontiAjastin != null)
694            {
695                verenLuontiAjastin.Interval = 0.1;
696                verenLuontiAjastin.Timeout += delegate
697                {
698                    GameObject veriPartikkeli = new GameObject(3, 3);
699                    veriPartikkeli.Color = Color.DarkRed;
700                    Add(veriPartikkeli, 2);
701
702                    Vector veriPaikka = paikka;
703                    double veriZ = z;
704                    double veriVz = 0.0;
705
706                    var veriPaivitysAjastin = new Timer();
707                    veriPaivitysAjastin.Interval = 0.02;
708                    veriPaivitysAjastin.Timeout += delegate
709                    {
710                        veriVz += g;
711                        veriZ += veriVz;
712                        veriPartikkeli.Position = veriPaikka + new Vector(0.0, 1.0)*veriZ;
713
714                        if (veriZ < 0.0)
715                        {
716                            veriPaivitysAjastin.Stop();
717                            veriPartikkeli.Destroy();
718                        }
719                    };
720                    veriPaivitysAjastin.Start();
721                };
722                verenLuontiAjastin.Start();
723            }
724        }
725    }
726
727    void LuoKiviPartikkelit(Vector alkupaikka)
728    {
729        LuoLentavaPartikkeli(alkupaikka, partikkeliKuva, 25, 6);
730    }
731
732    public void Splatter(Vector alkupaikka)
733    {
734        LuoLentavaPartikkeli(alkupaikka, taideVeri, 8, 10, true);
735    }
736
737    protected override void Update(Time time)
738    {
739        if (digging)
740        {
741            Color vari = CanDig() ? Color.White : Color.Red;
742            Vector alku = huoneet[digStart.X, digStart.Y].Position;
743            Vector loppu = Mouse.PositionOnWorld;
744            Vector suunta = loppu - alku;
745            double pituus = suunta.Magnitude;
746            if (pituus <= 2) pituus = 2;
747
748            digArrow.Color = vari;
749            digArrow.Position = alku + suunta * 0.5;
750            digArrow.Angle = suunta.Angle;
751            digArrow.Width = pituus;
752
753            digArrowHead.Color = vari;
754            digArrowHead.Position = alku + suunta;
755            digArrowHead.Angle = suunta.Angle - Angle.FromDegrees(90);
756        }
757
758        base.Update(time);
759    }
760
761    protected override void Paint(Canvas canvas)
762    {
763        canvas.BrushColor = Color.Purple;
764
765        var points = FindPath(new Point(6, 0), MuunnaJypelista(Mouse.PositionOnWorld));
766        for (int i = 0; i < points.Count - 1; i++)
767        {
768            Vector v = huoneSiirtyma + new Vector(points[i].X - huoneet.GetLength(0) / 2, points[i].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
769            Vector v2 = huoneSiirtyma + new Vector(points[i + 1].X - huoneet.GetLength(0) / 2, points[i + 1].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
770            canvas.DrawLine(v, v2);
771        }
772
773        base.Paint(canvas);
774    }
775
776    #endregion
777}
Note: See TracBrowser for help on using the repository browser.