select difficulty level (when play against bot) using a dedicated frame to show a graphics menu
This commit is contained in:
@@ -27,6 +27,7 @@ long exec_t2= millis();
|
|||||||
|
|
||||||
enum game_statuses : uint8_t {
|
enum game_statuses : uint8_t {
|
||||||
MENU,
|
MENU,
|
||||||
|
MENU_BOT_SKILLS,
|
||||||
TIMER,
|
TIMER,
|
||||||
RUN,
|
RUN,
|
||||||
SCORE,
|
SCORE,
|
||||||
@@ -45,12 +46,14 @@ Paddle* p1= nullptr;
|
|||||||
Paddle* p2= nullptr;
|
Paddle* p2= nullptr;
|
||||||
HumanPaddle human_pad1(1, P1_BTN_UP, P1_BTN_BOTTOM);
|
HumanPaddle human_pad1(1, P1_BTN_UP, P1_BTN_BOTTOM);
|
||||||
HumanPaddle human_pad2(4, P2_BTN_UP, P2_BTN_BOTTOM);
|
HumanPaddle human_pad2(4, P2_BTN_UP, P2_BTN_BOTTOM);
|
||||||
BotPaddle bot_pad1(1, 0, 2);
|
BotPaddle bot_pad1(1, 0);
|
||||||
BotPaddle bot_pad2(4, MATRIX_WIDTH-1, 2);
|
BotPaddle bot_pad2(4, MATRIX_WIDTH-1);
|
||||||
|
|
||||||
uint8_t current_gmode_idx= 0;
|
uint8_t current_gmode_idx= 0;
|
||||||
bool update_menu= 1;
|
bool update_menu= true;
|
||||||
bool mode_selected= 0;
|
bool mode_selected= false;
|
||||||
|
uint8_t current_bot_menu_idx= 0;
|
||||||
|
bool update_menu_bot_skills= true;
|
||||||
|
|
||||||
Engine engine(ball, INITIAL_BALL_DELAY);
|
Engine engine(ball, INITIAL_BALL_DELAY);
|
||||||
Renderer renderer(ball, frame, matrix);
|
Renderer renderer(ball, frame, matrix);
|
||||||
@@ -81,6 +84,7 @@ void loop() {
|
|||||||
else if (digitalRead(P2_BTN_UP) == LOW && current_gmode_idx > 0) {
|
else if (digitalRead(P2_BTN_UP) == LOW && current_gmode_idx > 0) {
|
||||||
update_menu= true;
|
update_menu= true;
|
||||||
current_gmode_idx -= 1;
|
current_gmode_idx -= 1;
|
||||||
|
game_mode= PVP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. P vs P
|
// 1. P vs P
|
||||||
@@ -94,12 +98,16 @@ void loop() {
|
|||||||
p1= &human_pad1;
|
p1= &human_pad1;
|
||||||
p2= &bot_pad2;
|
p2= &bot_pad2;
|
||||||
mode_selected= true;
|
mode_selected= true;
|
||||||
|
update_menu= false;
|
||||||
|
game_mode= PVC;
|
||||||
}
|
}
|
||||||
// 3. CPU vs CPU
|
// 3. CPU vs CPU
|
||||||
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && game_modes(current_gmode_idx) == CVC) {
|
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW && game_modes(current_gmode_idx) == CVC) {
|
||||||
p1= &bot_pad1;
|
p1= &bot_pad1;
|
||||||
p2= &bot_pad2;
|
p2= &bot_pad2;
|
||||||
mode_selected= true;
|
mode_selected= true;
|
||||||
|
update_menu= false;
|
||||||
|
game_mode= CVC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_menu) {
|
if (update_menu) {
|
||||||
@@ -112,7 +120,36 @@ void loop() {
|
|||||||
else if (mode_selected) {
|
else if (mode_selected) {
|
||||||
engine.set_players(p1, p2);
|
engine.set_players(p1, p2);
|
||||||
renderer.set_players(p1, p2);
|
renderer.set_players(p1, p2);
|
||||||
|
if (game_mode == PVC || game_mode == CVC) {
|
||||||
|
game_status= MENU_BOT_SKILLS;
|
||||||
|
delay(300); // avoid accidental double click for next menu
|
||||||
|
}
|
||||||
|
else game_status= TIMER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MENU_BOT_SKILLS: {
|
||||||
|
if (digitalRead(P2_BTN_BOTTOM) == LOW && current_bot_menu_idx < sizeof(frame_bot_skills)/sizeof(frame_bot_skills[0]) -1) {
|
||||||
|
current_bot_menu_idx += 1;
|
||||||
|
update_menu_bot_skills= true;
|
||||||
|
}
|
||||||
|
else if (digitalRead(P2_BTN_UP) == LOW && current_bot_menu_idx > 0) {
|
||||||
|
current_bot_menu_idx -= 1;
|
||||||
|
update_menu_bot_skills= true;
|
||||||
|
}
|
||||||
|
else if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW) {
|
||||||
|
if (!p1 -> is_human()) p1 -> set_skills(current_bot_menu_idx + 1);
|
||||||
|
if (!p2 -> is_human()) p2 -> set_skills(current_bot_menu_idx + 1);
|
||||||
game_status= TIMER;
|
game_status= TIMER;
|
||||||
|
update_menu_bot_skills= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_menu_bot_skills) {
|
||||||
|
const byte (*current_skill_frame)[12]= frame_bot_skills[current_bot_menu_idx];
|
||||||
|
matrix.loadPixels((uint8_t*)current_skill_frame, MATRIX_HEIGHT * MATRIX_WIDTH);
|
||||||
|
update_menu= false;
|
||||||
|
delay(300);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/font.cpp
24
src/font.cpp
@@ -212,3 +212,27 @@ const byte frame_cvc[MATRIX_HEIGHT][MATRIX_WIDTH] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const byte (*frame_gmodes[3])[12]= {frame_pvp, frame_pvc, frame_cvc};
|
const byte (*frame_gmodes[3])[12]= {frame_pvp, frame_pvc, frame_cvc};
|
||||||
|
|
||||||
|
const byte frame_bot_skill_easy[MATRIX_HEIGHT][MATRIX_WIDTH] = {
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
|
||||||
|
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
|
||||||
|
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0 },
|
||||||
|
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0 },
|
||||||
|
{ 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const byte frame_bot_skill_hard[MATRIX_HEIGHT][MATRIX_WIDTH] = {
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
|
||||||
|
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
|
||||||
|
{ 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
|
||||||
|
{ 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 },
|
||||||
|
{ 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const byte (*frame_bot_skills[3])[12]= {frame_bot_skill_easy, frame_bot_skill_hard};
|
||||||
|
|||||||
@@ -13,4 +13,8 @@ extern const byte frame_pvc[MATRIX_HEIGHT][MATRIX_WIDTH];
|
|||||||
extern const byte frame_cvc[MATRIX_HEIGHT][MATRIX_WIDTH];
|
extern const byte frame_cvc[MATRIX_HEIGHT][MATRIX_WIDTH];
|
||||||
extern const byte (*frame_gmodes[3])[12];
|
extern const byte (*frame_gmodes[3])[12];
|
||||||
|
|
||||||
|
extern const byte frame_bot_skill_easy[MATRIX_HEIGHT][MATRIX_WIDTH];
|
||||||
|
extern const byte frame_bot_skill_hard[MATRIX_HEIGHT][MATRIX_WIDTH];
|
||||||
|
extern const byte (*frame_bot_skills[3])[12];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,10 +44,14 @@ bool Paddle::check_pad_movement(Ball &ball) {
|
|||||||
// redefine me
|
// redefine me
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Paddle::get_skills() {
|
uint8_t Paddle::get_skills() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Paddle::set_skills(uint8_t skills) {
|
||||||
|
}
|
||||||
|
|
||||||
bool HumanPaddle::check_pad_movement() {
|
bool HumanPaddle::check_pad_movement() {
|
||||||
bool need_refresh= false;
|
bool need_refresh= false;
|
||||||
if (digitalRead(_pin_btn_top) == LOW) {
|
if (digitalRead(_pin_btn_top) == LOW) {
|
||||||
@@ -66,6 +70,8 @@ bool BotPaddle::check_pad_movement(Ball &ball) {
|
|||||||
int8_t ball_dir= ball.get_direction_x();
|
int8_t ball_dir= ball.get_direction_x();
|
||||||
int8_t ball_dir_ver= ball.get_direction_y();
|
int8_t ball_dir_ver= ball.get_direction_y();
|
||||||
|
|
||||||
|
uint8_t skills= this -> get_skills();
|
||||||
|
|
||||||
// ball is moving left and pad is on right, do not move
|
// ball is moving left and pad is on right, do not move
|
||||||
if (ball_dir < 0 && _pos_x > MATRIX_WIDTH / 2) return false;
|
if (ball_dir < 0 && _pos_x > MATRIX_WIDTH / 2) return false;
|
||||||
// ball is moving right and pad is on left, do not move
|
// ball is moving right and pad is on left, do not move
|
||||||
@@ -74,18 +80,18 @@ bool BotPaddle::check_pad_movement(Ball &ball) {
|
|||||||
uint8_t ball_x= ball.get_x();
|
uint8_t ball_x= ball.get_x();
|
||||||
int8_t ball_distance= ball_x - _pos_x;
|
int8_t ball_distance= ball_x - _pos_x;
|
||||||
if (ball_distance < 0) ball_distance *= -1;
|
if (ball_distance < 0) ball_distance *= -1;
|
||||||
switch (this -> get_skills()) {
|
switch (skills) {
|
||||||
case 1:
|
case 1:
|
||||||
if (ball_distance > 2) return false;
|
if (ball_distance > 3) return false;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (ball_distance > 3) return false;
|
if (ball_distance > 4) return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO BotPaddle movement logics
|
uint8_t move_chances= random(skills * 10) % 2;
|
||||||
// on higher difficult level i could also check the ball direction
|
if (!move_chances) return false;
|
||||||
// or at lover difficulty level i could also check the distance from the pad and move only when the ball si near
|
|
||||||
enum Movement {NONE, UP, DOWN};
|
enum Movement {NONE, UP, DOWN};
|
||||||
Movement _movment= NONE;
|
Movement _movment= NONE;
|
||||||
|
|
||||||
@@ -113,3 +119,9 @@ bool BotPaddle::check_pad_movement(Ball &ball) {
|
|||||||
uint8_t BotPaddle::get_skills() {
|
uint8_t BotPaddle::get_skills() {
|
||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BotPaddle::set_skills(uint8_t skills) {
|
||||||
|
if (skills < 0) _skills= 0;
|
||||||
|
else if (skills > 1) _skills= 1;
|
||||||
|
else _skills= skills;
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class Paddle {
|
|||||||
virtual bool check_pad_movement();
|
virtual bool check_pad_movement();
|
||||||
virtual bool check_pad_movement(Ball &ball);
|
virtual bool check_pad_movement(Ball &ball);
|
||||||
virtual uint8_t get_skills();
|
virtual uint8_t get_skills();
|
||||||
|
virtual void set_skills(uint8_t skills);
|
||||||
};
|
};
|
||||||
|
|
||||||
class HumanPaddle : public Paddle {
|
class HumanPaddle : public Paddle {
|
||||||
@@ -46,13 +47,11 @@ class BotPaddle : public Paddle {
|
|||||||
uint8_t _skills; // this is the difficulty level
|
uint8_t _skills; // this is the difficulty level
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BotPaddle(uint8_t position, uint8_t pos_x, uint8_t skills)
|
BotPaddle(uint8_t position, uint8_t pos_x)
|
||||||
: Paddle(position, false), _pos_x(pos_x), _skills(skills) {
|
: Paddle(position, false), _pos_x(pos_x) {}
|
||||||
if (_skills < 1) _skills= 1;
|
|
||||||
if (_skills > 2) _skills= 2;
|
|
||||||
}
|
|
||||||
bool check_pad_movement(Ball &ball);
|
bool check_pad_movement(Ball &ball);
|
||||||
uint8_t get_skills();
|
uint8_t get_skills();
|
||||||
|
void set_skills(uint8_t skills);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user