source: 2010/23/hniemi/BlockPusher/Blockpusher/Blockpusher/BlockLevel.cs @ 2635

Revision 2635, 9.3 KB checked in by hniemi, 11 years ago (diff)

Jonkinlainen toimiva protytyyppi kenttävalinnasta.

Line 
1using System;
2using System.IO;
3using System.Collections.Generic;
4using System.Linq;
5using System.Text;
6using Jypeli;
7
8/// <summary>
9/// Class that holds information of level and players location
10/// Also handles movement of player.
11/// </summary>
12public class BlockLevel
13{
14    private Block[,] playfield;
15    private Blockpusher game;
16    private List<Tuple<char, BlockType>> charcolors = new List<Tuple<char, BlockType>>();
17    private List<Block> goals = new List<Block>();
18
19    private int playerX;
20    private int playerY;
21
22    public delegate void GameEvent();
23    public event GameEvent Victory;
24
25    /// <summary>
26    /// Height of the playfield
27    /// </summary>
28    public int PlayfieldHeight { get { return playfield.GetLength(1); } }
29    /// <summary>
30    /// Width of the playfield
31    /// </summary>
32    public int PlayfieldWidth { get { return playfield.GetLength(0); } }
33
34    /// <summary>
35    /// Name of the level
36    /// </summary>
37    public string Name { get; set; }
38
39    /// <summary>
40    /// Constructor from game
41    /// </summary>
42    /// <param name="game">Game that level is used in</param>
43    public BlockLevel(Blockpusher game)
44    {
45        this.game = game;
46        InitCharColors();
47    }
48
49    /// <summary>
50    /// Adds blocks to game
51    /// </summary>
52    public void AddToGame()
53    {
54        game.Level.Size = new Vector(playfield.GetLength(0) * (Blockpusher.BlockSize + 1), playfield.GetLength(1) * (Blockpusher.BlockSize + 1));
55        game.Level.CreateBorders();
56        for (int i = 0; i < playfield.GetLength(0); i++)
57        {
58            for (int j = 0; j < playfield.GetLength(1); j++)
59            {
60
61                playfield[i, j].X = i * (Blockpusher.BlockSize + 1) + game.Level.Left + (Blockpusher.BlockSize / 2);
62                playfield[i, j].Y = -(j * (Blockpusher.BlockSize + 1) + game.Level.Bottom + (Blockpusher.BlockSize / 2));
63                game.Add(playfield[i,j]);
64            }
65        }
66    }
67
68    /// <summary>
69    /// Moves player x and y steps
70    /// </summary>
71    /// <param name="x">X Movement</param>
72    /// <param name="y">Y Movement</param>
73    public void MovePlayer(int x, int y)
74    {
75        switch (Type(playerX + x, playerY + y))
76        {
77            case BlockType.SatisfiedGoalZone:
78            case BlockType.Movable:
79                int nextX = playerX + x;
80                if (x != 0) { nextX += (x / Math.Abs(x)); }
81                int nextY = playerY + y;
82                if (y != 0) { nextY += (y / Math.Abs(y)); }
83                BlockType t = Type(nextX, nextY);
84                if (t == BlockType.Empty || t == BlockType.GoalZone || t == BlockType.SatisfiedGoalZone)
85                {
86                    Move(playerX + x, playerY + y, nextX, nextY);
87                    Move(playerX, playerY, playerX + x, playerY + y);
88                    playerX += x;
89                    playerY += y;
90                }
91
92                break;
93            case BlockType.GoalZone:
94            case BlockType.Empty:
95                Move(playerX, playerY, playerX + x, playerY + y);
96                playerX += x;
97                playerY += y;
98                break;
99            default:
100                break;
101        }
102
103        if (VictoryCheck())
104        {
105            //TODO Insert Event
106            //MessageDisplay.Add("You Win!");
107        }
108    }
109
110    /// <summary>
111    /// Moves block from place a to place b
112    ///
113    /// Don't move walls!
114    /// </summary>
115    /// <param name="startx">Source X coordinate</param>
116    /// <param name="starty">Source Y coordinate</param>
117    /// <param name="endx">Destination X coordinate</param>
118    /// <param name="endy">Destination Y coordinate</param>
119    public void Move(int startx, int starty, int endx, int endy)
120    {
121        //TODO Works, but fugly.
122        BlockType destType = playfield[endx, endy].Type;
123        BlockType sourType = playfield[startx, starty].Type;
124        bool destGoal = playfield[endx, endy].IsGoalZone;
125        bool sourGoal = playfield[startx, starty].IsGoalZone;
126
127        if (sourGoal)
128        {
129            playfield[startx, starty].Type = BlockType.GoalZone;
130        }
131        else
132        {
133            playfield[startx, starty].Type = BlockType.Empty;
134        }
135
136        if (destGoal)
137        {
138            if (sourType == BlockType.Player) { playfield[endx, endy].Type = BlockType.Player; }
139            if (sourType == BlockType.SatisfiedGoalZone) { playfield[endx, endy].Type = BlockType.SatisfiedGoalZone; }
140            if (sourType == BlockType.Movable) { playfield[endx, endy].Type = BlockType.SatisfiedGoalZone; }
141        }
142        else
143        {
144            if (sourType == BlockType.Player) { playfield[endx, endy].Type = BlockType.Player; }
145            if (sourType == BlockType.SatisfiedGoalZone) { playfield[endx, endy].Type = BlockType.Movable; }
146        }
147    }
148
149    /// <summary>
150    /// Checks if level is completed.
151    /// </summary>
152    /// <returns></returns>
153    public bool VictoryCheck()
154    {
155        foreach (var item in goals)
156        {
157            if (!(item.Type == BlockType.SatisfiedGoalZone)) return false;
158        }
159        if (Victory != null) Victory();
160        return true;
161    }
162
163    /// <summary>
164    /// Initialaizes char->Color-dict.
165    /// </summary>
166    public void InitCharColors()
167    {
168        charcolors.Add(new Tuple<char, BlockType>('x', BlockType.UnMovable));
169        charcolors.Add(new Tuple<char, BlockType>('b', BlockType.Movable));
170        charcolors.Add(new Tuple<char, BlockType>(' ', BlockType.Empty));
171        charcolors.Add(new Tuple<char, BlockType>('m', BlockType.GoalZone));
172        charcolors.Add(new Tuple<char, BlockType>('p', BlockType.Player));
173        charcolors.Add(new Tuple<char, BlockType>('s', BlockType.SatisfiedGoalZone));
174    }
175
176    /// <summary>
177    /// Finds char matching type.
178    /// If not found, return ' '
179    /// </summary>
180    /// <param name="type">Type you want to find</param>
181    /// <returns>Matching char</returns>
182    public char FindChar(BlockType type) 
183    {
184        foreach (var item in charcolors)
185        {
186            if (item.Item2 == type) return item.Item1;
187        }
188        return ' ';
189    }
190
191    /// <summary>
192    /// Finds Blocktype matching char.
193    /// If not found, BlockType.Empty is returned.
194    /// </summary>
195    /// <param name="c">Char you want to find</param>
196    /// <returns>Matching type</returns>
197    public BlockType FindBlockType(char c)
198    {
199        foreach (var item in charcolors)
200        {
201            if (item.Item1 == c) return item.Item2;
202        }
203        return BlockType.Empty;
204    }
205
206    /// <summary>
207    /// Creates playfield from given list of strings
208    /// </summary>
209    /// <param name="level"></param>
210    public void CreateField(List<string> level)
211    {
212        int playfieldWidth = level[0].Length;
213        int playfieldHeight = level.Count;
214
215        playfield = new Block[playfieldWidth, playfieldHeight];
216
217        for (int i = 0; i < playfield.GetLength(0); i++)
218        {
219            for (int j = 0; j < playfield.GetLength(1); j++)
220            {
221                Block block = new Block(Blockpusher.BlockSize, Blockpusher.BlockSize);
222                block.X = i * (Blockpusher.BlockSize + 1) + game.Level.Left + (Blockpusher.BlockSize / 2);
223                block.Y = -(j * (Blockpusher.BlockSize + 1) + game.Level.Bottom + (Blockpusher.BlockSize / 2));
224
225                block.Type = FindBlockType(level[j][i]);
226                if (block.Type == BlockType.Player)
227                {
228                    playerX = i;
229                    playerY = j;
230                }
231                if (block.IsGoalZone)
232                {
233                    goals.Add(block);
234                }
235                playfield[i, j] = block;
236            }
237        }
238        UpdatePlayer(BlockType.Player);
239    }
240
241    /// <summary>
242    /// Checks if given coordinates are empty and can be moved to.
243    ///
244    /// If coordinates are not in playfield, UnMovable is returned.
245    /// </summary>
246    /// <param name="x">X-coordinate</param>
247    /// <param name="y">Y-coordinate</param>
248    /// <returns>State of block at given coordinates</returns>
249    public BlockType Type(int x, int y)
250    {
251        if (x < 0) return BlockType.UnMovable;
252        if (y < 0) return BlockType.UnMovable;
253        if (x >= PlayfieldWidth) return BlockType.UnMovable;
254        if (y >= PlayfieldHeight) return BlockType.UnMovable;
255
256        return playfield[x, y].Type;
257    }
258
259    /// <summary>
260    /// Returns the current state of level.
261    /// </summary>
262    /// <returns></returns>
263    public List<string> CurrentState() 
264    {
265        List<string> list = new List<string>();
266
267        for (int i = 0; i < playfield.GetLength(1); i++)
268        {
269            StringBuilder line = new StringBuilder();
270            for (int j = 0; j < playfield.GetLength(0); j++)
271            {
272               
273                line.Append(FindChar(playfield[j,i].Type));
274            }
275            list.Add(line.ToString());
276        }
277
278        return list;
279    }
280
281    /// <summary>
282    /// Changes color of players coordinates
283    /// </summary>
284    /// <param name="color">Color</param>
285    public void UpdatePlayer(BlockType type)
286    {
287        playfield[playerX, playerY].Type = type;
288    }
289}
290
Note: See TracBrowser for help on using the repository browser.