嫦娥奔月:C++调用EasyX库实现

简介: 不羡嫦娥成神仙,月宫寒冷恨无边;不羡吴刚桂花酒,人间美酒比蜜甜。中秋之夜庆团圆,家家户户笑声欢。愿以此心寄明月,国泰民安长万年。

引言

不羡嫦娥成神仙,月宫寒冷恨无边;不羡吴刚桂花酒,人间美酒比蜜甜。中秋之夜庆团圆,家家户户笑声欢。愿以此心寄明月,国泰民安长万年。

前期准备

这个C++项目需要调用Easyx图形库,可从官网下载使用:https://easyx.cn/

我们只需要将下载好的文件中的.exe文件复制粘贴到我们建立项目的地址处就可以使用了。

开始项目

在建立项目后,我们需要建立一个文件夹用来存放图片,这里需要存放 "嫦娥"、"月亮”图片:

完成这些之后,就可以安心敲代码了。

我们首先需要对程序设计进行大致分析,也就是说我需要干什么、怎么干。

在这里我需要设计一款游戏,玩家通过键盘进行移动,月亮在玩家移动后也会随机移动,玩家需要帮助嫦娥追到月亮。

初始化绘图窗口后加载图片,为了代码的可阅读性,这里使用棋盘的思想,设计一个棋盘,我们将月亮放在棋盘中间,将嫦娥放在棋盘左下角,宏定义棋盘格子的大小后,我们使嫦娥和月亮的坐标最小长度都为1,将相应的坐标乘上格子大小就是真实坐标了。

现在具体分析一下:

下面将需要全局声明、全局变量、宏定义、头文件贴出来:

#include <graphics.h>
#include <conio.h>
#include<iostream>
using namespace std;
#define WINDOW_LENGTH 1024    //棋盘长
#define WINDOW_WIDTH 768      //棋盘宽
#define BEGIN_X 85            //棋盘最左上角点的x坐标
#define BEGIN_Y 85            //棋盘最左上角点的y坐标
#define GRID_N 15             //格子数
#define GRID_LENGTH 30        //每个格子的边长(像素数)
//定义图型变量
IMAGE pic_moon;
IMAGE pic_ren;
//定义二维棋盘数组 
int chessboard[15][15] = { 0 };
//****************核心数据*****************//
//定义判断玩家或电脑
int last = 1;
//人物初始位置
int renX = 0;
int renY = 14;
int moonX = 7;
int moonY = 7;
int step = 0;
//判断赢 
int num = 0;
void start();
void loadsource();
void playgame();
void wingame();
void drawpicture();

程序主要使用自定义函数,主函数非常简短:

void main()
{
  start();
}

下面是start()函数代码:

void start()
{
  //设置初始面板
  //mciSendString("play  music\\qingtian.mp3",0,0,0);
  initgraph(WINDOW_LENGTH, WINDOW_WIDTH);
  loadsource();
  playgame();
}

根据执行顺序,我们进入加载图片的函数:

void loadsource()
{
  //加载
  loadimage(&pic_moon, L"tupian\\moon.png", GRID_LENGTH, GRID_LENGTH);
  loadimage(&pic_ren, L"tupian\\ren.png", GRID_LENGTH, GRID_LENGTH);
}

接下来就是玩游戏的函数了,这里相比之前的函数代码相对较长,但是也很好理解,我们将嫦娥和月亮限制在棋盘中,根据玩家的输入嫦娥移动,使用last来使玩家和电脑依次移动,最后判断是否胜利。

void playgame()
{
  //移动人物
  unsigned char ch;
  while (1)
  {
    drawpicture();
    if (last == 1 && renX >= 0 && renX <= 14 && renY >= 0 && renY <= 14)
    {
      ch = _getch();
      step++;
      switch (ch)
      {
      case 'a':
      case 'A':
      {
        renX--;
        last = 2;
        break;
      }
      case 'w':
      case 'W':
      {
        renY--;
        last = 2;
        break;
      }
      case 's':
      case 'S':
      {
        renY++;
        last = 2;
        break;
      }
      case 'd':
      case 'D':
      {
        renX++;
        last = 2;
        break;
      }
      }
    }
    if (renX > 14)
      renX--;
    if (renX < 0)
      renX++;
    if (renY > 14)
      renY--;
    if (renY < 0)
      renY++;
    //移动月亮
    if (last == 2)
    {
      last = 1;
      int moon_temp_X = rand() % 3;
      int moon_temp_Y = rand() % 3;
      switch (moon_temp_X)
      {
      case 0:
        break;
      case 1:
        moonX++;
        break;
      case 2:
        moonX--;
        break;
      }
      switch (moon_temp_Y)
      {
      case 0:
        break;
      case 1:
        moonY++;
        break;
      case 2:
        moonY--;
        break;
      }
    }
    if (moonX > 14)
      moonX--;
    if (moonX < 0)
      moonX++;
    if (moonY > 14)
      moonY--;
    if (moonY < 0)
      moonY++;
    wingame();
  }
}

