写一个带图像的贪吃蛇C++
时间: 2024-01-06 22:04:20 浏览: 27
以下是一个简单的带图像的贪吃蛇C++代码,使用了SFML图形库:
```c++
#include <SFML/Graphics.hpp>
#include <deque>
// 窗口大小
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;
// 蛇身大小
const int SNAKE_SIZE = 20;
// 蛇的方向
enum class Direction {
Up,
Down,
Left,
Right
};
// 蛇
class Snake {
public:
// 初始化蛇
Snake(int x, int y) {
// 初始化蛇头
head.setPosition(x, y);
head.setSize(sf::Vector2f(SNAKE_SIZE, SNAKE_SIZE));
head.setFillColor(sf::Color::Green);
// 初始化蛇身
for (int i = 1; i < 4; i++) {
sf::RectangleShape body(sf::Vector2f(SNAKE_SIZE, SNAKE_SIZE));
body.setPosition(x - i * SNAKE_SIZE, y);
body.setFillColor(sf::Color::White);
snake_body.push_back(body);
}
// 初始化方向
direction = Direction::Right;
}
// 移动蛇
void move() {
// 记录蛇尾位置
sf::Vector2f tail_pos = snake_body.back().getPosition();
// 移动蛇身
for (int i = snake_body.size() - 1; i > 0; i--) {
sf::Vector2f prev_pos = snake_body[i - 1].getPosition();
snake_body[i].setPosition(prev_pos);
}
// 移动蛇头
switch (direction) {
case Direction::Up:
head.move(0, -SNAKE_SIZE);
break;
case Direction::Down:
head.move(0, SNAKE_SIZE);
break;
case Direction::Left:
head.move(-SNAKE_SIZE, 0);
break;
case Direction::Right:
head.move(SNAKE_SIZE, 0);
break;
}
// 将蛇尾移到蛇头位置
snake_body.front().setPosition(head.getPosition());
// 将蛇尾放在蛇尾位置
snake_body.push_front(sf::RectangleShape(sf::Vector2f(SNAKE_SIZE, SNAKE_SIZE)));
snake_body.front().setPosition(tail_pos);
snake_body.pop_back();
}
// 改变蛇的方向
void change_direction(Direction new_direction) {
direction = new_direction;
}
// 检查是否吃到食物
bool eat_food(sf::RectangleShape food) {
if (head.getGlobalBounds().intersects(food.getGlobalBounds())) {
snake_body.push_back(sf::RectangleShape(sf::Vector2f(SNAKE_SIZE, SNAKE_SIZE)));
snake_body.back().setFillColor(sf::Color::White);
return true;
}
return false;
}
// 检查蛇是否撞墙或撞自己
bool check_collision() {
// 检查是否撞墙
if (head.getPosition().x < 0 || head.getPosition().x >= WINDOW_WIDTH ||
head.getPosition().y < 0 || head.getPosition().y >= WINDOW_HEIGHT) {
return true;
}
// 检查是否撞自己
for (int i = 1; i < snake_body.size(); i++) {
if (head.getGlobalBounds().intersects(snake_body[i].getGlobalBounds())) {
return true;
}
}
return false;
}
// 绘制蛇
void draw(sf::RenderWindow& window) {
window.draw(head);
for (auto& body : snake_body) {
window.draw(body);
}
}
private:
sf::RectangleShape head;
std::deque<sf::RectangleShape> snake_body;
Direction direction;
};
// 食物
class Food {
public:
// 初始化食物
Food() {
food.setSize(sf::Vector2f(SNAKE_SIZE, SNAKE_SIZE));
food.setFillColor(sf::Color::Red);
// 随机生成位置
int x = rand() % (WINDOW_WIDTH / SNAKE_SIZE) * SNAKE_SIZE;
int y = rand() % (WINDOW_HEIGHT / SNAKE_SIZE) * SNAKE_SIZE;
food.setPosition(x, y);
}
// 绘制食物
void draw(sf::RenderWindow& window) {
window.draw(food);
}
// 获取食物位置
sf::Vector2f get_position() {
return food.getPosition();
}
private:
sf::RectangleShape food;
};
int main() {
// 创建窗口
sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Snake Game");
// 创建蛇和食物
Snake snake(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
Food food;
// 游戏循环
while (window.isOpen()) {
// 处理事件
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
// 改变蛇的方向
if (event.type == sf::Event::KeyPressed) {
switch (event.key.code) {
case sf::Keyboard::Up:
snake.change_direction(Direction::Up);
break;
case sf::Keyboard::Down:
snake.change_direction(Direction::Down);
break;
case sf::Keyboard::Left:
snake.change_direction(Direction::Left);
break;
case sf::Keyboard::Right:
snake.change_direction(Direction::Right);
break;
}
}
}
// 移动蛇
snake.move();
// 检查是否吃到食物
if (snake.eat_food(food.get_position())) {
food = Food();
}
// 检查蛇是否撞墙或撞自己
if (snake.check_collision()) {
window.close();
}
// 绘制游戏场景
window.clear(sf::Color::Black);
snake.draw(window);
food.draw(window);
window.display();
}
return 0;
}
```
这个代码使用了deque来存储蛇的身体,使用了SFML图形库来绘制图像和处理事件。在游戏循环中,不断处理事件、移动蛇、检查是否吃到食物、检查是否撞墙或撞自己,然后绘制游戏场景。