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

Revision 5965, 5.8 KB checked in by empaheik, 7 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    private bool dug; // Onko huone kaivettu?
23    public bool Dug
24    {
25        get { return dug; }
26        set
27        {
28            dug = value;
29            Roof.IsVisible = !Dug;
30        }
31    }
32
33    public Room(Point paikka)
34        : base(Dungeon.RUUDUN_KOKO, Dungeon.RUUDUN_KOKO)
35    {
36        Walls = new Dictionary<Direction, GameObject>();
37        Location = paikka;
38    }
39}
40
41public class Dungeon : PhysicsGame
42{
43    public const int RUUDUN_KOKO = 64;
44
45    Image lattiaKuva = LoadImage("floor");
46    Image seinaKuva = LoadImage("wall");
47    Image reikaSeinaKuva = LoadImage("wallhole");
48    Image kiviKuva = LoadImage("rock");
49
50    Room[,] huoneet;
51    Point digStart; // Huoneen sijainti, josta kaivuu aloitetaan.
52    bool digging = false;
53
54    public override void Begin()
55    {
56        ClearAll();
57        IsMouseVisible = true;
58
59        // Luodaan huoneet ruutuihin.
60        huoneet = new Room[12, 8];
61        foreach (var paikka in RuutujenPaikat())
62        {
63            var huone = CreateRoom(paikka);
64            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Pressed, () => RoomPressed(huone), null);
65            Mouse.ListenOn(huone, MouseButton.Left, ButtonState.Released, () => RoomReleased(huone), null);
66            huoneet[paikka.X, paikka.Y] = huone;
67        }
68
69        LuoSpawn();
70
71        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
72        Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
73    }
74
75    void LuoSpawn()
76    {
77        Room spawnHuone = huoneet[(int)(huoneet.GetLength(0) * 0.5), 0];
78        spawnHuone.Image = null;
79        spawnHuone.Dug = true;
80
81        Direction oviSuunta = ((spawnHuone.Position - new Vector(0, RUUDUN_KOKO * 0.5)).Angle.MainDirection);
82        spawnHuone.Walls[oviSuunta].Image = reikaSeinaKuva;
83    }
84
85    void RoomPressed(Room huone)
86    {
87        digStart = huone.Location;
88        digging = true;
89    }
90
91    void RoomReleased(Room kohdeHuone)
92    {
93        digging = false;
94        if (CanDig()) 
95        {
96            // Merkataan huoneet kaivetuksi.
97            var alkuHuone = huoneet[digStart.X, digStart.Y];
98            kohdeHuone.Dug = alkuHuone.Dug = true;
99
100            // Reiät seinään.
101            Direction oviSuunta = (kohdeHuone.Position - alkuHuone.Position).Angle.MainDirection;
102            Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
103            alkuHuone.Walls[oviSuunta].Image = reikaSeinaKuva;
104            kohdeHuone.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
105        }
106    }
107
108    Room CreateRoom(Point paikka)
109    {
110        Room huone = new Room(paikka);
111        huone.Image = lattiaKuva;
112        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
113        foreach (var suunta in Suunnat())
114            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
115        Add(huone, -1);
116        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
117        huone.Roof.Image = kiviKuva;
118        huone.Roof.Position = huone.Position;
119        Add(huone.Roof, 2);
120        return huone;
121    }
122
123    GameObject CreateWall(Vector paikka, Direction suunta)
124    {
125        GameObject wall = new GameObject(RUUDUN_KOKO + 2, RUUDUN_KOKO + 2);
126        wall.Position = paikka;
127        wall.Image = seinaKuva;
128        wall.Angle = suunta.Angle;
129        Add(wall, 1);
130        return wall;
131    }
132
133    bool CanDig()
134    {
135        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
136        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
137        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
138        return dx + dy == 1;
139    }
140
141    protected override void Paint(Canvas canvas)
142    {
143        if (digging)
144        {
145            canvas.BrushColor = CanDig() ? Color.Green : Color.Red;
146            canvas.DrawLine(huoneet[digStart.X, digStart.Y].Position, Mouse.PositionOnWorld);
147        }
148        base.Paint(canvas);
149    }
150
151    #region Extra Juttuja
152
153    IEnumerable<Direction> Suunnat()
154    {
155        yield return Direction.Left;
156        yield return Direction.Right;
157        yield return Direction.Up;
158        yield return Direction.Down;
159    }
160
161    IEnumerable<Point> RuutujenPaikat()
162    {
163        return from y in Enumerable.Range(0, huoneet.GetLength(1))
164               from x in Enumerable.Range(0, huoneet.GetLength(0))
165               select new Point(x, y);
166    }
167
168    Room GetRoom(Point paikka)
169    {
170        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
171        {
172            return huoneet[paikka.X, paikka.Y];
173        }
174        return null;
175    }
176
177    /// <summary>
178    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
179    /// </summary>
180    Point MuunnaJypelista(Vector paikka)
181    {
182        Vector siirrettyOrigo = paikka + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
183        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
184        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
185        return new Point((int)valmis.X, (int)valmis.Y);
186    }
187
188    #endregion
189}
Note: See TracBrowser for help on using the repository browser.