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

Revision 5927, 5.4 KB checked in by sieerinn, 8 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        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
70        Keyboard.Listen(Key.F1, ButtonState.Pressed, Begin, null);
71    }
72
73    void RoomPressed(Room huone)
74    {
75        digStart = huone.Location;
76        digging = true;
77    }
78
79    void RoomReleased(Room kohdeHuone)
80    {
81        digging = false;
82        if (CanDig()) 
83        {
84            // Merkataan huoneet kaivetuksi.
85            var alkuHuone = huoneet[digStart.X, digStart.Y];
86            kohdeHuone.Dug = alkuHuone.Dug = true;
87
88            // Reiät seinään.
89            Direction oviSuunta = (kohdeHuone.Position - alkuHuone.Position).Angle.MainDirection;
90            Direction toinenOviSuunta = Direction.Inverse(oviSuunta);
91            alkuHuone.Walls[oviSuunta].Image = reikaSeinaKuva;
92            kohdeHuone.Walls[toinenOviSuunta].Image = reikaSeinaKuva;
93        }
94    }
95
96    Room CreateRoom(Point paikka)
97    {
98        Room huone = new Room(paikka);
99        huone.Image = lattiaKuva;
100        huone.Position = new Vector(paikka.X - huoneet.GetLength(0) / 2, paikka.Y - huoneet.GetLength(1) / 2) * RUUDUN_KOKO;
101        foreach (var suunta in Suunnat())
102            huone.Walls[suunta] = CreateWall(huone.Position, suunta);
103        Add(huone, -1);
104        huone.Roof = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
105        huone.Roof.Image = kiviKuva;
106        huone.Roof.Position = huone.Position;
107        Add(huone.Roof, 2);
108        return huone;
109    }
110
111    GameObject CreateWall(Vector paikka, Direction suunta)
112    {
113        GameObject wall = new GameObject(RUUDUN_KOKO, RUUDUN_KOKO);
114        wall.Position = paikka;
115        wall.Image = seinaKuva;
116        wall.Angle = suunta.Angle;
117        Add(wall, 1);
118        return wall;
119    }
120
121    bool CanDig()
122    {
123        Room kohdeHuone = GetRoom(MuunnaJypelista(Mouse.PositionOnWorld));
124        int dx = Math.Abs(kohdeHuone.Location.X - digStart.X);
125        int dy = Math.Abs(kohdeHuone.Location.Y - digStart.Y);
126        return dx + dy == 1;
127    }
128
129    protected override void Paint(Canvas canvas)
130    {
131        if (digging)
132        {
133            canvas.BrushColor = CanDig() ? Color.Green : Color.Red;
134            canvas.DrawLine(huoneet[digStart.X, digStart.Y].Position, Mouse.PositionOnWorld);
135        }
136        base.Paint(canvas);
137    }
138
139    #region Extra Juttuja
140
141    IEnumerable<Direction> Suunnat()
142    {
143        yield return Direction.Left;
144        yield return Direction.Right;
145        yield return Direction.Up;
146        yield return Direction.Down;
147    }
148
149    IEnumerable<Point> RuutujenPaikat()
150    {
151        return from y in Enumerable.Range(0, huoneet.GetLength(1))
152               from x in Enumerable.Range(0, huoneet.GetLength(0))
153               select new Point(x, y);
154    }
155
156    Room GetRoom(Point paikka)
157    {
158        if (paikka.X >= 0 && paikka.X < huoneet.GetLength(0) && paikka.Y >= 0 && paikka.Y < huoneet.GetLength(1))
159        {
160            return huoneet[paikka.X, paikka.Y];
161        }
162        return null;
163    }
164
165    /// <summary>
166    /// Muuntaa Jypeli-koordinaatin peliruudukon koordinaatiksi.
167    /// </summary>
168    Point MuunnaJypelista(Vector paikka)
169    {
170        Vector siirrettyOrigo = paikka + RUUDUN_KOKO * (0.5 * new Vector(huoneet.GetLength(0), huoneet.GetLength(1)) + new Vector(0.5, 0.5));
171        Vector wtf = new Vector(siirrettyOrigo.X < 0 ? -1 : 0, siirrettyOrigo.Y < 0 ? -1 : 0);
172        Vector valmis = wtf + siirrettyOrigo / RUUDUN_KOKO;
173        return new Point((int)valmis.X, (int)valmis.Y);
174    }
175
176    #endregion
177}
Note: See TracBrowser for help on using the repository browser.