今天跟大家分享一下个人的一个课程设计
一、前言
编译器是vs,需要在vs上安装easyX。
构造函数加载图像里面是你的素材所在路径。
二、代码
#include<iostream>
#include<vector>
#include<conio.h>
#include<time.h>
#include<graphics.h>
using namespace std;
int Size = 10, Grade = 0;
//箱子移动
class Push_box {
private:
IMAGE ima_up, ima_down, ima_left, ima_right;
IMAGE ima_ground, ima_wall, ima_box, ima_dest, ima_arrive;
int person_row = 0, person_rank = 0, cnt = 0, map[100][100] = { 0 }, grade = 0;
vector<string>flag;
char key = '\0';
ExMessage exm;
public:
Push_box()//构造函数加载图像
{
loadimage(&ima_ground, _T("./地面.png"));
loadimage(&ima_up, _T("./上.png"));
loadimage(&ima_down, _T("./下.png"));
loadimage(&ima_left, _T("./左.png"));
loadimage(&ima_right, _T("./右.png"));
loadimage(&ima_box, _T("./箱子.png"));
loadimage(&ima_wall, _T("./墙.png"));
loadimage(&ima_dest, _T("./目的地.png"));
loadimage(&ima_arrive, _T("./arrive.png"));
}
int Get_cnt()//得到以到达目的地的箱子个数
{
return cnt;
}
char Get_key()//得到该操作
{
return key;
}
int Get_grade()//得到当前分数
{
return grade;
}
void Make_map()//制作地图
{
//1 人物, 2 箱子, 3 墙, 4 目的地, 5 人与目的地重合, 6 箱子到达目的地
srand(time(NULL));
int car_row = rand() % 8 + 1;
int car_rank = rand() % 8 + 1;
map[car_row][car_rank] = 1;
int cnt1 = 0;
for (int i = 0; i < Size; i++)//用墙围成闭合区域
{
for (int j = 0; j < Size; j++)
{
if (i == 0 || j == 0 || i == Size - 1 || j == Size - 1)
map[i][j] = 3;
}
}
for (int i = 0; cnt1 < Size - 6; i++)//生成盒子,通过Size可以改变生成箱子的数量,默认为Size-6
{
int x = rand() % (Size - 6) + 3;
int y = rand() % (Size - 6) + 3;
if (map[x][y] == 0)
{
map[x][y] = 2;
cnt1++;
}
}
cnt1 = 0;
for (int i = 0; cnt1 < Size - 6; i++)//生成目的地,通过Size可以改变生成目的地的数量,默认为Size-6(目的地应与箱子数量相同)
{
int x = rand() % (Size - 2) + 1;
int y = rand() % (Size - 2) + 1;
if (map[x][y] == 0)
{
map[x][y] = 4;
cnt1++;
}
}
cnt1 = 0;
for (int i = 0; cnt1 < Size - 3; i++)//生成墙壁,通过Size可以改变生成墙壁的数量,默认为Size-3
{
int x = rand() % Size - 2 + 1;
int y = rand() % Size - 2 + 1;
if (map[x][y] == 0)
{
map[x][y] = 3;
cnt1++;
}
}
}
void Return(string key)//返回上一步操作
{
if (key == "a1")//向左走,且左边没有箱子
{
person_rank++;//退回
map[person_row][person_rank - 1]--;//左边map值减一
map[person_row][person_rank] ++;//当前位置map值加一
}
if (key == "a2")//向左走且左边有箱子
{
person_rank++;
map[person_row][person_rank - 2] -= 2;
map[person_row][person_rank - 1] ++;
map[person_row][person_rank] ++;
}
if (key == "d1")
{
person_rank--;
map[person_row][person_rank + 1] --;
map[person_row][person_rank] ++;
}
if (key == "d2")
{
person_rank--;
map[person_row][person_rank + 2] -= 2;
map[person_row][person_rank + 1] ++;
map[person_row][person_rank] ++;
}
if (key == "s1")
{
person_row--;
map[person_row + 1][person_rank] --;
map[person_row][person_rank] ++;
}
if (key == "s2")
{
person_row--;
map[person_row + 2][person_rank] -= 2;
map[person_row + 1][person_rank] ++;
map[person_row][person_rank]++;
}
if (key == "w1")
{
person_row++;
map[person_row - 1][person_rank]--;
map[person_row][person_rank]++;
}
if (key == "w2")
{
person_row++;
map[person_row - 2][person_rank] -= 2;
map[person_row - 1][person_rank] ++;
map[person_row][person_rank]++;
}
}
void Find_person()//拿到自己的坐标
{
for (int i = 0; i < Size; i++)
for (int j = 0; j < Size; j++)
{
if (map[i][j] == 1)
{
person_row = i;
person_rank = j;
return;
}
}
}
void Print()//打印地图
{
cnt = 0;
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
//根据map值和当前操作打印对应图像
if (map[i][j] == 0)
putimage(j * 64, i * 64, &ima_ground);
else if (map[i][j] == 1 || map[i][j] == 5)
{
if (key == 'a')
{
putimage(j * 64, i * 64, &ima_left);
}
else if (key == 'd')
{
putimage(j * 64, i * 64, &ima_right);
}
else if (key == 'w')
{
putimage(j * 64, i * 64, &ima_up);
}
else
putimage(j * 64, i * 64, &ima_down);
}
else if (map[i][j] == 2)
putimage(j * 64, i * 64, &ima_box);
else if (map[i][j] == 3)
putimage(j * 64, i * 64, &ima_wall);
else if (map[i][j] == 4)
putimage(j * 64, i * 64, &ima_dest);
else if (map[i][j] == 6)//箱子已到达目的地
{
putimage(j * 64, i * 64, &ima_arrive);
cnt++;
}
}
}
grade = Grade + cnt;
}
void Initial()//初始化
{
//初始化地图
for (int i = 0; i < Size; i++)
for (int j = 0; j < Size; j++)
map[i][j] = 0;
cnt = 0; //初始化计数
grade = Grade;//继承分数
flag.clear();//清空vector容器
}
void Next()//获取下一步操作
{
key = _getch();//得到操作
if (key == 'o' || key == 'O' || key == 27)//按o或者Esc退出
{
over:
wchar_t s_[10];
InputBox(s_, 10, L"确定要结束游戏吗 1:确定 0:取消", 0, 0, 0, 0, 0);//再次确认
if (_wtoi(s_) == 1)
Over();//进入结束界面
else
key = '\0';
}
else if (key == 'w' || key == 'W')
{
up:
key = 'w';
if (person_row - 1 < 0)//判断是否越界
return;
else if (map[person_row - 1][person_rank] == 0 || map[person_row - 1][person_rank] == 4)//上面是空或者目的地
{
flag.push_back("w1");
map[person_row - 1][person_rank] ++;
map[person_row][person_rank]--;
person_row--;
}
else if ((map[person_row - 1][person_rank] == 2 || map[person_row - 1][person_rank] == 6) && person_row - 2 >= 0 && (map[person_row - 2][person_rank] == 4 || map[person_row - 2][person_rank] == 0))//上面有箱子
{
flag.push_back("w2");
map[person_row - 2][person_rank] += 2;
map[person_row - 1][person_rank] --;
map[person_row][person_rank]--;
person_row--;
}
}
else if (key == 's' || key == 'S')
{
down:
key = 's';
if (person_row + 1 >= Size)
return;
else if (map[person_row + 1][person_rank] == 0 || map[person_row + 1][person_rank] == 4)
{
flag.push_back("s1");
map[person_row + 1][person_rank] ++;
map[person_row][person_rank] --;
person_row++;
}
else if ((map[person_row + 1][person_rank] == 2 || map[person_row + 1][person_rank] == 6) && person_row + 2 < Size && (map[person_row + 2][person_rank] == 0 || map[person_row + 2][person_rank] == 4))
{
flag.push_back("s2");
map[person_row + 2][person_rank] += 2;
map[person_row + 1][person_rank] --;
map[person_row][person_rank]--;
person_row++;
}
}
else if (key == 'a' || key == 'A')
{
left:
key = 'a';
if (person_rank - 1 < 0)
return;
else if (map[person_row][person_rank - 1] == 0 || map[person_row][person_rank - 1] == 4)
{
flag.push_back("a1");
map[person_row][person_rank - 1]++;
map[person_row][person_rank] --;
person_rank--;
}
else if ((map[person_row][person_rank - 1] == 2 || map[person_row][person_rank - 1] == 6) && person_rank - 2 >= 0 && (map[person_row][person_rank - 2] == 4 || map[person_row][person_rank - 2] == 0))
{
flag.push_back("a2");
map[person_row][person_rank - 2] += 2;
map[person_row][person_rank - 1] --;
map[person_row][person_rank]--;
person_rank--;
}
}
else if (key == 'd' || key == 'D')
{
right:
key = 'd';
if (person_rank + 1 >= Size)
return;
else if (map[person_row][person_rank + 1] == 0 || map[person_row][person_rank + 1] == 4)
{
flag.push_back("d1");
map[person_row][person_rank + 1] ++;
map[person_row][person_rank] --;
person_rank++;
}
else if ((map[person_row][person_rank + 1] == 2 || map[person_row][person_rank + 1] == 6) && person_rank + 2 < Size && (map[person_row][person_rank + 2] == 4 || map[person_row][person_rank + 2] == 0))
{
flag.push_back("d2");
map[person_row][person_rank + 2] += 2;
map[person_row][person_rank + 1] --;
map[person_row][person_rank] --;
person_rank++;
}
}
else if (key == 'z' || key == 'Z')//按z返回上一步
{
back:
if (flag.size() > 0)//如果进行过操作可以返回
{
Return(flag.back());
if (flag.back() == "a1" || flag.back() == "a2")
key = 'a';
else if (flag.back() == "s1" || flag.back() == "s2")
key = 's';
else if (flag.back() == "d1" || flag.back() == "d2")
key = 'd';
else if (flag.back() == "w1" || flag.back() == "w2")
key = 'w';
flag.pop_back();//去掉前一次操作
}
}
else if (key == 13)//回车键调出输入框
{
wchar_t s[10];
InputBox(s, 10, L"请输入操作:\n1:左 2:下 3:右 5:上\n4:结束游戏 6:返回上一步\n大于等于10:改变地图大小并重新生成地图", 0, 0, 0, 0, 0);
if (_wtoi(s) == 5)
goto up;
else if (_wtoi(s) == 2)
goto down;
else if (_wtoi(s) == 1)
goto left;
else if (_wtoi(s) == 3)
goto right;
else if (_wtoi(s) == 6)
goto back;
else if (_wtoi(s) < 1 || (_wtoi(s) > 6 && _wtoi(s) < 10))//防止重新生成地图
key = '\0';
else if (_wtoi(s) >= 10)//改变地图大小
Size = _wtoi(s);
else if (_wtoi(s) == 4)//退出
goto over;
}
}
void Over()//结束界面
{
cleardevice();
IMAGE ima;
loadimage(&ima, _T("C:\\Users\\好家伙\\Desktop\\地面.png"));
//打印地面
for (int i = 0; i < Size; i++)
for (int j = 0; j < Size; j++)
putimage(j * 64, i * 64, &ima);
//打印最终分数
settextstyle(30, 30, _T("楷书"));
settextcolor(BLACK);
setbkmode(TRANSPARENT);//设置背景为透明
outtextxy(100, 64 * Size / 3, _T("最终分数为:"));
TCHAR s[10];
_stprintf_s(s, _T("%d"), Grade);
outtextxy(100 + textwidth(_T("最终分数为:")), 64 * Size / 3, s);
system("pause");//暂停
exit(0);//结束
}
};
//开场动画
class _Begin {
private:
float x = 128, y = 0;
IMAGE ima_g, ima_b1, ima_arr, ima_b2, ima_dest, ima_push;
public:
_Begin()//构造函数,加载好图片
{
loadimage(&ima_g, _T("./地面.png"));
loadimage(&ima_b1, _T("./箱.png"));
loadimage(&ima_b2, _T("./子.png"));
loadimage(&ima_dest, _T("./目的地.png"));
loadimage(&ima_push, _T("./推.png"));
loadimage(&ima_arr, _T("./arr.png"));
settextstyle(25 * 2, 15 * 2, _T("楷书"));
setbkmode(TRANSPARENT);
settextcolor(BLACK);
}
void Draw_ground()//打印地面
{
for (int i = 0; i < Size; i++)
for (int j = 0; j < Size; j++)
putimage(j * 64, i * 64, &ima_g);
}
void Fall()//模拟下降
{
//绘制“箱子”的移动
while (y < 2 * 64)
{
y += 16;
Draw_ground();
putimage(x, y, &ima_b1);
putimage(x + 64, y, &ima_b2);
putimage(128 + 4 * 64, y, &ima_dest);//打印目的地
Sleep(150);
cleardevice();//清屏
}
x = 0;
//绘制“推”的移动
while (x <= 3 * 64)
{
x += 12;
Draw_ground();
if (x < 0)//“推”未到之前箱子不用动
{
putimage(100, y, &ima_b1);
putimage(100 + 64, y, &ima_b2);
putimage(x, y, &ima_push);
putimage(128 + 4 * 64, y, &ima_dest);
}
else//“推”到之后一起移动
{
putimage(128 + 4 * 64, y, &ima_dest);
putimage(x + 128, y, &ima_b1);
putimage(x + 128 + 64, y, &ima_b2);
putimage(x, y, &ima_push);
}
Sleep(150);
cleardevice();
}
Draw_ground();
putimage(x + 128, y, &ima_b1);
putimage(x + 128 + 64, y, &ima_arr);//箱子与目的地重合之后变为红色
putimage(x, y, &ima_push);
}
};
//绘制开始游戏按钮
class Exmessage {
private:
ExMessage mes;
RECT r;
public:
Exmessage(RECT r_)
{
r.left = r_.left;
r.right = r_.right;
r.top = r_.top;
r.bottom = r_.bottom;
}
void Play()//展示开始游戏按钮
{
while (1)
{
if (peekmessage(&mes))//得到一个消息
{
switch (mes.message)
{
case WM_LBUTTONDOWN://左键在按钮处按下直接返回
if (mes.x >= r.left && mes.x <= r.right && mes.y >= r.top && mes.y <= r.bottom)
{
return;
}
break;
case WM_MOUSEMOVE://鼠标在按钮内是填充为青色,否则为黑色
if (mes.x >= r.left && mes.x <= r.right && mes.y >= r.top && mes.y <= r.bottom)
setfillcolor(CYAN);
else
setfillcolor(BLACK);
//绘制按钮
fillrectangle(r.left, r.top, r.right, r.bottom);
drawtext(_T("开始游戏"), &r, DT_CENTER);
break;
default:
break;
}
}
}
}
};
int main()
{
//创建窗口,开场动画
initgraph(64 * Size, 64 * Size);
Push_box p;
_Begin b;
b.Fall();
//给出提示
settextcolor(WHITE);
settextstyle(15, 15, _T("楷书"));
outtextxy(40, 200, _T("w:上 s:下 a:左 d:右 q:退出 z:返回上一步"));
//打印开始游戏
RECT r = { 210, 260, 440, 300 };
settextstyle(30, 30, _T("楷书"));
setfillcolor(BLACK);
settextcolor(0xffffb4);
fillrectangle(r.left, r.top, r.right, r.bottom);
drawtext(_T("开始游戏"), &r, DT_CENTER);//以r为外切矩形,文字水平居中打印
//绘制开始游戏按钮
Exmessage e(r);
e.Play();
//开始游戏
while (1)
{
make:
p.Initial();//初始化
p.Make_map();//制作地图
p.Find_person();//找到自身坐标
while (p.Get_cnt() < Size - 6)
{
p.Print(); //绘制地图
//打印分数
settextstyle(15, 15, _T("楷书"));
settextcolor(BLACK);
setbkmode(TRANSPARENT);
outtextxy(250, 30, _T("Grade:"));
TCHAR s[10];
_stprintf_s(s, _T("%d"), p.Get_grade());
outtextxy(260 + textwidth(_T("Grade:")), 30, s);
p.Next();
cleardevice();//清屏
if (p.Get_key() == 13)//回车改变地图大小
{
closegraph();
initgraph(64 * Size, 64 * Size);//重新初始化窗口
goto make;//goto避免分数相加
}
}
Grade += Size - 6;//下一关时继承分数
}
closegraph();
return 0;
}
三、素材
链接:https://pan.baidu.com/s/1qlD-QPUeYmMpaajQtGabRQ?pwd=vtgh
提取码:vtgh
总结
对于该课程设计,有什么问题都可以私信我啊~
等我有时间会重新编辑一下,把代码分开讲解,
链接中只有素材和代码,答辩的ppt和视频找不到了QAQ,但是老师让录了一个代码讲解的视频给他,如果有需要的话,可以私信我啊