A rouge-like rpg, heavily inspired on the binding of isaac. Running on a FRDM-K64F Mbed board. C++.
Dependencies: mbed MotionSensor
Player.cpp
00001 #include "Player.h" 00002 #include "math.h" 00003 00004 // Constructor 00005 Player::Player(float pos_x, float pos_y) 00006 { 00007 _hp = 3; 00008 _attack = 1; 00009 _face = 2; 00010 00011 _hitbox.width = 6; 00012 _hitbox.height = 5; 00013 00014 _position.x = pos_x; 00015 _position.y = pos_y; 00016 00017 _sprite_size.width = 6; 00018 _sprite_size.height = 12; 00019 _sprite_size.offset_x = 0; 00020 _sprite_size.offset_y = -7; 00021 00022 _frame.count = 0; 00023 _frame.number = 0; 00024 _frame.max = 4; 00025 00026 for (int i = 0; i < bullets_max; i++) { 00027 valid_bullets[i] = false; 00028 } 00029 00030 _invulnerability_counter = INVULNERABILITY_PERIOD; 00031 00032 // Upgradable status 00033 _fire_rate_delay = 30; 00034 _fire_rate_counter = _fire_rate_delay; 00035 _velocity = 0.7; 00036 _bullet_speed = 1; 00037 } 00038 00039 Player::~Player() 00040 { 00041 delete_bullets(); 00042 } 00043 00044 // Accessors 00045 int Player::get_bullet_speed() 00046 { 00047 return _bullet_speed; 00048 } 00049 int Player::get_hearts_width() 00050 { 00051 return 9; 00052 } 00053 int Player::get_hearts_height() 00054 { 00055 return 9; 00056 } 00057 char * Player::get_hearts_sprite() 00058 { 00059 return (char *) sprite_heart; 00060 } 00061 00062 // Functions 00063 void Player::move(float mapped_x, float mapped_y, char * map, bool * doorways) // Update all bullet movement and player movement, also takes care of animation 00064 { 00065 move_player(mapped_x, mapped_y, map, doorways); 00066 move_bullets(); 00067 increment_frames(mapped_x, mapped_y); // Sets the face of the person, and increment frame count 00068 _invulnerability_counter++; // for damage checking 00069 } 00070 00071 void Player::move_player(float mapped_x, float mapped_y, char * map, bool * doorways) // Moves the player unless if the player walks onto a wall 00072 { 00073 update_prev_pos(); 00074 _position.y -= _velocity*mapped_y; 00075 _position.x += _velocity*mapped_x; 00076 00077 undo_move_x(entity_to_map_collision_test(_position.x, _prev_pos.y, map, doorways)); 00078 undo_move_y(entity_to_map_collision_test(_prev_pos.x, _position.y, map, doorways)); 00079 } 00080 00081 void Player::move_bullets() // For each bullet, move them 00082 { 00083 for (int i = 0; i < bullets_max; i++) { 00084 if (valid_bullets[i]) { 00085 bullets_array[i]->move(get_bullet_speed(), 0, 0, (bool *) 0); 00086 } 00087 } 00088 } 00089 00090 void Player::increment_frames(float mapped_x, float mapped_y) 00091 { 00092 if (abs(mapped_x) + abs(mapped_y) > 0.1f) { // If player is moving 00093 if (mapped_y < 0 && abs(mapped_y) > abs(mapped_x)) { 00094 _face = 2; 00095 } else if (mapped_y > 0 && abs(mapped_y) > abs(mapped_x)) { 00096 _face = 0; 00097 } else if (mapped_x > 0 && abs(mapped_x) > abs(mapped_y)) { 00098 _face = 1; 00099 } else if (mapped_x < 0 && abs(mapped_x) > abs(mapped_y)) { 00100 _face = 3; 00101 } 00102 if (_frame.number < _frame.max) { // Animate frames by incrementing and reseting frames 00103 _frame.count++; 00104 } else { 00105 _frame.count = 0; 00106 } 00107 } else { 00108 _frame.count = 0; // If the player is not moving, don't animate 00109 } 00110 _frame.number = (_frame.count/8) % _frame.max; // Frame number is used in chosing sprite-frame for animation; the constant 8 is the number of frames per sprite-frame 00111 } 00112 00113 void Player::take_damage(int damage) // Takes damage unless if player just got damaged within invulnerability period 00114 { 00115 if (damage < 0){ 00116 _hp -= damage; 00117 } 00118 else if (_invulnerability_counter >= INVULNERABILITY_PERIOD) { 00119 _hp -= damage; 00120 _invulnerability_counter = 0; 00121 } 00122 if (_hp > 5) { // Max HP is a constant 5, this might be an upgradable status later 00123 _hp = 5; 00124 } 00125 } 00126 00127 bool Player::delete_out_of_bounds_bullets(char * map, bool * doorways) // Attempts to delete bullets that are out of bounds or colliding with the wall, returns true if any bullets are deleted 00128 { 00129 bool result = false; 00130 for (int i = 0; i < bullets_max; i++) { 00131 if((valid_bullets[i]) && (bullets_array[i]->out_of_bounds_check(map, doorways))) { 00132 valid_bullets[i] = false; 00133 delete bullets_array[i]; 00134 result = true; 00135 } 00136 } 00137 return result; 00138 } 00139 00140 void Player::draw(N5110 &lcd) 00141 { 00142 draw_player(lcd); 00143 } 00144 00145 void Player::draw_player(N5110 &lcd) 00146 { 00147 lcd.drawSpriteTransparent(_position.x+_sprite_size.offset_x, 00148 _position.y+_sprite_size.offset_y, 00149 _sprite_size.height, 00150 _sprite_size.width, 00151 get_frame()); 00152 } 00153 00154 void Player::draw_bullets(N5110 &lcd, int j) 00155 { 00156 for (int i = 0; i < bullets_max; i++) { 00157 if ((valid_bullets[i]) && (bullets_array[i]->get_pos_y() == j)) { 00158 bullets_array[i]->draw(lcd); 00159 } 00160 } 00161 } 00162 00163 void Player::delete_bullets() // Delete all bullets, normally used in unloading 00164 { 00165 for (int i = 0; i < bullets_max; i++) { 00166 if (valid_bullets[i]) { 00167 delete bullets_array[i]; 00168 valid_bullets[i] = false; 00169 } 00170 } 00171 } 00172 00173 char * Player::get_frame() // Returns the current frame's sprite pointer 00174 { 00175 if ((_invulnerability_counter < INVULNERABILITY_PERIOD) && (_invulnerability_counter % 10 <= 4)) { 00176 return (char*) sprite_transparent_player; 00177 } 00178 return (char *) sprite_player[_face][_frame.number]; 00179 } 00180 00181 void Player::buttons(bool button_A, bool button_B, bool button_Y, bool button_X) // Summons new bullets and overloads the player face when buttons are pressed 00182 { 00183 _fire_rate_counter++; 00184 if (button_Y) { 00185 _face = 0; 00186 } else if (button_B) { 00187 _face = 1; 00188 } else if (button_A) { 00189 _face = 2; 00190 } else if (button_X) { 00191 _face = 3; 00192 } 00193 if (button_Y || button_B || button_A || button_X) { 00194 for (int i = 0; i < bullets_max; i++) { 00195 if (!valid_bullets[i] && (_fire_rate_counter >= _fire_rate_delay)) { // waits until _fire_rate_delay is done before creating a bullet in an invalid slot of bullet_array 00196 bullets_array[i] = new Bullets(_position.x+2, _position.y+2, _face); 00197 valid_bullets[i] = true; 00198 _fire_rate_counter = 0; 00199 break; 00200 } 00201 } 00202 } 00203 }
Generated on Tue Jul 19 2022 23:32:07 by 1.7.2