推箱子游戏全代码+资源

 全资源免费下载

tool.h

#pragma once
#include<easyx.h>
void drawImg(int x, int y, IMAGE* src) {

	DWORD* pwin = GetImageBuffer();
	DWORD* psrc = GetImageBuffer(src);
	int win_w = getwidth();
	int win_h = getheight();
	int src_w = src->getwidth();
	int src_h = src->getheight();
	//计算 贴图的实际长宽
	int real_w = (x + src_w > win_w) ? win_w - x : src_w;
	int real_h = (y + src_h > win_h) ? win_h - y : src_h;
	if (x < 0) { psrc += -x;            real_w -= -x;   x = 0; }
	if (y < 0) { psrc += (src_w * -y);  real_h -= -y;   y = 0; }

	//修正贴图起始位置
	pwin += (win_w * y + x);

	//实现透明贴图
	for (int iy = 0; iy < real_h; iy++) {
		for (int ix = 0; ix < real_w; ix++) {
			byte a = (byte)(psrc[ix] >> 24);
			if (a > 100) {
				pwin[ix] = psrc[ix];
			}
		}
		//换到下一行
		pwin += win_w;
		psrc += src_w;
	}
}

main.cpp 

#include<iostream>
using namespace std;
#include<easyx.h>
#include<fstream>
#include<stdio.h>
#include"tool.h"
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")


//游戏场景定义
#define AIR   '0'
//游戏区外面
#define SPACE '1'
//空地		
#define BOX   '2'
//箱子		
#define WALL  '3'
//墙体		
#define DEST  '4'
//目的地    

//定义窗口宽度和高度
#define W 640
#define H 640
//定义每个格子的宽度
#define SIZE 40
//箱子最大数目
#define MAXNUM 30

//自定义坐标类型
typedef struct {
	int x;
	int y;
}locate;

//存储目的地,待会用来判断是否胜利
typedef struct {
	int num;
	//目的地的数量
	locate	dest[MAXNUM];
	//每个目的地的坐标
}Dests;

Dests d;
//目的地
int level;
//关卡

//读取关卡
void LoadLevel() {
	ifstream ifs;
	char tmp[10];
	ifs.open("./level/level.txt", ios::in);
	while (ifs >> tmp) {}
	level = atoi(tmp);
	ifs.close();
}

//写入关卡
void WriteLevel(int a) {
	ofstream ofs;
	char tmp[20];
    sprintf(tmp, "%d", a);
	ofs.open("./level/level.txt", ios::out);
	ofs << tmp<< endl;
	ofs.close();
}

//定义地图的类
class Map {
	friend class Person;
public:
	Map();
	//初始化地图数据
	void Draw();
	//绘制地图		
private:
	char map[H / SIZE+1][W / SIZE];
	//地图数据(不包括人物和箱子)
};

//定义箱子的类
class  Box{
	friend class Person;
public:
	Box();
	//初始化箱子数据
	void Draw(Dests& d);
	//绘制箱子	
	bool IsWin(Map& m);
	//用来判断是否胜利
private:
	int num;
	//箱子的数目
	locate box[MAXNUM];
	//每个箱子的坐标
};

//定义角色的类
class Person {
public:
	Person();
	//初始化角色数据
	void Draw();
	//绘制角色
	void Move(Map& m, Box& b);
	//移动
	bool IsBox(Box& b, int x, int y);
	//用来判断移动路径上的两个箱子是否靠在一起
private:
	int x, y;
	//角色的坐标
};

