1 /*
2  * Copyright (C) 2011-2012 Me and My Shadow
3  *
4  * This file is part of Me and My Shadow.
5  *
6  * Me and My Shadow is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Me and My Shadow is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Me and My Shadow.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef PLAYER_H
21 #define PLAYER_H
22 
23 #include "ThemeManager.h"
24 #include <vector>
25 #include <string>
26 #include <SDL.h>
27 
28 //Debug the game record file.
29 //#define RECORD_FILE_DEBUG
30 
31 class Block;
32 class Game;
33 class PlayerScriptAPI;
34 
35 //The different player buttons.
36 //The right arrow.
37 const int PlayerButtonRight=0x01;
38 //The left arrow.
39 const int PlayerButtonLeft=0x02;
40 //The up arrow for jumping.
41 const int PlayerButtonJump=0x04;
42 //The down arrow for actions.
43 const int PlayerButtonDown=0x08;
44 //space bar for recording. (Only in recordButton)
45 const int PlayerButtonSpace=0x10;
46 
47 class Player{
48 	friend class PlayerScriptAPI;
49 protected:
50 	//Vector used to store the player actions in when recording.
51 	//These can be given to the shadow so he can execute them.
52 	std::vector<int> playerButton;
53 	//Vector used to store the playerButton vector when saving the player's state (checkpoint).
54 	std::vector<int> playerButtonSaved;
55 
56 private:
57 	//Vector used to record the whole game play.
58 	//And saved record in checkpoint.
59 	std::vector<int> recordButton,savedRecordButton;
60 
61 	//record index. -1 means read input from keyboard,
62 	//otherwise read input from recordings (recordButton[recordIndex]).
63 	int recordIndex;
64 
65 	//Vector containing squares along the path the player takes when recording.
66 	//It will be drawn as a trail of squares.
67 	std::vector<SDL_Rect> line;
68 	//Vector that will hold the line vector when saving the player's state (checkpoint).
69 	std::vector<SDL_Rect> lineSaved;
70 
71 	//Boolean if the player called the shadow to copy his moves.
72 	bool shadowCall;
73 	//Boolean if the player is recording his moves.
74 	bool record,recordSaved;
75 
76 	//The following variables are to store a state.
77 	//Rectangle containing the players location.
78 	SDL_Rect boxSaved;
79 	//Boolean if the player is in the air.
80 	bool inAirSaved;
81 	//Boolean if the player is (going to) jump(ing).
82 	bool isJumpSaved;
83 	//Boolean if the player can move.
84 	bool canMoveSaved;
85 	//Boolean if the player is holding the other (shadow).
86 	bool holdingOtherSaved;
87 	//The x velocity.
88 	//NOTE: The x velocity is used to indicate that there's a state saved.
89 	int xVelSaved;
90 	//The y velocity.
91 	int yVelSaved;
92 	//The state.
93 	int stateSaved;
94 
95 protected:
96 	//Rectangle containing the player's location.
97 	SDL_Rect box;
98 
99 	//The x and y velocity.
100 	int xVel, yVel;
101 	//The base x and y velocity, used for standing on moving blocks.
102 	int xVelBase, yVelBase;
103 
104 	//Boolean if the player is in the air.
105 	bool inAir;
106 	//Boolean if the player is (going to) jump(ing).
107 	bool isJump;
108 	//Boolean if the player can move.
109 	bool canMove;
110 	//Boolean if the player is dead.
111 	bool dead;
112 
113 	//The direction the player is walking, 0=right, 1=left.
114 	int direction;
115 	//Integer containing the state of the player.
116 	int state;
117 	//The time the player is in the air (jumping).
118 	int jumpTime;
119 	//Boolean if the player is in fact the shadow.
120 	bool shadow;
121 
122 	//Pointer to the Game state.
123 	friend class Game;
124 	Game* objParent;
125 
126 	//Boolean if the downkey is pressed.
127 	bool downKeyPressed;
128 	//Boolean if the space keu is pressed.
129 	bool spaceKeyPressed;
130 	//Pointer to the object that is currently been stand on by the player.
131 	//This is always a valid pointer.
132 	Block* objCurrentStand;
133 	//Pointer to the object the player stood last on.
134 	//NOTE: This is a weak reference only.
135 	Block* objLastStand;
136 	//Pointer to the teleporter the player last took.
137 	//NOTE: This is a weak reference only.
138 	Block* objLastTeleport;
139 	//Pointer to the notification block the player is in front of.
140 	//This is always a valid pointer.
141 	Block* objNotificationBlock;
142 	//Pointer to the shadow block the player is in front of.
143 	//This is always a valid pointer.
144 	Block* objShadowBlock;
145 
146 	//The save variable for the GameObject pointers.
147 	//FIXME: Also save the other game object pointers?
148 	Block* objCurrentStandSave;
149 	Block* objLastStandSave;
150 
151 public:
152 
153 	//X and y location where the player starts and gets when reseted.
154 	int fx, fy;
155 	//The appearance of the player.
156 	ThemeBlockInstance appearance;
157 	//Boolean if the player is holding the other.
158 	bool holdingOther;
159 
160 	//Constructor.
161 	//objParent: Pointer to the Game state.
162 	Player(Game* objParent);
163 	//Destructor.
164 	~Player();
165 
166 	//Method used to set the position of the player.
167 	//x: The new x location of the player.
168 	//y: The new y location of the player.
169 	void setLocation(int x,int y);
170 
171 	//Method used to handle (key) input.
172 	//shadow: Pointer to the shadow used for recording/calling.
173 	void handleInput(class Shadow* shadow);
174 	//Method used to do the movement of the player.
175 	//NOTE: should call collision() for both player/shadow before call move().
176 	//levelObjects: Array containing the levelObjects, used to check collision.
177 	//lastX, lastY: the position of player before calling collision().
178 	void move(std::vector<Block*> &levelObjects, int lastX, int lastY);
179 	//Method used to check if the player can jump and executes the jump.
180 	//strength: The strength of the jump.
181 	void jump(int strength=13);
182 
183 	//This method will render the player to the screen.
184     void show(SDL_Renderer &renderer);
185 	//Method that stores the actions if the player is recording.
186 	void shadowSetState();
187 
188 	//Method that will reset the state to 0.
189 	virtual void stateReset();
190 
191 	//This method checks the player against the other to see if they stand on eachother.
192 	//other: The shadow or the player.
193 	void otherCheck(class Player* other);
194 
195 	//Method that will ease the camera so that the player is in the center.
196 	void setMyCamera();
197 	//This method will reset the player to it's initial position.
198 	//save: Boolean if the saved state should also be deleted.
199 	void reset(bool save);
200 	//Method used to retrieve the current location of the player.
201 	//Returns: SDL_Rect containing the player's location.
202 	SDL_Rect getBox();
203 
204 	//This method will
205 	void shadowGiveState(class Shadow* shadow);
206 
207 	//Method that will save the current state.
208 	//NOTE: The special <name>Saved variables will be used.
209 	virtual void saveState();
210 	//Method that will retrieve the last saved state.
211 	//If there is none it will reset the player.
212 	virtual void loadState();
213 	//Method that checks if the player can save the state.
214 	//Returns: True if the player can save his state.
215 	virtual bool canSaveState();
216 	//Method that checks if the player can load a state.
217 	//Returns: True if the player can load a state.
218 	virtual bool canLoadState();
219 	//Method that will swap the state of the player with the other.
220 	//other: The player or the shadow.
221 	void swapState(Player* other);
222 
223 	//Check if this player is in fact the shadow.
224 	//Returns: True if this is the shadow.
isShadow()225 	inline bool isShadow(){
226 		return shadow;
227 	}
228 
229 	//Method for returning the objCurrentStand pointer.
230 	//Returns: Pointer to the gameobject the player is standing on.
getObjCurrentStand()231 	inline Block* getObjCurrentStand(){
232 		return objCurrentStand;
233 	}
234 
235 	//Let the player die when he falls of or hits spikes.
236 	//animation: Boolean if the death animation should be played, default is true.
237 	void die(bool animation=true);
238 
239 	//Check if currently it's play from record file.
240 	bool isPlayFromRecord();
241 
242 	//get the game record object.
243 	std::vector<int>* getRecord();
244 
245 #ifdef RECORD_FILE_DEBUG
246 	std::string& keyPressLog();
247 	std::vector<SDL_Rect>& playerPosition();
248 #endif
249 
250 	//play the record.
251 	void playRecord();
252 
253 private:
254 	//The space key is down. call this function from handleInput and another function.
255 	void spaceKeyDown(class Shadow* shadow);
256 
257 public:
258 	//Method that will handle the actual movement.
259 	//NOTE: partially internal function. Should call collision() for both player/shadow before call move().
260 	//levelObjects: Array containing the levelObjects, used to check collision.
261 	void collision(std::vector<Block*> &levelObjects, Player* other);
262 
263 };
264 
265 #endif
266