(語言:C++ 版本:vs 2019 community )
提示:文章最末有代碼的GitHub鏈接,可以直接下載,別忘記給星哦!
溫馨提示:本代碼對于錦城的學生尤其適用!(轉載本文請指明出處)
文章目錄
- 前言
- 一、代碼框架
- 二、核心功能
- 三、運行截圖
- 四、代碼
前言
貪吃蛇是我們的一個基本專案,但是我發現網上的貪吃蛇有很多拓展的寫法,對于一些只需要的基本需求的貪吃蛇,有時候還不能拿來直接用,于是乎,在學校寫這個貪吃蛇的時候,我就順便記錄一下,(本代碼沒有圖形化,沒有使用EasyX圖形庫)
本文中的貪吃蛇一些功能如下:
1.蛇的自由移動(w,s,a,d)
2.蛇移動時有效輸入的判斷:例如蛇往右移動時,輸入a蛇不能改向
3.蛇的吃食物變長,分數增加,等級提升
3.食物的隨機出現
4.背景音樂:用了playSound函式,不需要直接注釋掉
5.選單:不需要的話直接不添加檔案并需要稍微修改原有代碼
一、代碼框架
貪吃蛇專案總體上用了6個類封裝,分別是CUnit類, CFood類,CMap類, CSnake類, CGame類, CMenu類,
CUnit類主要功能:實作一個點的顯示與擦除,
CFood類主要功能:創建隨機食物位置,
CMap類主要功能:初始化視窗大小,繪制地圖,顯示初始資訊,
CSnake類主要功能:顯示、擦除,自由移動,吃食物蛇身變長等,
CGame類主要功能:運行、結束游戲,隱藏游標,運行時檢測游戲等級、游戲分數、食物是否被吃并改變相應顯示資訊,
CMenu類主要功能:游戲加載頁面,選單顯示,
二、核心功能
CSnake類:新增quitGame()函式,用于實作選擇退出游戲,在該蛇的自由移動程序中,另外實作了按空格鍵暫停,按q鍵選擇退出游戲,按+鍵增加游戲速度,
CMap類:新增了drawGameWindows函式,用于實作初始化游戲界面大小,
CGame類:增加了hideCursor函式,用于實作隱藏游標,增加了GameOver函式,用于蛇死亡后的一系列操作,
CMenu類:新增類,增加了showMenu()函式(選單顯示),startGame()函式(開始游戲),quitGame()函式(退出游戲),gameHelp()函式(游戲幫助),loadGame()函式(加載游戲界面),
三、運行截圖





