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

Revision 5970, 11.9 KB checked in by sieerinn, 4 years ago (diff)

Barbaareille animaatio.

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
11class Room : GameObject
12{
13    // Sijainti pelin ruudukossa.
14    public Point Location { get; set; }
15
16    // Päällä näkyvä "katto" kun huone ei ole vielä kaivettu.
17    public GameObject Roof { get; set; }
18
19    // Neljä seinää, jotka on GameObjekteja.
20    public Dictionary<Direction, GameObject> Walls { get; set; }
21
22    public String Type { get; set; }
23
24    public int Damage { get; set; }
25
26    public int Culture { get; set; }
27
28    private bool dug; // Onko huone kaivettu?
29    public bool Dug
30    {
31        get { return dug; }
32        set
33        {
34            dug = value;
35            Roof.IsVisible = !Dug;
36        }
37    }
38
39    public Room(Point paikka)
40        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
41    {
42        Walls = new Dictionary<Direction, GameObject>();
43        Location = paikka;
44    }
45
46    public int Price { get; set; }
47
48}
49
50public class Dungeon : PhysicsGame
51{
52    public const int RUUDUN_KOKO = 64;
53
54    #region Kuvat
55    Image lattiaKuva = LoadImage("floor");
56    Image seinaKuva = LoadImage("wall");
57    Image reikaSeinaKuva = LoadImage("wallhole");
58    Image kiviKuva = LoadImage("rock");
59    static Image kulttuuriKuva1 = LoadImage("es");
60    static Image kulttuuriKuva2 = LoadImage("nyan");
61    static Image kulttuuriKuva3 = LoadImage("spurdo");
62    Image[] huoneKuvat = new Image[] { kulttuuriKuva1, kulttuuriKuva2, kulttuuriKuva3 };
63    Image[] vihuKuvat = LoadImages((from i in Enumerable.Range(1, 10) select String.Format("v{0:0000}", i)).ToArray());
64    #endregion
65
66    int[] hinnat = new int[] { 100, 200, 300 };
67    private int barbaariMaara = 3;
68
69    Room[,] huoneet;
70    Room spawn;
71    Timer barbaariAjastin = new Timer();
72    Room ostettu;
73    Point digStart; // Huoneen sijainti, josta kaivuu aloitetaan.
74    bool digging = false;
75
76    GameObject digArrow;
77    GameObject digArrowHead;
78
79    IntMeter kulttuuri = new IntMeter(300, 0, 2000);
80
81    int vaakaHuoneet = 12;
82    int pystyHuoneet = 8;
83
84    public override void Begin()
85    {
86        ClearAll();
87        Kontrollit();
88        UlkoAsuRoskaa();
89        Kauppa();
90        Nuoli();
91
92        // Luodaan huoneet ruutuihin.
93        huoneet = new Room[vaakaHuoneet, pystyHuoneet];
94        foreach (var paikka in RuutujenPaikat())
95        {
96            var huone = CreateRoom(paikka);
97            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, () => RoomPressed(huone), null);
98            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Released, () => RoomReleased(huone), null);
99            huoneet[paikka.X, paikka.Y] = huone;
100        }
101
102        LuoSpawn();
103
104        barbaariAjastin.Timeout += delegate { LuoBarbaareja(); };
105        barbaariAjastin.Interval = 3;
106    }
107
108    void Nuoli()
109    {
110        digArrow = new GameObject(5, 5);
111        digArrowHead = new GameObject(15, 15);
112        digArrowHead.Shape = Shape.Triangle;
113        digArrowHead.IsVisible = digArrow.IsVisible = false;
114        Add(digArrow, 3);
115        Add(digArrowHead, 3);
116    }
117
118    void UlkoAsuRoskaa()
119    {
120        Level.Background.Color = Color.Black;
121
122        Label rahat = new Label();
123        rahat.BindTo(kulttuuri);
124        rahat.Position = new Vector(Level.Right + Level.Width * 0.2, Level.Bottom + Level.Height * 0.1);
125        rahat.TextColor = Color.White;
126        rahat.IntFormatString = "Käytettävää kulttuuria: {0:D3}";
127        Add(rahat);
128    }
129
130    void Kauppa()
131    {
132        for (int i = 0; i < huoneKuvat.Length; i++)
133        {
134            Point lokaatio = new Point(0, 0);
135
136            Room kuva = new Room(lokaatio);
137            kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - (i * RUUDUN_KOKO)));
138            kuva.Image = huoneKuvat[i];
139            kuva.Price = hinnat[i];
140            Add(kuva);
141
142            Mouse.ListenOn(kuva, MouseButton.Left, ButtonState.Pressed, delegate(Room a) { ostettu = a; }, "Asetetaan ostettu huone paikoilleen", kuva);
143
144            Label teksti = new Label();
145            teksti.Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0);
146            teksti.TextColor = Color.White;
147            teksti.Text = hinnat[i].ToString();
148            Add(teksti);
149        }
150    }
151
152    void LuoBarbaareja()
153    {
154        PhysicsObject barbaari = new PhysicsObject(RUUDUN_KOKO * 0.4, RUUDUN_KOKO * 0.4);
155        barbaari.Color = Color.Red;
156        //barbaari.Position = RandomGen.NextVector(Level.Right, Level.Bottom, Level.Left, Level.Top);
157        barbaari.Position = spawn.Position;
158        barbaari.Animation = new Animation(vihuKuvat);
159        barbaari.Animation.FPS = 10;
160        barbaari.Animation.Start();
161        Add(barbaari);
162    }
163
164    void Kontrollit()
165    {
166        IsMouseVisible = true;
167        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
168        Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
169
170        Keyboard.Listen(Key.Space, ButtonState.Pressed, SeuraavaAalto, "Anna kivan barbaariaallon tulla");
171    }
172
173    void SeuraavaAalto()
174    {
175        barbaariMaara += 2;
176        barbaariAjastin.Start(barbaariMaara);
177    }
178
179    void LuoSpawn()
180    {
181        spawn = huoneet[(int)(huoneet.GetLength(0) * 0.5), 0];
182        spawn.Dug = true;
183
184        Direction oviSuunta = ((spawn.Position - new Vector(0, RUUDUN_KOKO * 0.5)).Angle.MainDirection);
185        spawn.Walls[oviSuunta].Image = reikaSeinaKuva;
186
187        Light valo = new Light();
188        valo.Position = spawn.Position;
189        valo.Intensity = 1;
190        valo.Distance = 40;
191        Add(valo);
192       
193    }
194
195    void RoomPressed(Room huone)
196    {
197        digStart = huone.Location;
198        digging = true;
199        digArrowHead.IsVisible = digArrow.IsVisible = true;
200    }
201
202    void RoomReleased(Room kohdeHuone)
203    {
204        digging = false;
205        digArrowHead.IsVisible = digArrow.IsVisible = false;
206        if (CanDig()) 
207        {
208            // Merkataan huoneet kaivetuksi.
209            var alkuHuone = huoneet[digStart.X, digStart.Y];
210            kohdeHuone.Dug = alkuHuone.Dug = true;
211
212            // Reiät seinään.
213            Direction oviSuunta = (kohdeHuone.Position - alkuHuone.Position).Angle.MainDirection;
214            Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
215            alkuHuone.Walls[oviSuunta].Image = reikaSeinaKuva;
216            kohdeHuone.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
217        }
218    }
219
220    Room CreateRoom(Point paikka)
221    {
222        Room huone = new Room(paikka);
223        huone.Image = lattiaKuva;
224        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
225        foreach (var suunta in Suunnat())
226            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
227        Add(huone, -1);
228        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
229        huone.Roof.Image = kiviKuva;
230        huone.Roof.Position = huone.Position;
231        Add(huone.Roof, 1);
232
233        Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, AsetaHuone, "Asetetaan ostettu huone paikoilleen", huone);
234
235        return huone;
236    }
237
238    void AsetaHuone(Room huone)
239    {
240        if(ostettu != null && huone.Dug && (kulttuuri.Value > huone.Price))
241        {
242            huone.Damage = ostettu.Damage;
243            huone.Culture = ostettu.Culture;
244            huone.Image = ostettu.Image;
245            kulttuuri.Value -= ostettu.Price;
246            ostettu = null;
247        }
248    }
249
250    GameObject CreateWall(Vector paikka, Direction suunta)
251    {
252        GameObject wall = new GameObject(RUUDUN_KOKO + 2, RUUDUN_KOKO + 2);
253        wall.Position = paikka;
254        wall.Image = seinaKuva;
255        wall.Angle = suunta.Angle;
256        Add(wall, 0);
257        return wall;
258    }
259
260    bool CanDig()
261    {
262        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
263        if (kohdeHuone == null)
264        {
265            return false;
266        }
267        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
268        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
269        return dx + dy == 1;
270    }
271
272    protected override void Update(Time time)
273    {
274        if (digging)
275        {
276            Color vari = CanDig() ? Color.White : Color.Red;
277            Vector alku = huoneet[digStart.X, digStart.Y].Position;
278            Vector loppu = Mouse.PositionOnWorld;
279            Vector suunta = loppu - alku;
280            double pituus = suunta.Magnitude;
281            if (pituus <= 2) pituus = 2;
282
283            digArrow.Color = vari;
284            digArrow.Position = alku + suunta * 0.5;
285            digArrow.Angle = suunta.Angle;
286            digArrow.Width = pituus;
287
288            digArrowHead.Color = vari;
289            digArrowHead.Position = alku + suunta;
290            digArrowHead.Angle = suunta.Angle - Angle.FromDegrees(90);
291        }
292
293        base.Update(time);
294    }
295
296    protected override void Paint(Canvas canvas)
297    {
298        canvas.BrushColor = Color.Purple;
299
300        var points = FindPath(new Point(6, 0), MuunnaJypelista(Mouse.PositionOnWorld));
301        for (int i = 0; i < points.Count - 1; i++)
302        {
303            Vector v = new Vector(points[i].X - huoneet.GetLength(0) / 2, points[i].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
304            Vector v2 = new Vector(points[i+1].X - huoneet.GetLength(0) / 2, points[i+1].Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
305            canvas.DrawLine(v, v2);
306        }
307
308        base.Paint(canvas);
309    }
310
311    #region Reitinlöytö
312
313    List<Point> FindPath(Point alku, Point loppu)
314    {
315        if (GetRoom(alku) == null || GetRoom(loppu) == null)
316            return new List<Point>();
317
318        bool[,] walkable = new bool[huoneet.GetLength(0), huoneet.GetLength(1)];
319        foreach (var paikka in RuutujenPaikat())
320        {
321            walkable[paikka.X, paikka.Y] = huoneet[paikka.X, paikka.Y].Dug;
322        }
323        var finder = new AStar.PathFinder(new AStar.SearchParameters(alku, loppu, walkable), OviTarkistus);
324        return finder.FindPath();
325    }
326
327    bool OviTarkistus(Point a, Point b)
328    {
329        Room ra = GetRoom(a);
330        Room rb = GetRoom(b);
331        Direction suunta = (new Vector(b.X, b.Y) - new Vector(a.X, a.Y)).Angle.MainDirection;
332        if (ra != null && rb != null)
333        {
334            return ra.Walls[suunta].Image == reikaSeinaKuva && rb.Walls[Direction.Inverse(suunta)].Image == reikaSeinaKuva;
335        }
336        return false;
337    }
338
339    #endregion
340
341    #region Extra Juttuja
342
343    IEnumerable<Direction> Suunnat()
344    {
345        yield return Direction.Left;
346        yield return Direction.Right;
347        yield return Direction.Up;
348        yield return Direction.Down;
349    }
350
351    IEnumerable<Point> RuutujenPaikat()
352    {
353        return from y in Enumerable.Range(0, huoneet.GetLength(1))
354               from x in Enumerable.Range(0, huoneet.GetLength(0))
355               select new Point(x, y);
356    }
357
358    Room GetRoom(Point paikka)
359    {
360        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
361        {
362            return huoneet[paikka.X, paikka.Y];
363        }
364        return null;
365    }
366
367    /// <summary>
368    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
369    /// </summary>
370    Point MuunnaJypelista(Vector paikka)
371    {
372        Vector siirrettyOrigo = paikka + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
373        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
374        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
375        return new Point((int)valmis.X, (int)valmis.Y);
376    }
377
378    #endregion
379}
Note: See TracBrowser for help on using the repository browser.