0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C/C++轻松实现4399小游戏:围住神经猫!

C语言编程学习基地 来源:C语言编程学习基地 2023-03-08 17:10 次阅读

每天一个C语言小项目,提升你的编程能力!

一、游戏说明

本游戏仿造 4399 的小游戏-围住神经猫。

游戏操作:通过鼠标点击操作,设置路障,围住神经猫,当成功围住神经猫时,游戏胜利。当神经猫逃离地图边缘,游戏失败。

二、游戏截图

三、实现思路

1. 地图还原:

首先是游戏的道路,这里我们采用绘制灰白色的圆来表示可走的路,用黄色的圆来表示已存在的障碍物。同时还需要注意奇偶行需要交错排列。

2.猫的移动:

这里我们采用广度优先搜索求最短路径。"猫"在一个位置,能够移动的方向有6个,需要注意的是:

由于奇偶行交替排列,导致奇偶行猫的可行路径是不一样的,奇数行:上,下,左,右,左下,左上。

偶数行:上,下,左,右,右下,右上。剩下的就是常规的求最短路径即可。

注:代码中所用图片,请见文末

d0e3416e-a8bd-11ed-bfe3-dac502259ad0.png

四、完整代码

简单了解游戏后我们就来试试吧!(直接上源码,大家可以看注释)

/////////////////////////////////////////////////////////
// 程序名称:围住神经猫
//编译环境VisualStudio2019(C++语言标准选择C++17),EasyX


#include 
#include 
#include 
#include 
#include 


#pragma comment( lib, "MSIMG32.LIB")
#define pix     50      // 像素比例
#define hight  (14 * pix)
#define width  (10 * pix)
using namespace std;


int stepS;          // 记录已经走的步数
int startBarrier;      // 开始的障碍物数目
wchar_t Score_[30];
MOUSEMSG m;          // 鼠标操作
IMAGE pig, bkimg;;      // 加载图片




enum class picture
{
  none, barrier
};


struct XY
{
  int x, y;
  int lastX, lastY;  //记录上一个点的坐标
}cat;


struct node
{
  int x, y;      //坐标,圆心位置
  picture pic;    //当前位置的图片内容
};


node canvas[10][10];  //  地图
bool visit[10][10];    //  记录是否访问过地图中的元素
int path[10][10][2];  //  记录上一个位置




//注意:因为地图是交错排列的,奇数列与偶数列猫的移动不同
int dirOdd[6][2]{ 1,0,-1,0,0,1,0,-1,-1,-1,-1,1 };  //控制方向奇数列
int dirEven[6][2]{ 1,0,-1,0,0,1,0,-1,1,-1,1,1 };  //控制方向偶数列


int main();


//贴图函数
void transparentimage(IMAGE* dstimg, int x, int y, IMAGE* srcimg,int direction)
{
  HDC dstDC = GetImageHDC(dstimg);
  HDC srcDC = GetImageHDC(srcimg);
  int w = 50;
  int h = 100;


  // 使用 Windows GDI 函数实现透明位图
  if (direction == 0)
    TransparentBlt(dstDC, x, y, w, h, srcDC, 0, 0, w, h, 0);
  else
    TransparentBlt(dstDC, x, y, w, h, srcDC, 10, 187, w, h, 0);
}


//游戏初始化
void initial()
{
  srand(time(0));
  stepS = 0;
  startBarrier = rand() % 6 + 8;  //障碍物数量
  loadimage(&pig, L"pig.png");
  loadimage(&bkimg, L"bkground.jpg", width, hight, true);
  initgraph(width, hight);
  HWND wnd = GetHWnd();
  SetWindowText(wnd, L"围住神经猫");//设置文章标题
  for (int i = 1; i <= 9; ++i)
    for (int j = 1; j <= 9; ++j)
    {
      if (i & 1)  //如果是奇数行
        canvas[i][j] = node{ j * pix - pix / 4, pix * 4 + i * pix ,picture::none };
      else
        canvas[i][j] = node{ j * pix + pix / 4, pix * 4 + i * pix ,picture::none };
    }


  cat.x = 5; cat.y = 5;  //猫最开始的地方
  while (startBarrier--)
  {
    int bx, by;      //设置初始障碍
    do
    {
      bx = rand() % 10;
      by = rand() % 10;
    } while (canvas[by][bx].pic == picture::barrier || (by == cat.y && bx == cat.x));
    canvas[by][bx].pic = picture::barrier;
  }
  setbkmode(TRANSPARENT);
  BeginBatchDraw();
}




