最近用SFML(C++)写了一个贪吃蛇的小游戏,在这里分享一下,希望能够对各位有所帮助。
1、环境配置
操作系统:Win 10
C++平台:Visual Studio 2015
SFML的配置参考:https://www.sfml-dev.org/tutorials/2.5/start-vc.php
-
在创建工程时,需要选择x64(对应于SFML版本)
-
注意:附加依赖项如下
sfml-graphics-d.lib
sfml-window-d.lib
sfml-system-d.lib
2、SFML库学习
在正式编写游戏前,SFML库的学习是必不可少的。这里列出需要学习的模块:
-
系统模块:处理时间、线程数
-
窗口模块:打开和管理SFML窗口、活动说明、键盘、鼠标和操纵杆
-
图像模块:绘制2D素材、精灵和纹理、文字和字体、形状、使用顶点数组设计自己的实体、位置、旋转、比例:变换实体、通过视图控制2D摄像机
其中小地图是通过视图控制2D摄像机实现的,使用视图过程中可能会改变精灵的形状,可以通过比例缩放来还原。这里列出的所有模块都可以在SFML给出的官方文档中学习和参考。
SFML官方文档:https://www.sfml-dev.org/tutorials/2.5/
3、源代码
源代码分为main.cpp和parameter.h,带有注释。
- main.cpp
#include "parameter.h"
//隐藏控制台
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//全局对象
sf::RenderWindow window; //主窗口
sf::Font font; //字体
sf::Clock clock_sys; //时钟,开始计时
sf::View mainView;
sf::View ParameterView;
sf::View miniMap;
sf::Texture texture;
sf::Sprite sprite;
sf::Text gameMsg;
sf::RectangleShape border;
ParameterText parametertext;
Snake snake;
Food food;
int Snake::growFactor = GROWFACTOR;
float Snake::sensitivity = 1.5;
float Snake::crawling_distance = 1.5*SNAKESIZE/GROWFACTOR;
int Difficulty = 3;
int Highest_score = 0;
bool pauseFlag = false;
const double PI = atan(1.)*4.; //圆周率
int main()
{
game_init();
sf::Clock clock_game;
gameMsg.setString("Playing...");
while (window.isOpen())
{
sf::Vector2f centertmp(0, 0);
//updata
snake.updataQueue(clock_game.restart());
parametertext.upData();
//更新主视角中心
centertmp = snake.getSnakeHeadPosition();
centertmp.x = limit_float(centertmp.x, WIDTH*(PWIDTH + MAINSCALE / 2), WIDTH*(1 - MAINSCALE / 2));
centertmp.y = limit_float(centertmp.y, HIGTH*MAINSCALE / 2, HIGTH*(1 - MAINSCALE / 2));
mainView.setCenter(centertmp);
border.setPosition(centertmp - sf::Vector2f(WIDTH*MAINSCALE / 2 + 10, HIGTH*MAINSCALE / 2 + 10));
//检测
if (snake.isCapture(food.rec))
{
//小蛇吃到食物
cout << "捕获" << endl;
snake.grow();
food.createFood();
}
if (snake.isCrashBorder())
{
//小蛇触碰到边界,游戏结束
snake.dead = true;
gameMsg.setString("GameOver\nPressEnter");
cout << "碰撞边界" << endl;
}
//事件
sf::Event event;
while (window.pollEvent(event))
{
float xtmp = 0;
float ytmp = 0;
sf::Uint32 unicode = 0;
switch (event.type)
{
case sf::Event::Closed: //关闭
w