我已经开始用C ++编写Snake的代码。到目前为止,这是我的代码。
main.cpp:
#include "game.hpp"
int main(void)
{
Game game;
int count = 0;
while(game.program_is_running)
{
game.key_events();
if(count >= 3000)
{
game.tick();
count = 0;
}
else
count++;
}
return 0;
}
game.hpp:
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <vector>
#include "snake.hpp"
#define NUMBER_OF_ROWS 25
#define NUMBER_OF_COLUMNS 25
class Game
{
public:
Game(void);
void tick(void);
void key_events(void);
bool program_is_running;
private:
char grid[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
Snake snake;
bool right_pressed, left_pressed, down_pressed, up_pressed;
void display_grid(void);
};
Game::Game(void)
{
for(int y = 0; y < NUMBER_OF_ROWS; y++)
{
for(int x = 0; x < NUMBER_OF_COLUMNS; x++)
{
if(y == 0 || y == NUMBER_OF_ROWS - 1)
grid[y][x] = '#';
else if(x == 0 || x == NUMBER_OF_COLUMNS - 1)
grid[y][x] = '#';
else
grid[y][x] = ' ';
}
}
program_is_running = true;
right_pressed = false;
left_pressed = false;
down_pressed = false;
up_pressed = false;
}
void Game::tick(void)
{
for(int y = 0; y < NUMBER_OF_ROWS; y++)
{
for(int x = 0; x < NUMBER_OF_COLUMNS; x++)
{
if(y == 0 || y == NUMBER_OF_ROWS - 1)
grid[y][x] = '#';
else if(x == 0 || x == NUMBER_OF_COLUMNS - 1)
grid[y][x] = '#';
else
grid[y][x] = ' ';
}
}
std::vector<Block> snake_body = snake.get_body();
if(right_pressed)
{
snake.move(0, 1);
}
else if(left_pressed)
{
snake.move(0, -1);
}
else if(down_pressed)
{
snake.move(1, 0);
}
else if(up_pressed)
{
snake.move(-1, 0);
}
for(int y = 0; y < NUMBER_OF_ROWS; y++)
{
for(int x = 0; x < NUMBER_OF_COLUMNS; x++)
{
for(int i = 0; i < snake_body.size(); i++)
{
if(snake_body[i].y == y && snake_body[i].x == x)
{
grid[y][x] = snake.get_symbol();
}
}
}
}
display_grid();
}
void Game::key_events(void)
{
char c;
if(kbhit())
{
c = _getch();
switch(c)
{
case 'q':
program_is_running = false;
case 'l':
left_pressed = false;
down_pressed = false;
up_pressed = false;
right_pressed = true;
case 'h':
right_pressed = false;
down_pressed = false;
up_pressed = false;
left_pressed = true;
case 'j':
right_pressed = false;
left_pressed = false;
up_pressed = false;
down_pressed = true;
case 'k':
right_pressed = false;
down_pressed = false;
left_pressed = false;
up_pressed = true;
}
}
}
void Game::display_grid(void)
{
system("cls");
for(int y = 0; y < NUMBER_OF_ROWS; y++)
{
for(int x = 0; x < NUMBER_OF_COLUMNS; x++)
{
std::cout << grid[y][x] << ' ';
}
std::cout << std::endl;
}
}
snake.hpp:
#include <vector>
struct Block
{
int y, x;
};
class Snake
{
public:
Snake();
std::vector<Block> get_body();
char get_symbol(void);
void add_block(int, int);
void move(int, int);
private:
std::vector<Block> body;
char symbol;
};
Snake::Snake(void)
{
symbol = 'X';
add_block(12, 12);
}
std::vector<Block> Snake::get_body()
{
return body;
}
char Snake::get_symbol(void)
{
return symbol;
}
void Snake::add_block(int y, int x)
{
Block block;
block.y = y;
block.x = x;
body.push_back(block);
}
void Snake::move(int y, int x)
{
body[0].y += y;
body[0].x += x;
}
此刻,我只是想让蛇通过键k,j,h和l上下,左右移动。无论您按四个键中的哪一个,蛇都只会向上移动。为什么是这样?另外,如果有人可以就程序的结构提出建议,我将不胜感激。
答案 0 :(得分:4)
开关
switch(c)
{
case 'q':
program_is_running = false;
case 'l':
left_pressed = false;
down_pressed = false;
up_pressed = false;
right_pressed = true;
case 'h':
right_pressed = false;
down_pressed = false;
up_pressed = false;
left_pressed = true;
case 'j':
right_pressed = false;
left_pressed = false;
up_pressed = false;
down_pressed = true;
case 'k':
right_pressed = false;
down_pressed = false;
left_pressed = false;
up_pressed = true;
}
总是遇到最后一种情况,'k'
,所以您总是以
right_pressed = false;
down_pressed = false;
left_pressed = false;
up_pressed = true;
在每种情况下,您都应该添加break
,以避免这种情况。
就样式而言,我想知道是否可以将四个互斥事件的四个布尔值折叠成一个标志,以显示要移动的值?
您可以拥有一个查找表(无序映射或类似的表),将键映射到move参数,然后仅调用move
而不需要switch语句。
答案 1 :(得分:1)
你没有休息;在您的情况之后:因此,您的switch语句将在每种情况下执行,并且由于“ up”是最后一种情况,因此它将覆盖所有其他情况。