int main() {
	int n;
a:
	cout << "请输入关卡(1-6):";
	cin >> n;
	if (n < 1 || n>6) {
		cout << "输入错误!"<<endl;
		goto a;
	}
	level = n - 1;
	initgraph(W, H,0);
	//背景音乐
	mciSendString("open bk.mp3", 0, 0, 0);
	mciSendString("play bk.mp3 repeat", 0, 0, 0);
table:
	//关卡设置
	level++;
	if (level == 7) {
		closegraph();
		cout << "恭喜通关!" << endl;
		return 0;
	}
	char str[10];
	sprintf(str, "第%d关", level);
	Map m;
	Box box;
	Person one;
	//游戏
	while (1) {
		one.Move(m,box);
		BeginBatchDraw();
		cleardevice();
		m.Draw();
		outtextxy(5, 5, str);
		box.Draw(d);
		one.Draw();
		EndBatchDraw();
		FlushBatchDraw();
		if (box.IsWin(m)) {
			//WriteLevel(level);
			break;
		}
		Sleep(80);
	};
	d.num = 0;

	goto table;
	return 0;
}

//初始化地图数据
Map::Map() {
	ifstream ifs;
	char str[20];
	sprintf(str, "./level/%d_map.txt", level);
	ifs.open(str, ios::in);
	int i = 0;
	while (ifs >> this->map[i]) {
		i++;
	}
	ifs.close();
	for (int i = 0; i < H / SIZE; i++) {
		for (int j = 0; j < W / SIZE; j++) {
			if (this->map[i][j] == '4') {
				d.num++;
				d.dest[d.num - 1].x = j * SIZE;
				d.dest[d.num - 1].y = i * SIZE;
			}
		}
	}
}

//绘制地图
void Map::Draw() {
	IMAGE bk;
	loadimage(&bk, "./bk.jpg", W, H);
	putimage(0, 0, &bk);
	for (int i = 0; i < H / SIZE; i++) {
		for (int j = 0; j < W / SIZE; j++) {
			int x = j * SIZE;
			int y = i * SIZE;
			//空地
			if (this->map[i][j] == SPACE) {
				setfillcolor(RGB(210, 210, 210));
				fillrectangle(x, y, (x + SIZE), (y + SIZE));
			}
			//墙体
			if (this->map[i][j] == WALL) {
				IMAGE a;
				loadimage(&a, "./wall.png", SIZE, SIZE);
				putimage(x, y, &a);
			}
			//目的地
			if (this->map[i][j] == DEST) {
				setfillcolor(RGB(210, 210, 210));
				fillrectangle(x, y, (x + SIZE), (y + SIZE));
				IMAGE a;
				loadimage(&a, "./dest.png", SIZE, SIZE);
				drawImg(x, y, &a);
				//调用"tool.h"头文件当中的接口实现透明贴图
			}
		}
	}
}

//初始化箱子数据
Box::Box() {
	this->num = 0;
	ifstream ifs;
	char str[20];
	sprintf(str, "./level/%d_box.txt", level);
	ifs.open(str, ios::in);
	char tmp[20];
	int i = 0;
	int j = 0;
	while (ifs >> tmp) {	
		if (i == 0) {
			this->box[j].x = atoi(tmp)*SIZE;
		}
		if (i == 1) {
			this->box[j].y = atoi(tmp)*SIZE;
		}
		i++;
		if (i == 2) {
			i = 0;
			j++;
			this->num++;
		}
	}
	ifs.close();
}

//绘制箱子
void Box::Draw(Dests& d) {
	for (int i = 0; i < this->num; i++) {
		IMAGE a;
		int status = 0;
		for (int m = 0; m < d.num; m++) {
			if (d.dest[m].x == this->box[i].x && d.dest[m].y == this->box[i].y) {
				loadimage(&a, "./box_ok.png", SIZE, SIZE);
				drawImg(this->box[i].x, this->box[i].y, &a);
				status = 1;
				break;
			}
		}
		if (status == 0) {
			loadimage(&a, "./box.png", SIZE, SIZE);
			drawImg(this->box[i].x, this->box[i].y, &a);
		}
	}
}

//初始化角色数据
Person::Person() {
	ifstream ifs;
	char str[20];
    sprintf(str, "./level/%d_role.txt", level);
	ifs.open(str, ios::in);
	char tmp[20];
	int i = 0;
	while (ifs >> tmp) {
		if (i == 0) {
			this->x = atoi(tmp) * SIZE;
		}
		if (i == 1) {
			this->y = atoi(tmp) * SIZE;
		}
		i++;
	}
	ifs.close();
}

