学习C++有一段时间了,但是一直都没怎么用它来做些事。这两天刚好有时间,就用C++实现了一把贪吃蛇小游戏程序。新手发文,水平有限,望谅解!!话不多说,直接上源码:
-----------common.h头文件程序-------------------------------------
#include
#include
using namespace std;
//设置每个坐标位置的值
extern short value[30][60];
//初始化得分
extern int my_scores ;
//蛇头的运动方向
enum direct { east,west,north,south, };
//移动光标到指定位置
extern void gotoxy(short x, short y);
----------------food.h头文件程序---------------------
#pragma once
#include
#include
#include"common.h"
#include"point.h"
using namespace std;
class food {
public:
//产生食物
void product_food();
//画出食物
void draw_food();
private:
//食物的位置
point food_position;
};
------------------point.h头文件程序---------------------------
#pragma once
//定义point类
class point {
public:
//点的两个坐标值
short x;
short y;
//默认构造函数
point() {}
point(short m, short n) :x(m), y(n) {}
//拷贝构造函数
point(const point& pointer) {
x = pointer.x;
y = pointer.y;
}
//拷贝赋值运算符
point& operator=(const point & pointer) {
x = pointer.x;
y = pointer.y;
return *this;
}
};
---------------------printinfo.h头文件程序----------------------------------------
#pragma once
#include
#include
#include"common.h"
using namespace std;
class printinfo {
public:
//打印得分
void print_score();
////打印出游戏开始时的封面
void print_cover();
//打印墙壁,隐藏光标,并将墙壁所处坐标的值全部设为2
void print_wall();
//打印出结果-蛇因为撞墙而死
void print_end_info_wall();
//打印出结果-蛇因为撞自己而死
void print_end_info_self();
};
------------------snake.h头文件程序----------
#pragma once
#include"point.h"
#include
#include
#include
#include"common.h"
using namespace std;
class snake {
private:
//蛇头
point snake_head;
//记录小蛇每次运动之前的最后一节的位置
point record_tail_point;
//记录小蛇运动一格后,蛇头将到达的位置点的值,这个值用来判断小蛇是否撞到墙或者自己,或者吃到食物
int record_new_begin_value;
//用一个双向链表来装小蛇的全身
list
public:
//小蛇当前的运动方向
direct direction;
//蛇的长度,用途不大,只有在初始化时设置为3节
short snake_length;
public:
//默认构造函数
snake();
//画蛇身子
void draw_snake();
//蛇动起来
void snake_move();
//是否吃到食物
bool is_eat_food();
//是否撞到墙
bool is_collide_wall();
//是否撞到自己
bool is_collide_self();
//蛇变长
void become_longer();
//擦除残影
void remove_shadow();
};
----------common.cpp源文件程序------------
#include"common.h"
//设置每个坐标位置的值
short value[30][60] = { 0 };
//初始化得分
int my_scores = 1;
//移动光标到指定位置
void gotoxy(short x, short y) {
COORD coord = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
--------------food.cpp源文件程序-----------------------------------
#include"food.h"
//产生食物的位置
void food::product_food() {
do {
srand(unsigned(time(0)));
food_position.x = (rand() % 28) * 2 + 2;
food_position.y = rand() % 28 + 1;
} while (value[food_position.x][food_position.y] == 1);
}
//将食物在固定坐标上画出来
void food::draw_food() {
gotoxy(food_position.x, food_position.y);
value[food_position.x][food_position.y] = 3;
cout << '*';
}
----------------------printinfo.cpp源文件程序----------------------
#include"printinfo.h"
#include
//打印墙壁,隐藏光标,并将墙壁所处坐标的值全部设为2
void printinfo::print_wall() {
system("cls");
for (short i = 0; i < 30; i++) {
gotoxy(0, i);
cout << '#';
}
for (short i = 0; i <30; i++) {
gotoxy(58, i);
cout << '#';
}
for (short i = 0; i <60; i++) {
gotoxy(i, 0);
cout << '#';
i++;
}
for (short i = 0; i < 60; i++) {
gotoxy(i, 29);
cout << '#';
i++;
}
for (short i = 0; i < 60; i = i + 2) {
value[i][0] = 2;
value[i][29] = 2;
}
for (short i = 0; i < 30; i++) {
value[0][i] = 2;
value[58][i] = 2;
}
//隐藏光标
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}
//打印得分
void printinfo::print_score() {
gotoxy(85, 15);
cout << "您的得分:" << my_scores;
}
//打印出游戏开始时的封面
void printinfo::print_cover() {
cout << " " << "欢迎来到贪吃蛇游戏" << endl;
cout << endl;
cout << " " << "a表示向左运动,d表示向右运动" << endl;
cout << endl;
cout << " " << "w表示向上运动,s表示向下运动" << endl;
cout << endl;
cout << " " << "祝您游戏愉快" << endl;
cout << endl;
cout << endl;
cout << "请输入任意键进入游戏" << endl;
int a = _getch();
}
//打印出结果-蛇因为撞墙而死
void printinfo::print_end_info_wall() {
system("cls");
cout << " "<<"Game Over" << endl;
cout << " "<<"撞墙了!!!!!" << endl;
char a;
a=_getch();
exit(0);
}
//打印出结果-蛇因为撞自己而死
void printinfo::print_end_info_self() {
system("cls");
cout << " " << "Game Over" << endl;
cout << " " << "撞自己了!" << endl;
char a;
a = _getch();
exit(0);
}
---------------------snake.cpp源文件程序-----------------------
#include"snake.h"
//默认构造函数
snake::snake():snake_length(3) {
snake_head.x = (rand() % 26) * 2 + 6;
snake_head.y = rand() % 28 + 1;
for (int i = 0; i < snake_length; i++) {
snake_body.push_back(point(snake_head.x - 2 * i, snake_head.y));
}
record_tail_point = snake_body.back();
}
//画蛇身子
void snake::draw_snake() {
list
for (; it != snake_body.end(); it++) {
value[it->x][it->y] = 1;
gotoxy(it->x, it->y);
cout << '#';
}
}
//不管向哪个方向,小蛇都运动一格
void snake::snake_move() {
record_tail_point = snake_body.back();
for (auto it = (--(snake_body.end())); it != snake_body.begin();) {
short& p = it->x;
short& q = it->y;
p = (--it)->x;
it++;
q = (--it)->y;
}
if (direction == east)
snake_body.begin()->x += 2;
else if (direction == west)
snake_body.begin()->x -= 2;
else if (direction == north)
snake_body.begin()->y -= 1;
else
snake_body.begin()->y += 1;
record_new_begin_value = value[snake_body.front().x][snake_body.front().y];
}
//是否吃到食物
bool snake::is_eat_food() {
if (record_new_begin_value== 3)
return true;
else
return false;
}
//蛇变长
void snake::become_longer() {
snake_body.push_back(record_tail_point);
}
//是否撞到墙
bool snake::is_collide_wall() {
if (record_new_begin_value== 2)
return true;
else
return false;
}
//是否撞到墙
bool snake::is_collide_self() {
if (record_new_begin_value == 1)
return true;
else
return false;
}
//擦除残影
void snake::remove_shadow() {
gotoxy(record_tail_point.x,record_tail_point.y);
value[record_tail_point.x][record_tail_point.y] = 0;
cout << ' ';
}
--------------------main.cpp主程序----------------------------------
#include"snake.h"
#include"food.h"
#include"printinfo.h"
#include
#include"common.h"
int main() {
//实例化一个printinfo类
printinfo printinfoer;
//打印游戏封面
printinfoer.print_cover();
//打印游戏围墙
printinfoer.print_wall();
//实例化一个snake类
snake snaker;
//第一次画小蛇
snaker.draw_snake();
//实例化一个food类
food fooder;
//第一次产生食物
fooder.product_food();
//第一次画食物
fooder.draw_food();
//打印得分,基础分为1分,没吃1个食物的1分
printinfoer.print_score();
while (1) {
//阻塞状态来等待输入运动方向
int a = _getch();
switch (a) {
case 100://向右
//如果自身的运动方向是向左的,那么按d(向右运动)是没有用的,直接跳出本次循环,并进行下次循环
if (snaker.direction == west) break;
//将小蛇本身的方向属性改为east
snaker.direction = east;
//小蛇运动一格
snaker.snake_move();
//画出运动后的小蛇
snaker.draw_snake();
//将之前的小蛇最后一节残影删除
snaker.remove_shadow();
//判断小蛇运动一格之后是否吃到食物,如果是,进入语句块
if (snaker.is_eat_food() == 1) {
//蛇身变长一格
snaker.become_longer();
//画出变长后的小蛇
snaker.draw_snake();
//重新在内存中产生一个食物
fooder.product_food();
//重新画出一个食物
fooder.draw_food();
//得分加1
my_scores++;
//蛇长度加1
snaker.snake_length++;
//打印最新得分
printinfoer.print_score();
}
//判断是否撞到自己,如果是,结束游戏
if ( snaker.is_collide_self() == 1)
printinfoer.print_end_info_self();
//判断是否撞到墙,如果是,结束游戏
if (snaker.is_collide_wall() == 1 )
printinfoer.print_end_info_wall();
break;
case 97://向左-------(逻辑过程与向右基本相同)
if (snaker.direction == east) break;
snaker.direction = west;
snaker.snake_move();
snaker.draw_snake();
snaker.remove_shadow();
if (snaker.is_eat_food() == 1) {
snaker.become_longer();
snaker.draw_snake();
fooder.product_food();
fooder.draw_food();
my_scores++;
printinfoer.print_score();
}
if (snaker.is_collide_self() == 1)
printinfoer.print_end_info_self();
if (snaker.is_collide_wall() == 1)
printinfoer.print_end_info_wall();
break;
case 119://向上
if (snaker.direction==south) break;
snaker.direction = north;
snaker.snake_move();
snaker.draw_snake();
snaker.remove_shadow();
if (snaker.is_eat_food() == 1) {
snaker.become_longer();
snaker.draw_snake();
fooder.product_food();
fooder.draw_food();
my_scores++;
printinfoer.print_score();
}
if (snaker.is_collide_self() == 1)
printinfoer.print_end_info_self();
if (snaker.is_collide_wall() == 1)
printinfoer.print_end_info_wall();
break;
case 115://向下
if (snaker.direction==north) break;
snaker.direction = south;
snaker.snake_move();
snaker.draw_snake();
snaker.remove_shadow();
if (snaker.is_eat_food() == 1) {
snaker.become_longer();
snaker.draw_snake();
fooder.product_food();
fooder.draw_food();
my_scores++;
printinfoer.print_score();
}
if (snaker.is_collide_self() == 1)
printinfoer.print_end_info_self();
if (snaker.is_collide_wall() == 1)
printinfoer.print_end_info_wall();
break;
default:
break;
}
}
return 0;
}