//绘制游戏画面, 白色:空  黄色:障碍物 
void show()
{
  putimage(0, 0, &bkimg);
  setbkcolor(WHITE);
  settextstyle(20, 0, L"微软雅黑");
  outtextxy(200, 170, L"重玩");
  outtextxy(250, 180, L"步数: ");
  swprintf(Score_, 29, L"%d", stepS);
  outtextxy(290, 180, Score_);
  for (int i = 1; i <= 9; ++i)
  {
    for (int j = 1; j <= 9; ++j)
    {
      if (canvas[i][j].pic == picture::barrier)
        setfillcolor(YELLOW);
      else
        setfillcolor(LIGHTGRAY);
      solidcircle(canvas[i][j].x, canvas[i][j].y, (pix - 4) / 2);
    }
  }
  if (cat.y & 1)  //奇数列
    transparentimage(NULL, cat.x * pix - pix / 4 - 25, pix * 3 + cat.y * pix - 21, &pig,0);
  else      //偶数列
    transparentimage(NULL, cat.x * pix - 25 + pix / 4, pix * 3 + cat.y * pix - 21, &pig,1);
  FlushBatchDraw();
}




//寻找下一个点的位置
struct LastOrder
{
  int x, y;
};


vector vec;


void findNextXY(int x, int y)
{
  if (x == cat.x && y == cat.y)
  {
    vec.push_back({ x,y });
    return;
  }
  else
  {
    findNextXY(path[y][x][0], path[y][x][1]);
    vec.push_back({ x,y });
  }
}




//利用广度优先搜索求最短路径,xy为数组的i,j下标,注意传参
void bfs(XY xy)
{
  //每次搜索时初始化数组
  memset(visit, false, sizeof(visit));
  memset(path, 0, sizeof(path));
  bool tag = true;
  queue que;
  que.push(xy);
  visit[xy.y][xy.x] = true;
  while (!que.empty())
  {
    XY temp = que.front();
    que.pop();
    //如果找到出口
    if (temp.x == 1 || temp.x == 9 || temp.y == 1 || temp.y == 9)
    {
      findNextXY(temp.x, temp.y);
      cat.x = vec[1].x;
      cat.y = vec[1].y;
      vec.clear();
      tag = false;
      break;
    }
    int dx, dy;
    //寻找可走的路
    for (int i = 0; i < 6; ++i)
    {
      if (temp.y & 1)
      {
        dx = temp.x + dirOdd[i][0];
        dy = temp.y + dirOdd[i][1];
      }
      else
      {
        dx = temp.x + dirEven[i][0];
        dy = temp.y + dirEven[i][1];
      }
      if (dx >= 1 && dx <= 9 && dy >= 1 && dy <= 9 && !visit[dy][dx] && canvas[dy][dx].pic == picture::none)
      {
        visit[dy][dx] = true;
        path[dy][dx][0] = temp.x;
        path[dy][dx][1] = temp.y;
        que.push({ dx,dy,temp.x,temp.y });
      }
    }
  }
  if (tag)          //如果没找到出口
  {
    show();
    HWND wnd = GetHWnd();
    swprintf(Score_, 29, L"你共用了%d步,重玩一局吗", stepS);
    FlushBatchDraw();
    if (MessageBox(wnd, Score_, L"成功", MB_YESNO | MB_ICONQUESTION) == IDYES)
      main();
    else
      exit(-1);
  }
}




//鼠标操作
void dataChangeWithMouseHit()
{
  while (true)
  {
    m = GetMouseMsg();
    if (m.x >= 200 && m.x <= 230 && m.y >= 170 && m.y <= 200)
      settextcolor(BLACK);
    else
      settextcolor(WHITE);
    outtextxy(200, 170, L"重玩");
    FlushBatchDraw();
    if (m.uMsg == WM_LBUTTONDOWN)
    {
      if (m.x >= 200 && m.x <= 230 && m.y >= 170 && m.y <= 200)
        main();
      for (int i = 1; i <= 9; ++i)
        for (int j = 1; j <= 9; ++j)
          //如果在当前方格内,则改变信息
          if (canvas[i][j].pic != picture::barrier && (m.x - canvas[i][j].x) * (m.x - canvas[i][j].x) +
            (m.y - canvas[i][j].y) * (m.y - canvas[i][j].y) <= (pix - 4) * (pix - 4) / 4)
          {
            canvas[i][j].pic = picture::barrier;
            stepS++;
            bfs({ cat.x,cat.y,0,0 });
            return;
          }
    }
  }
}




