RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C/C++輕松實(shí)現(xiàn)4399小游戲:圍住神經(jīng)貓!

C語言編程學(xué)習(xí)基地 ? 來源:C語言編程學(xué)習(xí)基地 ? 2023-03-08 17:10 ? 次閱讀

每天一個C語言小項(xiàng)目,提升你的編程能力!

一、游戲說明

本游戲仿造 4399 的小游戲-圍住神經(jīng)貓。

游戲操作:通過鼠標(biāo)點(diǎn)擊操作,設(shè)置路障,圍住神經(jīng)貓,當(dāng)成功圍住神經(jīng)貓時,游戲勝利。當(dāng)神經(jīng)貓?zhí)与x地圖邊緣,游戲失敗。

二、游戲截圖

三、實(shí)現(xiàn)思路

1. 地圖還原:

首先是游戲的道路,這里我們采用繪制灰白色的圓來表示可走的路,用黃色的圓來表示已存在的障礙物。同時還需要注意奇偶行需要交錯排列。

2.貓的移動:

這里我們采用廣度優(yōu)先搜索求最短路徑。"貓"在一個位置,能夠移動的方向有6個,需要注意的是:

由于奇偶行交替排列,導(dǎo)致奇偶行貓的可行路徑是不一樣的,奇數(shù)行:上,下,左,右,左下,左上。

偶數(shù)行:上,下,左,右,右下,右上。剩下的就是常規(guī)的求最短路徑即可。

注:代碼中所用圖片,請見文末

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

四、完整代碼

簡單了解游戲后我們就來試試吧!(直接上源碼,大家可以看注釋)

/////////////////////////////////////////////////////////
// 程序名稱:圍住神經(jīng)貓
//編譯環(huán)境VisualStudio2019(C++語言標(biāo)準(zhǔn)選擇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;          // 記錄已經(jīng)走的步數(shù)
int startBarrier;      // 開始的障礙物數(shù)目
wchar_t Score_[30];
MOUSEMSG m;          // 鼠標(biāo)操作
IMAGE pig, bkimg;;      // 加載圖片




enum class picture
{
  none, barrier
};


struct XY
{
  int x, y;
  int lastX, lastY;  //記錄上一個點(diǎn)的坐標(biāo)
}cat;


struct node
{
  int x, y;      //坐標(biāo),圓心位置
  picture pic;    //當(dāng)前位置的圖片內(nèi)容
};


node canvas[10][10];  //  地圖
bool visit[10][10];    //  記錄是否訪問過地圖中的元素
int path[10][10][2];  //  記錄上一個位置




//注意:因?yàn)榈貓D是交錯排列的,奇數(shù)列與偶數(shù)列貓的移動不同
int dirOdd[6][2]{ 1,0,-1,0,0,1,0,-1,-1,-1,-1,1 };  //控制方向奇數(shù)列
int dirEven[6][2]{ 1,0,-1,0,0,1,0,-1,1,-1,1,1 };  //控制方向偶數(shù)列


int main();


//貼圖函數(shù)
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 函數(shù)實(shí)現(xiàn)透明位圖
  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;  //障礙物數(shù)量
  loadimage(&pig, L"pig.png");
  loadimage(&bkimg, L"bkground.jpg", width, hight, true);
  initgraph(width, hight);
  HWND wnd = GetHWnd();
  SetWindowText(wnd, L"圍住神經(jīng)貓");//設(shè)置文章標(biāo)題
  for (int i = 1; i <= 9; ++i)
    for (int j = 1; j <= 9; ++j)
    {
      if (i & 1)  //如果是奇數(shù)行
        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;      //設(shè)置初始障礙
    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"步數(shù): ");
  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)  //奇數(shù)列
    transparentimage(NULL, cat.x * pix - pix / 4 - 25, pix * 3 + cat.y * pix - 21, &pig,0);
  else      //偶數(shù)列
    transparentimage(NULL, cat.x * pix - 25 + pix / 4, pix * 3 + cat.y * pix - 21, &pig,1);
  FlushBatchDraw();
}




//尋找下一個點(diǎn)的位置
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 });
  }
}




//利用廣度優(yōu)先搜索求最短路徑,xy為數(shù)組的i,j下標(biāo),注意傳參
void bfs(XY xy)
{
  //每次搜索時初始化數(shù)組
  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);
  }
}




//鼠標(biāo)操作
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)
          //如果在當(dāng)前方格內(nèi),則改變信息
          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;
          }
    }
  }
}




