运行截图

等待开始界面

运行过程

失败界面截图

SFML配置

csdn上面已经有很多SFML配置的blog,随便就能搜到。正常配置好SFML后,还需要将字体ttf文件放在源代码同一目录和exe同一目录中,不然无法显示字符

代码部分

下面贴上各个部分的代码

头文件和全局常量

#include <SFML/Graphics.hpp>
#include <time.h>
#include<iostream>
#include<conio.h>const int BodyMaxLong = 2000;        //最长蛇身
const int SnakeInitLongth = 10;      //初始蛇身
const sf::Vector2f SnakeInitPos = {200,200}; //蛇头初始位置
const int BodyRadius = 5;             //蛇身半径
const sf::Vector2i WindowSize = { 500,500 };
const int FoodRadius = 2;
const int FoodNum = 30;
#define SnakeColor sf::Color::Green
#define FoodColor sf::Color::Red

sfml中已经定义了颜色可以直接用,还有图形类和二维向量类(int型vector2i,float型vector2f),都在名称空间sf中。

既然是贪吃蛇游戏,那么一定有蛇啦。

class Snake {                       //蛇
private:int longth;                            //蛇身长度sf::Vector2f dir;                        //蛇当前行进方向sf::CircleShape body[BodyMaxLong];        //用圆形类来建造蛇身
public:Snake() {longth = SnakeInitLongth;dir = { 5 , 0 };                       //初始方向for (int i = 0;i < 5;i++) {            //初始化位置和蛇身每个圆形之间的间距sf::Vector2f pos = { SnakeInitPos.x - i * 5, SnakeInitPos.y };body[i].setPosition(pos);}for (int i = 0;i < BodyMaxLong;i++) {        //初始化蛇身半径和颜色body[i].setRadius(BodyRadius);body[i].setFillColor(SnakeColor);}}void SnakeMove() {                      //整体移动蛇身函数,用一个循环依次移动每一个蛇身for (int i = longth - 1;i > 0;i--){body[i].setPosition(body[i - 1].getPosition().x,body[i - 1].getPosition().y);}body[0].move(dir);}void SnakeHolding(sf::Event &event) {            //控制蛇行进方向switch (event.key.code){case sf::Keyboard::Up:case sf::Keyboard::W:if (dir.x != 0 && dir.y != 5) { dir = { 0,-5 }; }break;case sf::Keyboard::Left:case sf::Keyboard::A:if (dir.x != 5 && dir.y != 0) { dir = { -5,0 }; }break;case sf::Keyboard::Right:case sf::Keyboard::D:if (dir.x != -5 && dir.y != 0) { dir = { 5,0 }; }break;case sf::Keyboard::Down:case sf::Keyboard::S:if (dir.x != 0 && dir.y != -5) { dir = { 0 , 5 }; }break;default:break;}}sf::CircleShape PreDrawSnake(int i) {        //在主函数绘制蛇时需要返回每个圆形对象return this->body[i];}int GetSnakeLongth() {return this->longth;}void UpLevel() { this->longth++; }            //吃到食物升级,长度自增sf::Vector2f GetDir() { return dir; }
};

食物

typedef struct {        //一个包含下x,y两个整型的结构体,用于表示坐标,本来可以用vector2i的,发现下面老是报错就尝试自己写个结构体,发现可以运行就这么运行了int x;int y;
}PosData;class Food {                            //食物类
private:PosData pos;sf::CircleShape Body;
public:Food() {pos = { rand() % 500,rand() % 500 };            //初始化随机食物位置Body.setFillColor(FoodColor);                    //初始化食物颜色Body.setPosition({(float)pos.x,(float)pos.y});        //将位置设置进图形对象中Body.setRadius(FoodRadius);                        //初始化食物的图形半径}sf::Vector2f GetFoodPos() {                           //返回食物位置的函数 return { (float)this->pos.x+FoodRadius,(float)this->pos.y+FoodRadius };}void SetFoodPos() {                    //一旦被吃掉,重新随机获得一个位置pos = { rand() % WindowSize.x, rand() % WindowSize.y };Body.setPosition({(float)pos.x,(float)pos.y});}sf::CircleShape PreDraFood() { return this->Body; }        //返回图形对象,以便绘制和其他功能
};

判断函数

检查有没有吃到食物用的函数

void GetFoodCheck(Snake& snake, Food& food) {sf::Vector2f snakepos = { snake.PreDrawSnake(0).getPosition().x+BodyRadius,snake.PreDrawSnake(0).getPosition().y+BodyRadius};sf::Vector2f foodpos = food.GetFoodPos();if (foodpos.x >= snakepos.x - BodyRadius && foodpos.x <= snakepos.x + BodyRadius && foodpos.y>=snakepos.y - BodyRadius && foodpos.y<=snakepos.y + BodyRadius) {snake.UpLevel();food.SetFoodPos();}
}

检查有没有撞墙或者咬到尾巴的函数,都没有则返回1,有其一则返回0

bool CollideCheck(Snake& snake) {sf::CircleShape head = snake.PreDrawSnake(0);if (head.getPosition().x >= WindowSize.x || head.getPosition().x <= 0 || head.getPosition().y >= WindowSize.y || head.getPosition().y <= 0){return 0;}int longth = snake.GetSnakeLongth();for (int i = 1;i < longth;i++) {if (snake.GetDir().x == 0){if (snake.PreDrawSnake(0).getPosition().x + BodyRadius >= snake.PreDrawSnake(i).getPosition().x && snake.PreDrawSnake(0).getPosition().x + BodyRadius <= snake.PreDrawSnake(i).getPosition().x + BodyRadius * 2){if (snake.GetDir().y > 0){if (snake.PreDrawSnake(0).getPosition().y + BodyRadius * 2 >= snake.PreDrawSnake(i).getPosition().y && snake.PreDrawSnake(0).getPosition().y + BodyRadius * 2 <= snake.PreDrawSnake(i).getPosition().y + BodyRadius * 2){return 0;}}else {if (snake.PreDrawSnake(0).getPosition().y >= snake.PreDrawSnake(i).getPosition().y && snake.PreDrawSnake(0).getPosition().y <= snake.PreDrawSnake(i).getPosition().y + BodyRadius * 2){return 0;}}}}if (snake.GetDir().y == 0){if (snake.PreDrawSnake(0).getPosition().y + BodyRadius >= snake.PreDrawSnake(i).getPosition().y && snake.PreDrawSnake(0).getPosition().y + BodyRadius <= snake.PreDrawSnake(i).getPosition().y + BodyRadius * 2){if (snake.GetDir().x > 0){if (snake.PreDrawSnake(0).getPosition().x + BodyRadius * 2 >= snake.PreDrawSnake(i).getPosition().x && snake.PreDrawSnake(0).getPosition().x + BodyRadius * 2 <= snake.PreDrawSnake(i).getPosition().x + BodyRadius * 2){return 0;}}else {if (snake.PreDrawSnake(0).getPosition().x  >= snake.PreDrawSnake(i).getPosition().x && snake.PreDrawSnake(0).getPosition().x  <= snake.PreDrawSnake(i).getPosition().x + BodyRadius * 2){return 0;}}}}}return 1;
}

main函数

int main()
{sf::Text text,score,pretext;sf::Font font,cnfont;font.loadFromFile("arial.ttf");            //加载字体文件cnfont.loadFromFile("hpsimplifiedhans-light.ttf");text.setPosition(1, 1);        //设置字体的位置score.setPosition(100, 1);pretext.setPosition(20,150);        pretext.setString("Welcome to shushuSnake Game\npress space button\n start the game");                        //设置字符内容pretext.setFont(font);pretext.setFillColor(sf::Color::Blue);text.setString("Score:");text.setFont(font);score.setFont(font);text.setFillColor(sf::Color::Black);score.setFillColor(sf::Color::Black);std::string str;srand((int)time(0));        sf::RenderWindow window(sf::VideoMode(WindowSize.x,WindowSize.y),"shushuSnake");Snake snake;            //创建蛇Food food[FoodNum];        //创建食物sf::Clock clock;                //double timer = 0, delay = 0.05;           //bool prep = 0;            //若prep = 0 等待玩家按空格开始游戏,开始游戏后prep = 1int longth;while (window.isOpen()){if (!prep){sf::Event event;while (window.pollEvent(event)) {if (event.type == sf::Event::Closed) {window.close();}if (event.type == sf::Event::KeyPressed) {if (event.key.code == sf::Keyboard::Space){prep = 1;}}}window.clear(sf::Color::White);window.draw(text);score.setString("0");window.draw(score);window.draw(pretext);window.display();}if (prep) {float time = clock.getElapsedTime().asSeconds();        //clock.restart();                        //timer += time;sf::Event event;while (window.pollEvent(event)) {if (event.type == sf::Event::Closed) {window.close();}if (event.type == sf::Event::KeyPressed) {snake.SnakeHolding(event);}}longth = snake.GetSnakeLongth();window.clear(sf::Color::White);for (int i = 0;i < FoodNum; i++)                     //食物绘制{window.draw(food[i].PreDraFood());}if (timer > delay) {timer = 0;snake.SnakeMove();for (int i = 0; i < FoodNum;i++){GetFoodCheck(snake, food[i]);}if (CollideCheck(snake) == 0)        //咬到尾巴或者撞到墙失败了{sf::Text endtext;endtext.setString("Game Over!!");endtext.setPosition(100, 150);endtext.setFont(font);endtext.setCharacterSize(50);endtext.setFillColor(sf::Color::Red);  window.clear(sf::Color::White);window.draw(text);window.draw(score);window.draw(endtext);longth = snake.GetSnakeLongth();for (int i = 0; i < longth;i++)                     //蛇身绘制window.draw(snake.PreDrawSnake(i));window.display();if (_getch())return 0;}str = std::to_string(snake.GetSnakeLongth() - SnakeInitLongth);score.setString(str);}for (int i = 0; i < longth;i++)                     //蛇身绘制window.draw(snake.PreDrawSnake(i));window.draw(text);window.draw(score);window.display();}}return 0;
}

欢迎大家一起讨论!

用c++和SFML实现简易的界面版贪吃蛇相关推荐

  1. C/C++制作简易版贪吃蛇游戏

    文章目录 C/C++制作简易版贪吃蛇游戏 一.开发环境 二.设计逻辑 三.代码块 3.1 使用initgraph()函数 3.2定义蛇和食物的结构体 3.3随机产生食物的坐标以及定义初始化的蛇的数据 ...

  2. 用Python做一个游戏——简易版贪吃蛇

    前言 今天,我来分享个中等级的简易版贪吃蛇,这次不是用turtle库,而是用pygame库和sys库. 1.导入库 我们需要把游戏所用的库导入进来: import pygame import sys ...

  3. JavaGUI简易版贪吃蛇小游戏

    做这个小游戏,主要是学习一下游戏制作的基本逻辑,加深对面向对象的理解. 游戏引擎: /*** 大牛程序员写的游戏的公共类 * 使用Game.init()方法初始化游戏* 使用Game.gameOver ...

  4. 简易贪吃蛇小游戏java版_用GUI实现java版贪吃蛇小游戏

    本文实例为大家分享了java版贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public stat ...

  5. 如何用c语言实现贪吃蛇登录界面,c语言贪吃蛇UI界面版.docx

    c语言UI界面版贪吃蛇 使用ege图形库,游戏实现单双人功能.道具有炸弹,随机魔盒,炸弹.有随机障碍物生成. 不附加图片 . /************************************ ...

  6. python界面小游戏贪吃蛇_用Python实现童年小游戏贪吃蛇

    贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中. 尽管贪吃蛇的历史相对比较久远,但它却有着十分顽强的生命力,保持经久不衰,其中很重要的原因便是游戏厂家不断的 ...

  7. python界面小游戏贪吃蛇_用Python实现童年贪吃蛇小游戏功能的实例代码

    贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中. 尽管贪吃蛇的历史相对比较久远,但它却有着十分顽强的生命力,保持经久不衰,其中很重要的原因便是游戏厂家不断的 ...

  8. 鸿蒙系统,鸿蒙app简易登录界面,界面开发教程

    鸿蒙系统,鸿蒙app简易登录界面,界面开发教程. // 这个是主Ability public class MainAbilitySlice extends AbilitySlice {@Overrid ...

  9. Android studio设计一个简易微信界面

    一.设计要求及实现构想 1.设计一个简易微信界面框架,包含至少4个tab页面(我设计的4个分别为message.contact.find.config),要求能实现四个页面之间的点击切换. 2.首先分 ...

最新文章

  1. linux安装mysql5.6.26_linux mysql-5.6.26 安装
  2. Android之INSTALL_FAILED_UPDATE_INCOMPATIBLE(pacakge:...do not match the previously installed version)
  3. 小程序添加和删除新元素功能实例
  4. Duplicate entry ‘‘ for key ‘***‘
  5. 【WiFi密码破解详细图文教程】ZOL仅此一份 详细介绍从CDlinux U盘启动到设置扫描破解-破解软件论坛-ZOL中关村在线...
  6. 女人让男人感到自卑的九个经典(摘于网络)
  7. Java爬取酷狗音乐歌单
  8. ConfuserEx加密工具
  9. JavaSE_面向对象_学习笔记
  10. AOSP、AOKP、CM ROM 究竟有哪些区别
  11. Balsamiq Mockups 便携版
  12. 时钟(CLOCK)置换算法
  13. 解决yay官方源下载慢问题
  14. unity hdrp的TAA
  15. javaweb-jsp编程例题
  16. PYTHON/JAVA实现固定时间且自动发送邮件的程序
  17. 学计算机的新手用什么笔记本好一点,笔记本什么配置比较好 有什么推荐呢
  18. 女生无法拒绝的表白拼图
  19. 大小写转化php,怎样用PHP做出人名币大小写的方法转换
  20. ubuntu20.04主屏幕与扩展屏同步

热门文章

  1. PC、H5网页授权跳转至支付宝APP
  2. Win10下python2和python3同时安装并解决pip共存问题
  3. 【初五】春晚红包挂了?
  4. 经典算法1-“河内之塔”
  5. 音频服务器未响应怎么修复,win10音频服务未响应怎么办 win10音频服务开启及关闭设置教程...
  6. 多Agent 深度强化学习综述
  7. robot_localization多传感器定位-IMU数据的校准与融合
  8. Oracle 19c OCP 1Z0-082认证考试题库(30-35)
  9. python编程ocr_cnocr是用来做中文OCR的Python 3包
  10. 人工智能,天使还是魔鬼