admin 管理员组

文章数量: 887021


2024年1月5日发(作者:mysql和oracle性能)

温馨提示

程序语言:C、C++、C#、Python

(红色字体表示本课设使用的程序设计语言)

图形功能选项:Win32控制台程序(黑框、文本界面)、Win32程序、MFC、WinForm、

DirectX10

(黑体标明表示本课设的程序图形类别,默认为非图形界面Win32控制台程序)

数据结构:基础类型、数组、链表、双向链表、搜索树(非平衡二叉树)、平衡二叉树、

链表与平衡二叉树相结合、堆栈、队列、串、图(黑体标明 表示本课设使用的数据结构)

C++语言项:STL库(黑体标明表示使用C++的STL库)

编译环境:Windows 7 64位旗舰版(Linux及其他环境请谨慎下载

集成开发环境:Visual C++ 6.0、DEVC++、CodeBlocks、Visual Studio 2015

均可通过编 译。(浅蓝色字体表示需要运行修改后的版本,请用户自行选择源代码测试)

分多头文件编译:否(所有代码基本都包含在一个文件内,如需试验头文件功能,请自

行参考相关文献)

内容说明:

1、课设题目及预览内容 将在第二页开始展示。

2、代码行数:259行

3、目录 所示内容,本文基本涵盖,如无内容,会在本页进行说明。

4、附录 绝对包含用户使用手册及程序完整源代码和详细注释。

5、如需下载 其他头文件(例如DirectX需另行配置),本文会在此进行说明。

6、本文撰写内容仅供学习参考,另外,由于本人水平有限,编写之处难免存在错

误和纰漏,恳请各位老师或同学批评指正。

■哥

If 242. 25-[Sc

EJJCEI ^ildw1 ■

DEMKU:

-

CWB-I

______________

.

女曲日iM|F| flEiq

1aHM

电口同酬网 口叶酩皿

BIIIWI

■:

BE AM 41 fi«3*

M司的票,「

- 行遇;Q

-

>*ri 0

titi文卷名二

n:V53033 1?=叼1=诋忙+〃翼日:...1>«

If

的大小;

1. 71JSJl»«9&Mi4l MLB

- 谴年讨同E..^

:;Sunn^wtri

-

-

长・上的

QV$»15,P«W«t-£>€C. .U vmirxpp 0WWCOtVi lib bte2S^ UUm2

h»«rt kd/Write

上机报告

程序实践名称: ________________________________

学生姓名: ________________________________

业: _________________________________

级: _________________________________

号: _________________________________

指导教师: ________________________________

上机成绩: ________________________________

上机地点: ________________________________

上机时间: ____________ 年 ______ 月 ______ 日

一、上机目的与上机要求(可以有多个目标及要求,对应多个上机内容)

1、上机目的(具体的目的,类似于“提出问题”)

将理论用于实践,更充分的掌握课本的知识,巩固并加深对课本知识的理解,

进一步提高我们的动手编程能力。编写程序既能锻炼我们的动手能力,又能培养

提高我们的学习热情。贪吃蛇是一个很简单而且比较益智的小游戏,编写起来比

较简单,而且我们所学的知识也恰好能解决这个问题。

首先,我们需要明确一下编写贪吃蛇的框架。

其次,需要几个类控制整个游戏的运作。

最后,如何解决蛇移动和吃到食物的问题。

2、上机要求

(具体的上机要求及相关的问题分析,类似于“分析问题”)

由于游戏比较简单,所以一个类足够驾驭这个游戏的运作。

还有蛇的移动,因为蛇吃到一个食物,相应的长度就加一,这样,应该拆成

蛇头、蛇身、蛇尾来进行比较方便操作,蛇头控制移动方向,而且蛇头吃到了食

物,则蛇尾不需要去除。

二、上机设备(环境)及要求

操作系统:Windows 7

编译环境:VC6.0++

三、上机内容与步骤(类似于“解决问题”)

1、步骤1

(1)上机内容(明确的上机内容):解决问题的思路和方法(系统/方法/算法

等),图文结合

首先,定义一个二维数组来储存整个地图的内容;

其次,再定义一个二维数组来记录蛇每部分的运动方向;

最后,分析一下整个游戏的关键:

一开始,我们把蛇分成了三个部分,蛇头、蛇身、蛇尾。

如图所示,黄色的是墙,这是初始状态的地图。

下图是初始状态的方向。

蛇开始默认移动,先擦除蛇头,绘制蛇身,如下图:

根据方向绘制蛇头,如下图:

擦除蛇尾,如下图:

再绘制蛇尾,如下图:

这样便完成了蛇的移动,同样的方向的记录也是类似的。

食物

蛇头

蛇尾

蛇头t

蛇尾t

注:有箭头代表蛇的方向。

当蛇吃到食物的时候,只需要在食物的地方绘制蛇头,而原来蛇 头的地方绘制蛇身即可,无须擦除蛇尾再进行绘制,然后重新产生食 物,如下图。

蛇头

蛇身

蛇尾

蛇头t

蛇身t

蛇尾t

食物

当检测到按键的时候,先改变蛇的移动方向,再移动蛇即可。

(2)主要实现(详细的关键代码)

void RetroSnaker::move()

{

switch (directionMap[hearY][hearX])

{

case UP:

if (FOOD == map[hearY - 1][hearX]) //吃到食物 againFood();

else if (EMPTY == map[hearY - 1][hearX]) //什么都没遇到 erasingTheTail(); //擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(UP);

break;

case DOWN:

if (FOOD == map[hearY + 1][hearX]) //吃到食物 againFood();

else if (EMPTY == map[hearY + 1][hearX]) //什么都没遇到 erasingTheTail(); //擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(DOWN);

break;

case LEFT:

if (FOOD == map[hearY][hearX - 1]) //吃到食物

againFood();

else if (EMPTY == map[hearY][hearX - 1]) //什么都没遇到 erasingTheTail(); //擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(LEFT);

break;

case RIGHT:

if (FOOD == map[hearY][hearX + 1]) //吃到食物

againFood();

else if (EMPTY == map[hearY][hearX + 1])//什么都没遇到 erasingTheTail(); 〃擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(RIGHT);

break;

default:

break;

}

}

:上机运行结果与分析

(详细的程序运行结果,图/表/文相结合,并对结果进行较全面的对比分析,类

似于“验证问题”)

与预期的结论一致,运行结果满足预期效果。

五:结论(讨论)

1、上机结论(对应前面的上机目的)

通过本次上机,充分的锻炼了我解决问题的能力,让我更加的了解到知识得

运用才能熟练的掌握,也提高了我的学习兴趣和热情。

2、讨论

(存在的问题及可能的改进方向)

游戏界面比较单一,只有蛇和食物,没有统计分数和排行榜,也 没

有游戏结束的画面,还不能调整游戏的难度,蛇的速度基本是恒定 的,无法动态修改。这是我需要改进的地方。

六、教师评审

教师评语

实验成绩

(虽然上机主要侧重于验证问题,但是建议各位老师从解决

“工程技术问题”,特别是“复杂工程问题”的角度去评审学 生上机过程及上机报告,主要内容包括提出问题、分析问题、 解决问题及验证问题。要有较详细的评审意见。)

签名:

日期:

附录

用户使用手册

1、编译运行即开始游戏。

2、按小写字母wsad即可进行游戏的操作。

3、按任意键暂停游戏

程序源代码

#include

#include

#include

#include

#include using namespace std;

#define N 20//地图大小

#define WALL 5

//墙

#define HEAR 1

//蛇头

#define TAIL 2

//蛇尾

#define BODY 3

//蛇身

#define FOOD 4

//食物

#define EMPTY 0

//空

#define UP 'w'

//蛇的前进方向:上下左右

#define DOWN 's'

#define LEFT 'a'

#define RIGHT 'd'

#define GMAE_TIME 100

class RetroSnaker {

public:

//设置游戏的绘制速度

RetroSnaker() { Init(); }

bool gameOver; //游戏是否结束

void move();

void move(char ch);

private:

int map[N][N]; //二维地图

int directionMap[N][N]; //方向图

int hearX, hearY; //蛇头坐标

int tailX, tailY; //蛇尾坐标

int foodX, foodY; //食物坐标

bool eatFood; //标记是否吃到食物

void Init();//初始化

void gotoXY(int x, int y); //光标跳转到屏幕的相应位置

void againFood(); //食物被吃,再次产生食物

void erasingTheTail(); //擦除尾巴

void erasingTheHear(char ch); //擦除蛇头

};

void RetroSnaker::move()

{

switch (directionMap[hearY][hearX])

{

case UP:

if (FOOD == map[hearY - 1][hearX]) //吃到食物 againFood();

else if (EMPTY == map[hearY - 1][hearX]) //什么都没遇到 erasingTheTail(); //擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(UP);

break;

case DOWN:

if (FOOD == map[hearY + 1][hearX]) //吃到食物 againFood();

else if (EMPTY == map[hearY + 1][hearX]) //什么都没遇到 erasingTheTail();

擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(DOWN);

break;

case LEFT:

if (FOOD == map[hearY][hearX - 1]) //吃到食物

againFood();

else if (EMPTY == map[hearY][hearX - 1]) //什么都没遇到 erasingTheTail();

擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

erasingTheHear(LEFT);

break;

case RIGHT:

if (FOOD == map[hearY][hearX + 1]) //吃到食物

againFood();

else if (EMPTY == map[hearY][hearX + 1]) //什么都没遇到 erasingTheTail();

擦除尾巴

else {

gameOver = true;//没有遇到食物或者空,则表示游戏结束 break;

}

//////

erasingTheHear(RIGHT);

break;

default:

break;

}

}

void RetroSnaker::move(char ch)

{

directionMap[hearY][hearX] = ch;

move();

}

void RetroSnaker::Init()

{

int i = 0,j=0;

gameOver = false;

eatFood = false;

for (i = 0; i < N; i++)

for (j = 0; j < N; j++) {

map[i][j] = EMPTY; //清空二维数组 directionMap[i][j]

图 }

for (i = 0; i < N; i++) { //初始化墙

map[0][i] = WALL;

map[N - 1][i] = WALL;

map[i][0] = WALL;

map[i][N - 1] = WALL;

}

//初始化蛇头

hearX = N / 2;

hearY = N / 2;

map[hearY][hearX] = HEAR;

directionMap[hearY][hearX] = RIGHT; //记录蛇头的移动方向

= EMPTY; //清空方向

//初始化蛇尾

tailX = N / 2 - 1;

tailY = N / 2;

map[tailY][tailX] = TAIL;

directionMap[tailY][tailX] = RIGHT; //记录蛇尾的移动方向

//初始化食物

srand(unsigned(time(NULL))); 〃随机播种

do {

foodX = rand() % (N - 1) + 1; 〃产生随机数 1~(N-1)

foodY = rand() % (N - 1) + 1;

} while (EMPTY != map[foodY][foodX]);

map[foodY][foodX] = FOOD;

//首次显示游戏界面

for (i = 0; i < N; i++) {

for (j = 0; j < N; j++)

switch

(map[i][j])

{

case WALL:cout

<< "■"; break;

case HEAR:cout

<< "o"; break;

case BODY:

case TAIL:cout

<< "•"; break;

case FOOD:cout

<< "★"; break

default:

cout << "

break;

}

cout << endl;

void RetroSnaker::gotoXY(int x, int y) {

COORD coord;

coord.X = 2*x;

coord.Y = y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),

}

void RetroSnaker::againFood()

{

srand(unsigned(time(NULL))); 〃随机播种

do {

foodX = rand() % (N - 1) + 1; 〃产生随机数 1~(N-1)

coord);

foodY = rand() % (N - 1) + 1;

} while (EMPTY != map[foodY][foodX]);

map[foodY][foodX] = FOOD;

gotoXY(foodX, foodY);

cout << "★";

}

void RetroSnaker::erasingTheTail()

{

gotoXY(tailX, tailY); //擦除尾巴 cout << " ";

map[tailY][tailX] = EMPTY;

if (UP == directionMap[tailY][tailX]) { directionMap[tailY][tailX] = EMPTY;

tailY--;

}

else if (DOWN == directionMap[tailY][tailX]) { directionMap[tailY][tailX] =

EMPTY;

tailY++;

}

else if (LEFT == directionMap[tailY][tailX]) { directionMap[tailY][tailX] =

EMPTY;

tailX--;

}

else { directionMap[tailY][tailX] = EMPTY;

tailX++;

}

map[tailY][tailX] = TAIL;

}

void RetroSnaker::erasingTheHear(char ch)

{

int x= hearX, y = hearY;

if (UP == ch)

--hearY;

else if (DOWN == ch)

++hearY;

else if (LEFT == ch)

hearX--;

else

hearX++;

map[y][x] = BODY;

gotoXY(x, y);

cout << "•";

//擦除蛇头,绘制蛇身

directionMap[hearY][hearX] = directionMap[y][x]; //绘制蛇头 map[hearY][hearX] =

HEAR;

gotoXY(hearX, hearY);

cout << "o";

int main(void)

{

char ch;

bool sign = false;

DWORD keyTime=0;

RetroSnaker r;

while (true) {

if (er) {

_getch();

break;

//游戏结束

if (_kbhit()) { //检测是否按下键盘

ch = _getch(); //获取该按键,并不回显在屏幕上 sign = true;

if (GetTickCount()- keyTime > GMAE_TIME&&sign) {//两次按键的间隔时间大于

GMAE_TIME 毫秒则移动蛇

(ch); //移动蛇 keyTime = GetTickCount(); sign = false;

}

else { //没按下键盘,则默认处理

if (GetTickCount() - keyTime > GMAE_TIME) { //两次按键的间隔时间大于

GMAE_TIME 毫秒则移动蛇

(); //默认移动

keyTime = GetTickCount();

return

0; }

附件

贪吃蛇VC6.0++项目.zip


本文标签: 上机 游戏 问题 内容 表示