wengame()函数非常简短,也很简单:

void wingame()
{
  if (renX == moonX && renY == moonY)
    num = 1;
}

我们可以在playgame()函数中看到使用了显示图片函数,这个函数根据坐标显示嫦娥和月亮图片,并每一次都重新绘制图像,不然程序中会出现多个嫦娥和月亮,这是因为图片被显示后在程序中会一直存在,使用我们需要使用函数重新绘制图像。可以看到这里有画线的操作,其实在最后这是可以被注释掉的(不注释也不会有什么大问题,而且这可以帮助我们调整嫦娥和月亮位置),最后我们根据是否胜利进行输出。这里同样贴出代码:

void drawpicture()
{
  for (int i = 0; i < GRID_N; i++)
  {
    setlinecolor(WHITE);
    line(100, 100 + i * GRID_LENGTH, 100 + GRID_LENGTH * 14, 100 + i * GRID_LENGTH);
    line(100 + i * GRID_LENGTH, 100, 100 + i * GRID_LENGTH, 100 + GRID_LENGTH * 14);
  }
  cleardevice();
  putimage(BEGIN_X + renX * GRID_LENGTH, BEGIN_Y + renY * GRID_LENGTH, &pic_ren);
  putimage(BEGIN_X + moonX * GRID_LENGTH, BEGIN_Y + moonY * GRID_LENGTH, &pic_moon);
  if (num == 1)
  {
    settextcolor(BLACK);
    setbkmode(TRANSPARENT);
    settextstyle(50, 30, L"宋体");
    outtextxy(650, 340, L"胜利,终端查看移动步数!");
    cout << "玩家胜利,共移动" << step << "步" << endl;
    Sleep(1000);
    closegraph();
  }
}

结语

游戏到这里就基本设计结束了,当然也可以继续修改增加一些技能什么的,这个笔者后续可能会继续设计。下面贴出部分游戏画面:

目录
相关文章
|
7天前
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
23 11
|
8天前
|
存储 计算机视觉 C++
在C++中实现Armadillo库与OpenCV库之间的数据格式转换
在C++中实现Armadillo库与OpenCV库之间的数据格式转换是一项常见且实用的技能。上述步骤提供了一种标准的方法来进行这种转换,可以帮助开发者在两个库之间高效地转移和处理数据。虽然转换过程相对直接,但开发者应留意数据类型匹配和性能优化等关键细节。
14 3
|
19天前
|
C++
fedora安装静态c和c++库
fedora安装静态c和c++库
|
1月前
|
算法 数据可视化 机器人
Pinocchio - 开源多刚体动力学 C++、Python库
Pinocchio - 开源多刚体动力学 C++、Python库
51 2
|
20天前
|
C++
C/C++静态链接pthread库的坑【-static -pthread】
C/C++静态链接pthread库的坑【-static -pthread】
|
26天前
|
C++
C++标准库探索
C++标准库探索
32 0
|
2月前
|
C++
C++一分钟之-文件系统库(fs)的使用
【7月更文挑战第18天】C++17的`&lt;filesystem&gt;`库简化了文件系统操作,包括`path`类和`directory_iterator`。`path`用于表示路径,`directory_iterator`用于遍历目录。常用功能有路径拼接、分解,创建/删除目录,以及遍历。错误处理、跨平台兼容性和性能是使用时需考虑的关键点。示例代码展示了如何初始化`path`、创建目录、删除目录以及处理异常。
66 1
|
1月前
|
编译器 C++ 开发者
Visual Studio属性表:在新项目中加入已配置好的C++库
通过以上步骤可以确保Visual Studio中新项目成功地加入了之前已配置好的C++库。这个过程帮助开发者有效地管理多个项目中共享的库文件,提升开发效率。
45 0
|
2月前
|
存储 C++ 容器
C++一分钟之-正则表达式库(regex)
【7月更文挑战第7天】C++从C++11开始支持正则表达式,通过`&lt;regex&gt;`库提供功能。本文涵盖基本概念如`std::regex`、`std::smatch`,以及`regex_search`和`regex_match`的使用。常见问题包括大小写敏感性、特殊字符转义、贪婪与非贪婪匹配和捕获组。提供的代码示例展示了如何进行匹配、不区分大小写的匹配、特殊字符匹配、贪婪与非贪婪匹配和捕获组的使用。理解并练习正则表达式能提升文本处理效率。
35 0
|
2月前
|
存储 算法 程序员
C++基础知识(八:STL标准库(Vectors和list))
C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等. STL容器的提供是为了让开发者可以更高效率的去开发,同时我们应该也需要知道他们的底层实现,这样在出现错误的时候我们才知道一些原因,才可以更好的去解决问题。