//不需要鼠標(biāo)的操作,判斷貓是否跑掉
void dataChangeWithoutMouseHit()
{
  if (cat.x == 1 || cat.y == 1 || cat.x == 9 || cat.y == 9)
  {
    show();
    HWND wnd = GetHWnd();
    if (MessageBox(wnd, L"游戲結(jié)束。
神經(jīng)貓跑掉了!,重玩一局嗎", L"詢問", MB_YESNO | MB_ICONQUESTION) == IDYES)
      main();
    else
      exit(-1);
  }
}




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

大家趕緊去動手試試吧!

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 游戲
    +關(guān)注

    關(guān)注

    2

    文章

    742

    瀏覽量

    26312
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136683
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2108

    瀏覽量

    73618
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4779

    瀏覽量

    68521

原文標(biāo)題:【項(xiàng)目實(shí)戰(zhàn)】C/C++輕松實(shí)現(xiàn)4399小游戲:圍住神經(jīng)貓!

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    C++游戲逆向輔助 CSGO_透視的實(shí)現(xiàn)

    C++
    電路設(shè)計(jì)
    發(fā)布于 :2023年01月10日 13:37:05

    論壇基于labview的小游戲合集(絕對精彩)

    )https://bbs.elecfans.com/jishu_207606_1_1.html labview小游戲飛天忍者https://bbs.elecfans.com
    發(fā)表于 03-01 15:29

    C++實(shí)現(xiàn)的經(jīng)典小游戲源代碼

    C++實(shí)現(xiàn)的經(jīng)典小游戲源代碼
    發(fā)表于 08-20 15:31

    基于LabVIEW小游戲11款合集

    /jishu_206863_1_1.html3、labview小游戲飛天忍者 https://bbs.elecfans.com/jishu_211335_1_1.html4、labviEW之打地鼠游戲 https
    發(fā)表于 12-10 15:16

    基于js實(shí)現(xiàn)2048小游戲

    用js實(shí)現(xiàn)2048小游戲
    發(fā)表于 07-02 15:58

    C語言小游戲源碼分享

    C語言小游戲源碼24點(diǎn)火柴人俄羅斯等等等35個游戲源碼網(wǎng)盤分享鏈接:https://pan.baidu.com/s/1Ez189jnaBELfsR10jy0dIQ提取碼:xa7o
    發(fā)表于 04-12 17:11

    基于HarmonyOS純ets語言實(shí)現(xiàn)的抓住神經(jīng)游戲設(shè)計(jì)資料

      1.前言  《抓住神經(jīng)》》游戲相信不少朋友都玩過,最近不是ARKUI挺火熱的么,一直搞嵌入式的也想嘗嘗鮮,想找個小玩意入門,想起來5,6年前看過的一篇文章,分析神經(jīng)
    發(fā)表于 04-06 10:40

    利用C語言來編寫打地鼠小游戲

    C語言模擬打地鼠小游戲
    的頭像 發(fā)表于 01-26 14:55 ?1.5w次閱讀

    《Visual C++游戲編程基礎(chǔ)》電子書.pdf

    《Visual C++游戲編程基礎(chǔ)》電子書.pdf
    發(fā)表于 04-23 11:27 ?0次下載
    《Visual <b class='flag-5'>C++</b><b class='flag-5'>游戲</b>編程基礎(chǔ)》電子書.pdf

    使用C++編寫的2048小游戲的論文和源代碼免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用C++編寫的2048小游戲的論文和源代碼免費(fèi)下載。
    發(fā)表于 07-01 10:26 ?18次下載
    使用<b class='flag-5'>C++</b>編寫的2048<b class='flag-5'>小游戲</b>的論文和源代碼免費(fèi)下載

    基于Labview的小游戲飛天忍者源碼

    基于Labview的小游戲飛天忍者源碼
    發(fā)表于 11-15 18:22 ?64次下載

    虛擬機(jī)的設(shè)計(jì)與實(shí)現(xiàn):C\C++

    虛擬機(jī)的設(shè)計(jì)與實(shí)現(xiàn):C\C++
    發(fā)表于 02-21 15:10 ?0次下載

    qt用C++寫的2048小游戲源代碼

    qt用C++寫的2048小游戲源代碼
    發(fā)表于 09-27 11:48 ?1次下載

    C++多文件寫法輕松實(shí)現(xiàn)練手小游戲:貪吃蛇!

    每天一個編程小項(xiàng)目,提升你的編程能力! 這個是用C++語法和鏈表知識實(shí)現(xiàn)的哦!
    的頭像 發(fā)表于 02-13 14:53 ?2286次閱讀

    C語言小游戲源碼大放送

    電子發(fā)燒友網(wǎng)站提供《C語言小游戲源碼大放送.rar》資料免費(fèi)下載
    發(fā)表于 11-21 10:36 ?1次下載
    <b class='flag-5'>C</b>語言<b class='flag-5'>小游戲</b>源碼大放送
    RM新时代网站-首页