//绘制角色
void Person::Draw() {
	IMAGE a;
	loadimage(&a, "./one.png", SIZE, SIZE);
	drawImg(this->x, this->y, &a);
}

//移动
void Person::Move(Map& m,Box& b) {
	//获取人物在二维数组中的坐标
	int j = this->x / SIZE;
	int i = this->y / SIZE;
	//用来判断前面是否有箱子
	int status = 0;
	//按下移动键
	if (GetAsyncKeyState('W')) {	
		for(int n = 0; n < b.num; n++) {
			//如果前面有箱子
			if (b.box[n].x == this->x && b.box[n].y == this->y - SIZE) {
				status = 1;
				//如果箱子后面不靠墙也不靠箱子
				if (m.map[i-2][j] != WALL&&!this->IsBox(b,b.box[n].x,b.box[n].y-SIZE)) {
					b.box[n].y -= SIZE;
					this->y -= SIZE;
				}
			}
		}
		//空地移动
		if ((m.map[i - 1][j] == SPACE || m.map[i - 1][j] == DEST)&&(status!=1)) {
			this->y -= SIZE;
		}
		return;
	}
	if (GetAsyncKeyState('S') ) {	
		for (int n = 0; n < b.num; n++) {
			//如果前面有箱子
			if (b.box[n].x == this->x && b.box[n].y == this->y + SIZE) {
				status = 1;
				//如果箱子后面不靠墙也不靠箱子
				if (m.map[i + 2][j] != WALL && !this->IsBox(b, b.box[n].x, b.box[n].y + SIZE)) {
					b.box[n].y += SIZE;
					this->y += SIZE;
				}
			}
		}
		//空地移动
		if ((m.map[i + 1][j] == SPACE || m.map[i + 1][j] == DEST) && (status != 1)) {
			this->y += SIZE;
		}
		return;
	}
	if (GetAsyncKeyState('A')) {
		for (int n = 0; n < b.num; n++) {
			//如果前面有箱子
			if (b.box[n].y == this->y && b.box[n].x == this->x - SIZE) {
				status = 1;
				//如果箱子后面不靠墙也不靠箱子
				if (m.map[i][j-2] != WALL && !this->IsBox(b, b.box[n].x-SIZE, b.box[n].y )) {
					b.box[n].x -= SIZE;
					this->x -= SIZE;
				}
			}
		}
		//空地移动
		if ((m.map[i][j-1] == SPACE || m.map[i][j-1] == DEST) && (status != 1)) {
			this->x -= SIZE;
		}
		return;
	}
	if (GetAsyncKeyState('D')) {
		for (int n = 0; n < b.num; n++) {
			//如果前面有箱子
			if (b.box[n].y == this->y && b.box[n].x == this->x + SIZE) {
				status = 1; 
				//如果箱子后面不靠墙也不靠箱子
				if (m.map[i][j + 2] != WALL && !this->IsBox(b, b.box[n].x+SIZE, b.box[n].y )) {
					b.box[n].x += SIZE;
					this->x += SIZE;
				}
			}
		}
		//空地移动
		if ((m.map[i][j+1] == SPACE || m.map[i][j+1] == DEST) && (status != 1)) {
			this->x += SIZE;
		}
		return;
	}
}

//用来判断移动路径上的两个箱子是否靠在一起
bool Person::IsBox(Box& b, int x, int y) {
	for (int i = 0; i < b.num; i++) {
		if (b.box[i].x == x && b.box[i].y == y)return true;
	}
	return false;
}

//用来判断是否胜利
bool Box::IsWin(Map& m) {
	int count = 0;
	for (int i = 0; i < d.num; i++) {
		for (int j = 0; j < this->num; j++) {
			if (this->box[j].x == d.dest[i].x && this->box[j].y == d.dest[i].y) {
				count++;
			}
		}
	}
	if (count == d.num) {
		return true;
	}
	return false;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值