四、代碼
Cunit類:
//.h
```cpp
#pragma once
#include<windows.h>
class Cunit
{
public:
Cunit(int x = 0, int y = 0, char pic = '*');
virtual ~Cunit();
void show();
void erase();
static void gotoxy(int x, int y);
public:
int m_ix;
int m_iy;
char m_cPic;
};
#include "CUnit.h"
#include<iostream>
using namespace std;
Cunit::Cunit(int x, int y, char pic)
{
m_ix = x;
m_iy = y;
m_cPic = pic;
}
Cunit::~Cunit()
{
}
void Cunit::gotoxy(int x, int y)
{
COORD pos = { x,y };
pos.X = x;
pos.Y = y;
//設定游標位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void Cunit::show()
{
gotoxy(m_ix, m_iy);
cout << m_cPic;
}
void Cunit::erase()
{
gotoxy(m_ix, m_iy);
cout << " ";
}
CFood類:
#pragma once
#include "CUnit.h"
class CFood :
public Cunit
{
public:
CFood(int x =0, int y=0, char pic = '#');
virtual ~CFood();
void createPos();
};
#include "CFood.h"
#include"CUnit.h"
#include"CMap.h"
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
CFood::CFood(int x, int y, char pic) : Cunit(x, y, pic)
{
}
CFood::~CFood()
{
}
void CFood::createPos()
{
/*m_ix = CMap::KLEFT + rand() % (CMap::KWIDTH - 2);
m_iy = CMap::KUP + rand() % (CMap::KHEIGHT - 4);*/
m_ix = CMap::KLEFT + rand() % (CMap::KWIDTH - CMap::KLEFT - 1);
m_iy = CMap::KUP + rand() % (CMap::KHEIGHT - CMap::KUP - 1);
}
CSnake類:
#pragma once
#include"CFood.h"
#include<iostream>
#include<vector>
#include<iostream>
#include<Windows.h>
using namespace std;
typedef enum {
w,s,a,d
}Directions;
class CSnake
{
public:
CSnake(int x = 40, int y = 15, int length = 4, Directions direction = d, int speed = 400, char pic = '*');
virtual~CSnake();
bool move();
void eraseSnake();
void eraseSnake(int flag);
bool changeDirections(char vkValue);
void changeDirections(Directions dir); //改變方向
bool quitGame();
bool eatFood(CFood* pfood);
bool checkFoodPos(CFood *pFood); //檢查食物位置
void movePos();
void growup();
void showSnake();
public:
int m_iLength;
int m_iHeadX;
int m_iHeadY;
int m_iSpeed; //蛇當前速度
char m_pic;
Directions m_enumCurrentDirection; //蛇當前方向
vector<Cunit> m_vecBody; //存盤蛇的位置
};
#include<iostream>
#include<vector>
#include<conio.h>
#include<Windows.h>
#include"CSnake.h"
#include"Cunit.h"
#include"CMap.h"
#include"CFood.h"
#include"CMenu.h"
using namespace std;
CSnake::CSnake(int x, int y, int length, Directions direct, int speed, char pic)
{
m_iLength = length;
m_iHeadX = x;
m_iHeadY = y;
m_iSpeed = speed;
m_pic = pic;
m_enumCurrentDirection = direct;
Cunit c(0, 0, '@');
m_vecBody.push_back(c);
m_vecBody[0].m_ix = m_iHeadX;
m_vecBody[0].m_iy = m_iHeadY;
for (int i = 1; i < m_iLength; i++)
{
Cunit c;
m_vecBody.push_back(c);
switch (m_enumCurrentDirection)
{
case w:
m_vecBody[i].m_ix = m_iHeadX;
m_vecBody[i].m_iy = m_iHeadY + i;
break;
case s:
m_vecBody[i].m_ix = m_iHeadX;
m_vecBody[i].m_iy = m_iHeadY - i;
break;
case a:
m_vecBody[i].m_ix = m_iHeadX + i;
m_vecBody[i].m_iy = m_iHeadY;
break;
case d:
m_vecBody[i].m_ix = m_iHeadX - i;
m_vecBody[i].m_iy = m_iHeadY;
break;
}
}
}
CSnake::~CSnake()
{
}
//顯示蛇
void CSnake::showSnake()
{
for (int i = 0; i < m_iLength; i++)
{
m_vecBody[i].show();
}
}
//擦除
void CSnake::eraseSnake()
{
/*for (int i = 0; i < m_iLength; i++)
{
m_vecBody[i].erase();
}*/
int i;
for (i = 0; i < m_iLength - 1; i++);
m_vecBody[i].erase();
}
void CSnake::eraseSnake(int flag)
{
for (int i = 0; i < m_iLength; i++)
m_vecBody[i].erase();
}
//改變方向
bool CSnake::changeDirections(char vkValue)
{
switch (vkValue)
{
case'w':
m_vecBody[0].m_iy--;
m_enumCurrentDirection = w;
return false;
case's':
m_vecBody[0].m_iy++;
m_enumCurrentDirection = s;
return false;
case'a':
if (m_enumCurrentDirection == a)
m_iSpeed -= 20;
m_vecBody[0].m_ix--;
m_enumCurrentDirection = a;
return false;
case'd':
m_vecBody[0].m_ix++;
m_enumCurrentDirection = d;
return false;
case 'q': //代表quit
changeDirections(m_enumCurrentDirection);
showSnake();
if (quitGame())
{
return true;
}
return false;
case '+':
changeDirections(m_enumCurrentDirection);
showSnake();
m_iSpeed -= 50;
return false;
case ' ':
changeDirections(m_enumCurrentDirection);
showSnake();
Cunit::gotoxy(CMap::KLEFT, CMap::KHEIGHT + 1);
cout << "游戲暫停,請按任意鍵繼續...";
_getch(); //游戲暫停
Cunit::gotoxy(CMap::KLEFT, CMap::KHEIGHT + 1);
for (int i = 0; i < 27; i++)
cout << ' ';
return false;
default:
changeDirections(m_enumCurrentDirection);
showSnake();
return false;
}
}
void CSnake::changeDirections(Directions dir)
{
switch (dir)
{
case w:
m_vecBody[0].m_iy--;
break;
case s:
m_vecBody[0].m_iy++;
break;
case a:
m_vecBody[0].m_ix--;
break;
case d:
m_vecBody[0].m_ix++;
break;
default:
break;
}
}
bool CSnake::quitGame() //退出游戲
{
Cunit::gotoxy(CMap::KLEFT, CMap::KHEIGHT + 1);
cout << "退出游戲?(y/n):";
char ch;
cin >> ch;
Cunit::gotoxy(CMap::KLEFT, CMap::KHEIGHT + 1);
for (int i = 0; i < 17; i++)
cout << ' ';
if (ch == 'y')
{
return true;
}
else return false;
}
//存盤移動坐標
void CSnake::movePos()
{
for (int i = m_iLength - 1; i > 0; i--)
{
m_vecBody[i].m_iy = m_vecBody[i - 1].m_iy;
m_vecBody[i].m_ix = m_vecBody[i - 1].m_ix;
}
}
//移動
bool CSnake::move()
{
bool flag = false;
movePos();
if (_kbhit())
{
char key;
key = _getch();
if (key == 'a' && m_enumCurrentDirection == d)
{
key = 'd';
flag=changeDirections(key);
}
else if (key == 'd' && m_enumCurrentDirection == a)
{
key = 'a';
flag=changeDirections(key);
}
else if (key == 'w' && m_enumCurrentDirection == s)
{
key = 's';
flag=changeDirections(key);
}
else if (key == 's' && m_enumCurrentDirection == w)
{
key = 'w';
flag=changeDirections(key);
}
else flag=changeDirections(key);
}
else changeDirections(m_enumCurrentDirection);
showSnake();
Sleep(m_iSpeed);
eraseSnake();
return flag;
}
//判斷是否吃到食物
bool CSnake::eatFood(CFood* pfood)
{
if (pfood->m_ix == m_vecBody[0].m_ix && pfood->m_iy == m_vecBody[0].m_iy)
return true;
else
return false;
}
//檢查食物位置是否在蛇身上
bool CSnake::checkFoodPos(CFood *pFood)
{
for (int i = 0; i < m_iLength; i++)
{
if (pFood->m_ix == m_vecBody[i].m_ix &&
pFood->m_iy == m_vecBody[i].m_iy)
return true;
}
return false;
}
//蛇吃到食物變長
void CSnake::growup()
{
Cunit c;
m_vecBody.push_back(c);
m_iLength++;
}
由于代碼量過大,所以這里只附加了部分代碼,更多的請點擊GitHub鏈接:
https://github.com/qing-qing-mei/Snake
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/249553.html
標籤:其他
下一篇:酒局游戲
