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

Revision 5968, 10.8 KB checked in by empaheik, 4 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
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    #endregion
64
65    int[] hinnat = new int[] { 100, 200, 300 };
66    private int barbaariMaara = 3;
67
68    Room[,] huoneet;
69    Room spawn;
70    Timer barbaariAjastin = new Timer();
71    Room ostettu;
72    Point digStart; // Huoneen sijainti, josta kaivuu aloitetaan.
73    bool digging = false;
74
75    GameObject digArrow;
76    GameObject digArrowHead;
77
78    IntMeter kulttuuri = new IntMeter(300, 0, 2000);
79
80    int vaakaHuoneet = 12;
81    int pystyHuoneet = 8;
82
83    public override void Begin()
84    {
85        ClearAll();
86        Kontrollit();
87        UlkoAsuRoskaa();
88        Kauppa();
89        Nuoli();
90
91        // Luodaan huoneet ruutuihin.
92        huoneet = new Room[vaakaHuoneet, pystyHuoneet];
93        foreach (var paikka in RuutujenPaikat())
94        {
95            var huone = CreateRoom(paikka);
96            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, () => RoomPressed(huone), null);
97            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Released, () => RoomReleased(huone), null);
98            huoneet[paikka.X, paikka.Y] = huone;
99        }
100
101        LuoSpawn();
102
103        barbaariAjastin.Timeout += delegate { LuoBarbaareja(); };
104        barbaariAjastin.Interval = 3;
105    }
106
107    void Nuoli()
108    {
109        digArrow = new GameObject(5, 5);
110        digArrowHead = new GameObject(15, 15);
111        digArrowHead.Shape = Shape.Triangle;
112        digArrowHead.IsVisible = digArrow.IsVisible = false;
113        Add(digArrow, 3);
114        Add(digArrowHead, 3);
115    }
116
117    void UlkoAsuRoskaa()
118    {
119        Level.Background.Color = Color.Black;
120
121        Label rahat = new Label();
122        rahat.BindTo(kulttuuri);
123        rahat.Position = new Vector(Level.Right + Level.Width * 0.2, Level.Bottom + Level.Height * 0.1);
124        rahat.TextColor = Color.White;
125        rahat.IntFormatString = "Käytettävää kulttuuria: {0:D3}";
126        Add(rahat);
127    }
128
129    void Kauppa()
130    {
131        for (int i = 0; i < huoneKuvat.Length; i++)
132        {
133            Point lokaatio = new Point(0, 0);
134
135            Room kuva = new Room(lokaatio);
136            kuva.Position = new Vector((Level.Right + Level.Width * 0.05), (Level.Top - Level.Height * 0.25 - (i * RUUDUN_KOKO)));
137            kuva.Image = huoneKuvat[i];
138            kuva.Price = hinnat[i];
139            Add(kuva);
140
141            Mouse.ListenOn(kuva, MouseButton.Left, ButtonState.Pressed, delegate(Room a) { ostettu = a; }, "Asetetaan ostettu huone paikoilleen", kuva);
142
143            Label teksti = new Label();
144            teksti.Position = kuva.Position + new Vector((RUUDUN_KOKO * 1.2), 0);
145            teksti.TextColor = Color.White;
146            teksti.Text = hinnat[i].ToString();
147            Add(teksti);
148        }
149    }
150
151    void LuoBarbaareja()
152    {
153        PhysicsObject barbaari = new PhysicsObject(RUUDUN_KOKO * 0.3, RUUDUN_KOKO * 0.3);
154        barbaari.Color = Color.Red;
155        //barbaari.Position = RandomGen.NextVector(Level.Right, Level.Bottom, Level.Left, Level.Top);
156        barbaari.Position = spawn.Position;
157        Add(barbaari);
158    }
159
160    void Kontrollit()
161    {
162        IsMouseVisible = true;
163        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
164        Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
165
166        // Testi haku huoneesta (0, 0) -> (5, 5).
167        Keyboard.Listen(Key.F2, ButtonState.Pressed, delegate
168        {
169            FindPath(new Point(0, 0), new Point(5, 5));
170        }, null);
171
172        Keyboard.Listen(Key.Space, ButtonState.Pressed, SeuraavaAalto, "Anna kivan barbaariaallon tulla");
173    }
174
175    void SeuraavaAalto()
176    {
177        barbaariMaara += 2;
178        barbaariAjastin.Start(barbaariMaara);
179    }
180
181    void LuoSpawn()
182    {
183        spawn = huoneet[(int)(huoneet.GetLength(0) * 0.5), 0];
184        spawn.Dug = true;
185
186        Direction oviSuunta = ((spawn.Position - new Vector(0, RUUDUN_KOKO * 0.5)).Angle.MainDirection);
187        spawn.Walls[oviSuunta].Image = reikaSeinaKuva;
188
189        Light valo = new Light();
190        valo.Position = spawn.Position;
191        valo.Intensity = 1;
192        valo.Distance = 40;
193        Add(valo);
194       
195    }
196
197    void RoomPressed(Room huone)
198    {
199        digStart = huone.Location;
200        digging = true;
201        digArrowHead.IsVisible = digArrow.IsVisible = true;
202    }
203
204    void RoomReleased(Room kohdeHuone)
205    {
206        digging = false;
207        digArrowHead.IsVisible = digArrow.IsVisible = false;
208        if (CanDig()) 
209        {
210            // Merkataan huoneet kaivetuksi.
211            var alkuHuone = huoneet[digStart.X, digStart.Y];
212            kohdeHuone.Dug = alkuHuone.Dug = true;
213
214            // Reiät seinään.
215            Direction oviSuunta = (kohdeHuone.Position - alkuHuone.Position).Angle.MainDirection;
216            Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
217            alkuHuone.Walls[oviSuunta].Image = reikaSeinaKuva;
218            kohdeHuone.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
219        }
220    }
221
222    Room CreateRoom(Point paikka)
223    {
224        Room huone = new Room(paikka);
225        huone.Image = lattiaKuva;
226        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
227        foreach (var suunta in Suunnat())
228            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
229        Add(huone, -1);
230        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
231        huone.Roof.Image = kiviKuva;
232        huone.Roof.Position = huone.Position;
233        Add(huone.Roof, 1);
234
235        Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, AsetaHuone, "Asetetaan ostettu huone paikoilleen", huone);
236
237        return huone;
238    }
239
240    void AsetaHuone(Room huone)
241    {
242        if(ostettu != null && huone.Dug && (kulttuuri.Value > huone.Price))
243        {
244            huone.Damage = ostettu.Damage;
245            huone.Culture = ostettu.Culture;
246            huone.Image = ostettu.Image;
247            kulttuuri.Value -= ostettu.Price;
248            ostettu = null;
249        }
250    }
251
252    GameObject CreateWall(Vector paikka, Direction suunta)
253    {
254        GameObject wall = new GameObject(RUUDUN_KOKO + 2, RUUDUN_KOKO + 2);
255        wall.Position = paikka;
256        wall.Image = seinaKuva;
257        wall.Angle = suunta.Angle;
258        Add(wall, 0);
259        return wall;
260    }
261
262    bool CanDig()
263    {
264        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
265        if (kohdeHuone == null)
266        {
267            return false;
268        }
269        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
270        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
271        return dx + dy == 1;
272    }
273
274    protected override void Update(Time time)
275    {
276        if (digging)
277        {
278            Color vari = CanDig() ? Color.White : Color.Red;
279            Vector alku = huoneet[digStart.X, digStart.Y].Position;
280            Vector loppu = Mouse.PositionOnWorld;
281            Vector suunta = loppu - alku;
282            double pituus = suunta.Magnitude;
283            if (pituus <= 2) pituus = 2;
284
285            digArrow.Color = vari;
286            digArrow.Position = alku + suunta * 0.5;
287            digArrow.Angle = suunta.Angle;
288            digArrow.Width = pituus;
289
290            digArrowHead.Color = vari;
291            digArrowHead.Position = alku + suunta;
292            digArrowHead.Angle = suunta.Angle - Angle.FromDegrees(90);
293        }
294        base.Update(time);
295    }
296
297    #region Reitinlöytö
298
299    void FindPath(Point alku, Point loppu)
300    {
301        bool[,] walkable = new bool[huoneet.GetLength(0), huoneet.GetLength(1)];
302        foreach (var paikka in RuutujenPaikat())
303        {
304            walkable[paikka.X, paikka.Y] = huoneet[paikka.X, paikka.Y].Dug;
305        }
306        var finder = new AStar.PathFinder(new AStar.SearchParameters(alku, loppu, walkable));
307        List<Point> path = finder.FindPath();
308        // Ei ota huomioon ovia :(
309    }
310
311    #endregion
312
313    #region Extra Juttuja
314
315    IEnumerable<Direction> Suunnat()
316    {
317        yield return Direction.Left;
318        yield return Direction.Right;
319        yield return Direction.Up;
320        yield return Direction.Down;
321    }
322
323    IEnumerable<Point> RuutujenPaikat()
324    {
325        return from y in Enumerable.Range(0, huoneet.GetLength(1))
326               from x in Enumerable.Range(0, huoneet.GetLength(0))
327               select new Point(x, y);
328    }
329
330    Room GetRoom(Point paikka)
331    {
332        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
333        {
334            return huoneet[paikka.X, paikka.Y];
335        }
336        return null;
337    }
338
339    /// <summary>
340    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
341    /// </summary>
342    Point MuunnaJypelista(Vector paikka)
343    {
344        Vector siirrettyOrigo = paikka + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
345        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
346        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
347        return new Point((int)valmis.X, (int)valmis.Y);
348    }
349
350    #endregion
351}
Note: See TracBrowser for help on using the repository browser.