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

Revision 2634, 7.1 KB checked in by hniemi, 11 years ago (diff)

Lisätty alkuvalikot ja eventti voittamiselle. Voittaminen on kivaa.

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 Dictionary<char, BlockType> charColor = new Dictionary<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    /// Constructor from game
36    /// </summary>
37    /// <param name="game">Game that level is used in</param>
38    public BlockLevel(Blockpusher game)
39    {
40        this.game = game;
41        InitCharColors();
42    }
43
44    /// <summary>
45    /// Moves player x and y steps
46    /// </summary>
47    /// <param name="x">X Movement</param>
48    /// <param name="y">Y Movement</param>
49    public void MovePlayer(int x, int y)
50    {
51        switch (Type(playerX + x, playerY + y))
52        {
53            case BlockType.SatisfiedGoalZone:
54            case BlockType.Movable:
55                int nextX = playerX + x;
56                if (x != 0) { nextX += (x / Math.Abs(x)); }
57                int nextY = playerY + y;
58                if (y != 0) { nextY += (y / Math.Abs(y)); }
59                BlockType t = Type(nextX, nextY);
60                if (t == BlockType.Empty || t == BlockType.GoalZone || t == BlockType.SatisfiedGoalZone)
61                {
62                    Move(playerX + x, playerY + y, nextX, nextY);
63                    Move(playerX, playerY, playerX + x, playerY + y);
64                    playerX += x;
65                    playerY += y;
66                }
67
68                break;
69            case BlockType.GoalZone:
70            case BlockType.Empty:
71                Move(playerX, playerY, playerX + x, playerY + y);
72                playerX += x;
73                playerY += y;
74                break;
75            default:
76                break;
77        }
78
79        if (VictoryCheck())
80        {
81            //TODO Insert Event
82            //MessageDisplay.Add("You Win!");
83        }
84    }
85
86    /// <summary>
87    /// Moves block from place a to place b
88    ///
89    /// Don't move walls!
90    /// </summary>
91    /// <param name="startx">Source X coordinate</param>
92    /// <param name="starty">Source Y coordinate</param>
93    /// <param name="endx">Destination X coordinate</param>
94    /// <param name="endy">Destination Y coordinate</param>
95    public void Move(int startx, int starty, int endx, int endy)
96    {
97        //TODO Works, but fugly.
98        BlockType destType = playfield[endx, endy].Type;
99        BlockType sourType = playfield[startx, starty].Type;
100        bool destGoal = playfield[endx, endy].IsGoalZone;
101        bool sourGoal = playfield[startx, starty].IsGoalZone;
102
103        if (sourGoal)
104        {
105            playfield[startx, starty].Type = BlockType.GoalZone;
106        }
107        else
108        {
109            playfield[startx, starty].Type = BlockType.Empty;
110        }
111
112        if (destGoal)
113        {
114            if (sourType == BlockType.Player) { playfield[endx, endy].Type = BlockType.Player; }
115            if (sourType == BlockType.SatisfiedGoalZone) { playfield[endx, endy].Type = BlockType.SatisfiedGoalZone; }
116            if (sourType == BlockType.Movable) { playfield[endx, endy].Type = BlockType.SatisfiedGoalZone; }
117        }
118        else
119        {
120            if (sourType == BlockType.Player) { playfield[endx, endy].Type = BlockType.Player; }
121            if (sourType == BlockType.SatisfiedGoalZone) { playfield[endx, endy].Type = BlockType.Movable; }
122        }
123    }
124
125    /// <summary>
126    /// Checks if level is completed.
127    /// </summary>
128    /// <returns></returns>
129    public bool VictoryCheck()
130    {
131        foreach (var item in goals)
132        {
133            if (!(item.Type == BlockType.SatisfiedGoalZone)) return false;
134        }
135        if (Victory != null) Victory();
136        return true;
137    }
138
139    /// <summary>
140    /// Initialaizes char->Color-dict.
141    /// </summary>
142    public void InitCharColors()
143    {
144        charColor.Add('x', BlockType.UnMovable);
145        charColor.Add('b', BlockType.Movable);
146        charColor.Add(' ', BlockType.Empty);
147        charColor.Add('m', BlockType.GoalZone);
148        charColor.Add('p', BlockType.Player);
149        charColor.Add('s', BlockType.SatisfiedGoalZone);
150    }
151
152    /// <summary>
153    /// Creates playfield from given list of strings
154    /// </summary>
155    /// <param name="level"></param>
156    public void CreateField(List<string> level)
157    {
158        int playfieldWidth = level[0].Length;
159        int playfieldHeight = level.Count;
160
161        playfield = new Block[playfieldWidth, playfieldHeight];
162        game.Level.Size = new Vector(playfieldWidth * (Blockpusher.BlockSize + 1), playfieldHeight * (Blockpusher.BlockSize + 1));
163        game.Level.CreateBorders();
164
165        for (int i = 0; i < playfield.GetLength(0); i++)
166        {
167            for (int j = 0; j < playfield.GetLength(1); j++)
168            {
169                Block block = new Block(Blockpusher.BlockSize, Blockpusher.BlockSize);
170                block.X = i * (Blockpusher.BlockSize + 1) + game.Level.Left + (Blockpusher.BlockSize / 2);
171                block.Y = -(j * (Blockpusher.BlockSize + 1) + game.Level.Bottom + (Blockpusher.BlockSize / 2));
172
173                block.Type = charColor[level[j][i]];
174                if (block.Type == BlockType.Player)
175                {
176                    playerX = i;
177                    playerY = j;
178                }
179                if (block.IsGoalZone)
180                {
181                    goals.Add(block);
182                }
183                game.Add(block);
184                playfield[i, j] = block;
185            }
186        }
187        UpdatePlayer(BlockType.Player);
188    }
189
190    /// <summary>
191    /// Checks if given coordinates are empty and can be moved to.
192    ///
193    /// If coordinates are not in playfield, UnMovable is returned.
194    /// </summary>
195    /// <param name="x">X-coordinate</param>
196    /// <param name="y">Y-coordinate</param>
197    /// <returns>State of block at given coordinates</returns>
198    public BlockType Type(int x, int y)
199    {
200        if (x < 0) return BlockType.UnMovable;
201        if (y < 0) return BlockType.UnMovable;
202        if (x >= PlayfieldWidth) return BlockType.UnMovable;
203        if (y >= PlayfieldHeight) return BlockType.UnMovable;
204
205        return playfield[x, y].Type;
206    }
207
208    /// <summary>
209    /// Changes color of players coordinates
210    /// </summary>
211    /// <param name="color">Color</param>
212    public void UpdatePlayer(BlockType type)
213    {
214        playfield[playerX, playerY].Type = type;
215    }
216}
217
Note: See TracBrowser for help on using the repository browser.