//不需要鼠标的操作,判断猫是否跑掉
void dataChangeWithoutMouseHit()
{
  if (cat.x == 1 || cat.y == 1 || cat.x == 9 || cat.y == 9)
  {
    show();
    HWND wnd = GetHWnd();
    if (MessageBox(wnd, L"游戏结束。
神经猫跑掉了!,重玩一局吗", L"询问", MB_YESNO | MB_ICONQUESTION) == IDYES)
      main();
    else
      exit(-1);
  }
}




int main()
{
  initial();
  while (true)
  {
    show();
    dataChangeWithMouseHit();
    dataChangeWithoutMouseHit();
    Sleep(20);
  }
  return 0;
}

大家赶紧去动手试试吧!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 游戏
    +关注

    关注

    2

    文章

    696

    浏览量

    26040
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128720
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66771

原文标题:【项目实战】C/C++轻松实现4399小游戏:围住神经猫!

文章出处:【微信号:cyuyanxuexi,微信公众号:C语言编程学习基地】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C++游戏逆向辅助 CSGO_透视的实现

    C++
    电路设计
    发布于 :2023年01月10日 13:37:05

    labview小游戏飞天忍者

    “飞天忍者”说明:(平台:Labview2011)一、操作说明 1.打开文件夹“Cat”里面的Main.vi,程序设置为“打开自动运行”; 2.运行将进入加载界面,加载完成后进入游戏界面; 3.点击
    发表于 12-13 16:20

    论坛基于labview的小游戏合集(绝对精彩)

    )https://bbs.elecfans.com/jishu_207606_1_1.html labview小游戏飞天忍者https://bbs.elecfans.com
    发表于 03-01 15:29

    C++实现的经典小游戏源代码

    C++实现的经典小游戏源代码
    发表于 08-20 15:31

    基于LabVIEW小游戏11款合集

    /jishu_206863_1_1.html3、labview小游戏飞天忍者 https://bbs.elecfans.com/jishu_211335_1_1.html4、labviEW之打地鼠游戏 https
    发表于 12-10 15:16

    【上海】诚聘C++游戏后端开发工程师

    猎头推荐职位:c++游戏后端开发工程师(15-30K)工作职责:1. 服务器端代码测试与维护;2. 服务器端核心模块与逻辑代码实现。岗位要求:1. 1年以上Linux平台C/
    发表于 07-10 11:56

    基于js实现2048小游戏

    用js实现2048小游戏
    发表于 07-02 15:58

    猜数字大小游戏研修实现

    `通过学习和努力,蛟龙腾飞团队成功在自己开发版上实现猜数字大小游戏。本游戏参考与引用了HonestQiao公开的代码。`
    发表于 12-16 18:07

    C语言小游戏源码分享

    C语言小游戏源码24点火柴人俄罗斯等等等35个游戏源码网盘分享链接:https://pan.baidu.com/s/1Ez189jnaBELfsR10jy0dIQ提取码:xa7o
    发表于 04-12 17:11

    如何学习C++,如何学好C++

    最近,很多学员都给我发邮件问我应该如何学习C++,如何学好C++?那么作为一个从C语言小白摸爬滚打、入坑无数到成长为如今的高级C++游戏开发
    发表于 08-20 06:27

    怎样去设计一种基于stm32f103c8t6的贪吃蛇小游戏

    基于stm32f103c8t6的贪吃蛇小游戏是由哪些部分组成的?怎样去设计一种基于stm32f103c8t6的贪吃蛇小游戏呢?
    发表于 02-21 06:27

    基于HarmonyOS纯ets语言实现的抓住神经游戏设计资料

      1.前言  《抓住神经》》游戏相信不少朋友都玩过,最近不是ARKUI挺火热的么,一直搞嵌入式的也想尝尝鲜,想找个小玩意入门,想起来5,6年前看过的一篇文章,分析神经
    发表于 04-06 10:40

    H5小游戏市场前景可期 市场容量一触即发

    虽然H5小游戏的概念已诞生许久,不过真正进入大众视线是在2014年推出的一款名为《围住神经猫》的H5游戏。据悉,该款游戏的开发周期只有一天半
    的头像 发表于 03-06 08:30 5975次阅读
    H5<b class='flag-5'>小游戏</b>市场前景可期 市场容量一触即发

    使用C++编写的2048小游戏的论文和源代码免费下载

    本文档的主要内容详细介绍的是使用C++编写的2048小游戏的论文和源代码免费下载。
    发表于 07-01 10:26 18次下载
    使用<b class='flag-5'>C++</b>编写的2048<b class='flag-5'>小游戏</b>的论文和源代码免费下载

    qt用C++写的2048小游戏源代码

    qt用C++写的2048小游戏源代码
    发表于 09-27 11:48 0次下载