简单的推箱子游戏实战

news2024/11/18 6:02:02

目录

项目分析

 地图初始化

背景图片

游戏场景图片:

热键控制

 按键设置

确定人物位置

实现人物移动(非箱子,目的地)

推箱子控制

游戏结束

最终代码

合法性判断:


项目分析

墙:0,地板:1,箱子目的地:2,小人:3,箱子:4,箱子命中目标:5

 地图初始化

背景图片

#include <iostream>
#include <graphics.h>
#include <MMsystem.h>
#include <Windows.h>

using namespace std;
IMAGE BG_IMAGE;
#define WIDE  650
#define HEITH 650
//设置窗口初始化,背景
void initGraph() {
	initgraph(WIDE, HEITH);
	loadimage(&BG_IMAGE, "推箱子图片素材/blackground.bmp", WIDE, HEITH,true);//设置图片为窗口大小
	putimage(0, 0, &BG_IMAGE);
}

int main(void) {
	initGraph();


	system("pause");//设置初始化的屏幕不一闪而逝
	return 0;
}

游戏场景图片:

#define MAP_WIDE   50  //方块宽
#define MAP_HEIGTH 50  //方块高
#define MAP_ROWS   9   //数组行数
#define MAP_COLS   12  //数组列数
#define RADIO      50  //每行乘这个比例就加载一个图片
#define MAP_X      100 //图片开始地方偏移量x
#define MAP_Y      100 //图片开始地方偏移量y
enum MyEnum{
	wall,  //墙
	Floor, //地板
	des,   //目的地
	man,   //小人
	box,   //箱子
	hit,   //命中
	all    //用来表示图片数组的大小
};
IMAGE MAP_IMAGE[all];//场景图片
void map() {
	int a[9][12] = {
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,1,0,1,1,1,1,1,1,1,0,0},
		{0,1,4,1,0,2,1,0,2,1,0,0},
		{0,1,0,1,0,1,0,0,1,1,1,0},
		{0,1,0,2,0,1,1,4,1,1,1,0},
		{0,1,1,1,0,3,1,1,1,4,1,0},
		{0,1,2,1,1,4,1,1,1,1,1,0},
		{0,1,0,0,1,0,1,1,0,0,1,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
	};
	//墙:0,地板:1,箱子目的地:2,小人:3,箱子:4,箱子命中目标:5
	loadimage(&MAP_IMAGE[wall], "推箱子图片素材/wall_right.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[Floor], "推箱子图片素材/floor.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[des], "推箱子图片素材/des.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[man], "推箱子图片素材/man.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[box], "推箱子图片素材/box.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[hit], "推箱子图片素材/box.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	
	for (int i = 0; i < MAP_ROWS; i++){
		for (int j = 0; j < MAP_COLS; j++) {
			putimage( MAP_X + j*RADIO, MAP_Y + i*RADIO, &MAP_IMAGE[a[i][j]]);
		}
	}
}

热键控制

 按键设置

但是一直执行循环块很占用CPU,消耗很大很严重资源(使用sleep(),在用户没有按键的时候,CPU休息)

#define KEY_UP		'w'
#define KEY_DOWN	's'
#define KEY_LEFT	'a'
#define KEY_RIGHT	'r'
#define KEY_QUIT	'q'
#include <conio.h>
void control() {
	
	bool quit = false;
	do
	{
		if (_kbhit()) {//判断用户是否按键
			char ch = _getch();//直接从键盘获取字符,不经过输入缓冲区
			if (ch == KEY_UP) {
				//get_control(KEY_UP);
			}
			else if (ch == KEY_DOWN) {
				//get_control(KEY_DOWN);
			}
			else if (ch == KEY_LEFT) {
				//get_control(KEY_LEFT);
			}
			else if (ch == KEY_RIGHT) {
				//get_control(KEY_RIGHT);
			}
			else if (ch == KEY_QUIT) {
				quit = true;
			}
		}
    Sleep(50);//在用户没有按键的时候,CPU休息)

	} while (quit ==false);
}

确定人物位置

//实现人物行动
enum MyEnum1 {
	UP,
	DOWN,
	RIGHT,
	LEFT
};
struct position {
	int x;
	int y;
};
typedef enum MyEnum1 keybord;
typedef struct position pos;
pos MAN;
void get_control(keybord control) {
	pos next_pos, next_next_pos;
	switch (control) {
	case UP:
		next_pos.x = MAN.x - 1;
		next_next_pos.x = MAN.x - 2;
		break;
	case DOWN:
		next_pos.x = MAN.x + 1;
		next_next_pos.x = MAN.x + 2;
		break;
	case LEFT:
		next_pos.y = MAN.y - 1;
		next_next_pos.y = MAN.y - 2;
		break;
	case RIGHT:
		next_pos.y = MAN.y + 1;
		next_next_pos.y = MAN.y + 2;
		break;
	}

}
//void map()函数内需要添加

/*

if (a[i][j] == man) {//记录小人的初始位置
	MAN.x = i;
	MAN.y = j;
}

*/

实现人物移动(非箱子,目的地)

//实现小人移动
void mapChange(pos* pos, enum MyEnum prop) {
	a[pos->x][pos->y] = prop;
	putimage(MAP_X + pos->y * RADIO, MAP_Y + pos->x * RADIO, &MAP_IMAGE[prop]);
}

//在void get_control(keybord control)

/*

//小人前面如果是地板,人就前进一步,站到next_pos的位置
if (a[next_pos.x][next_pos.y] == Floor) {
	mapChange(&next_pos, man);
	mapChange(&MAN, Floor);
	MAN = next_pos;
}

*/

推箱子控制

//人前进一步是箱子则判断箱子前的道具,即next_next_pos,如果是地板和箱子目的地,推着箱子走
if (a[next_pos.x][next_pos.y] == box) {
	//下下个是地板
	if (a[next_next_pos.x][next_next_pos.y] == Floor) {
		mapChange(&next_next_pos, box);
		mapChange(&next_pos, man);
		mapChange(&MAN, Floor);
		MAN = next_pos;
		//下下个是目的地
	}else if (a[next_next_pos.x][next_next_pos.y] == des) {
		mapChange(&next_next_pos, hit);
		mapChange(&next_pos, man);
		mapChange(&MAN, Floor);
		MAN = next_pos;
	}
}

游戏结束

bool gameOver() {
	for (int i = 0; i < MAP_ROWS; i++) {
		for (int j = 0; j < MAP_COLS; j++) {
			if (a[i][j]==des) {
				return false;
			}
		}
	}
	return true;
}
void gameOverScien() {
	putimage(0, 0, &BG_IMAGE);
	settextcolor(RGB(255, 255, 0));
	settextstyle(90, 0, "微软雅黑");//这里可能会有字符集的问题,上上篇发过解决方法
	
	rectangle(300, 297, 570, 300);//设置矩形框
	outtextxy(300, 300, "游戏结束");;//添加文字

}

最终代码

#include <iostream>
#include <graphics.h>
#include <MMsystem.h>
#include <Windows.h>
#include <conio.h>

using namespace std;
IMAGE BG_IMAGE;
#define WIDE  800
#define HEITH 650

//按键
#define KEY_UP		'w'
#define KEY_DOWN	's'
#define KEY_LEFT	'a'
#define KEY_RIGHT	'd'
#define KEY_QUIT	'q'

//end按键
//实现人物行动
enum MyEnum1 {
	UP,
	DOWN,
	RIGHT,
	LEFT
};
struct position {
	int x;
	int y;
};
typedef enum MyEnum1 keybord;
typedef struct position pos;
pos MAN;

//end 人物移动
int a[9][12] = {
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,1,0,1,1,1,1,1,1,1,0,0},
		{0,1,4,1,0,2,1,0,2,1,0,0},
		{0,1,0,1,0,1,0,0,1,1,1,0},
		{0,1,0,2,0,1,1,4,1,1,1,0},
		{0,1,1,1,0,3,1,1,1,4,1,0},
		{0,1,2,1,1,4,1,1,1,1,1,0},
		{0,1,0,0,1,0,1,1,0,0,1,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
};
//道具
#define MAP_WIDE   50  //方块宽
#define MAP_HEIGTH 50  //方块高
#define MAP_ROWS   9   //数组行数
#define MAP_COLS   12  //数组列数
#define RADIO      50  //每行乘这个比例就加载一个图片
#define MAP_X      100 //图片开始地方偏移量x
#define MAP_Y      100 //图片开始地方偏移量y
enum MyEnum {
	wall,  //墙
	Floor, //地板
	des,   //目的地
	man,   //小人
	box,   //箱子
	hit,   //命中
	all    //用来表示图片数组的大小
};
IMAGE MAP_IMAGE[all];//场景图片
//end 道具

//设置窗口初始化,背景
void initGraph() {
	initgraph(WIDE, HEITH);
	loadimage(&BG_IMAGE, "推箱子图片素材/blackground.bmp", WIDE, HEITH, true);//设置图片为窗口大小
	putimage(0, 0, &BG_IMAGE);
}


void map() {
	//墙:0,地板:1,箱子目的地:2,小人:3,箱子:4,箱子命中目标:5
	loadimage(&MAP_IMAGE[wall], "推箱子图片素材/wall_right.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[Floor], "推箱子图片素材/floor.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[des], "推箱子图片素材/des.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[man], "推箱子图片素材/man.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[box], "推箱子图片素材/box.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);
	loadimage(&MAP_IMAGE[hit], "推箱子图片素材/box.bmp", MAP_WIDE, MAP_HEIGTH, TRUE);

	for (int i = 0; i < MAP_ROWS; i++) {
		for (int j = 0; j < MAP_COLS; j++) {
			if (a[i][j] == man) {//记录小人的初始位置
				MAN.x = i;
				MAN.y = j;
			}
			putimage(MAP_X + j * RADIO, MAP_Y + i * RADIO, &MAP_IMAGE[a[i][j]]);
		}
	}
}
//实现小人移动
void mapChange(pos* pos, enum MyEnum prop) {
	a[pos->x][pos->y] = prop;
	putimage(MAP_X + pos->y * RADIO, MAP_Y + pos->x * RADIO, &MAP_IMAGE[prop]);
}
void get_control(keybord control) {
	pos next_pos = MAN, next_next_pos=MAN;
	switch (control) {
	case UP:
		next_pos.x = MAN.x - 1;
		next_next_pos.x = MAN.x - 2;
		break;
	case DOWN:
		next_pos.x = MAN.x + 1;
		next_next_pos.x = MAN.x + 2;
		break;
	case LEFT:
		next_pos.y = MAN.y - 1;
		next_next_pos.y = MAN.y - 2;
		break;
	case RIGHT:
		next_pos.y = MAN.y + 1;
		next_next_pos.y = MAN.y + 2;
		break;
	}
	
	//小人前面如果是地板,人就前进一步,站到next_pos的位置
	if (a[next_pos.x][next_pos.y] == Floor) {//做合法性判断
		mapChange(&next_pos, man);
		mapChange(&MAN, Floor);
		MAN = next_pos;
	}
	//人前进一步是箱子则判断箱子前的道具,即next_next_pos,如果是地板和箱子目的地,推着箱子走
	if (a[next_pos.x][next_pos.y] == box) {
		//下下个是地板
		if (a[next_next_pos.x][next_next_pos.y] == Floor) {
			mapChange(&next_next_pos, box);
			mapChange(&next_pos, man);
			mapChange(&MAN, Floor);
			MAN = next_pos;
			//下下个是目的地
		}else if (a[next_next_pos.x][next_next_pos.y] == des) {
			mapChange(&next_next_pos, hit);
			mapChange(&next_pos, man);
			mapChange(&MAN, Floor);
			MAN = next_pos;
		}
	}
	
}
bool gameOver() {
	for (int i = 0; i < MAP_ROWS; i++) {
		for (int j = 0; j < MAP_COLS; j++) {
			if (a[i][j]==des) {
				return false;
			}
		}
	}
	return true;
}
void gameOverScien() {
	putimage(0, 0, &BG_IMAGE);
	settextcolor(RGB(255, 255, 0));
	settextstyle(90, 0, "微软雅黑");//这里可能会有字符集的问题,上上篇发过解决方法
	
	rectangle(300, 297, 570, 300);//设置矩形框
	outtextxy(300, 300, "游戏结束");;//添加文字

}
void control() {
	bool quit = false;
	do{
		if (_kbhit()) {//判断用户是否按键
			char ch = _getch();//直接从键盘获取字符,不经过输入缓冲区
			if (ch == KEY_UP) {
				get_control(UP);
			}
			else if (ch == KEY_DOWN) {
				get_control(DOWN);
			}
			else if (ch == KEY_LEFT) {
				get_control(LEFT);
			}
			else if (ch == KEY_RIGHT) {
				get_control(RIGHT);
			}
			else if (ch == KEY_QUIT) {
				quit = true;
			}
			if (gameOver()) {
				gameOverScien();
			}
		}
		Sleep(50);
	} while (quit ==false);
}
int main(void) {
	//初始化
	initGraph();
	//加载场景图片
	map();
	//实现热键控制人物
	control();

	system("pause");//设置初始化的屏幕不一闪而逝
	return 0;
}

合法性判断:

#define isValues(pos) (pos.x>=0 &&pos.x<MAP_COLS &&pos.y>=0&&pos.y<MAP_ROWS)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1395819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开发实践6_缓存^中间件

以下学习 朔宁夫 开发工程师 课程。 缓存可提高程序响应速度。数据库缓存(可过期)/ Redis缓存(Key:Value)/ Memcacheed缓存/ 程序层缓存。 一 缓存 1. 数据库缓存 创建缓存数据表 // python manage.py createcachetable cache_table setting // # 缓存配置 CACHES {def…

怎么样的布局是符合可制造性的PCB布局?

满足可制造性、可装配性、可维修性要求&#xff0c;方便调试的时候于检测和返修&#xff0c;能够方便的拆卸器件&#xff1a; 1&#xff09;极性器件的方向不要超过2种&#xff0c;最好都进行统一方向等要求&#xff0c;如图1-1所示&#xff1b; 图1-1 极性器件方向统一摆放 2…

【C语言】ipoib模块 - ipoib_send_rss函数

一、ipoib_send_rss函数定义 int ipoib_send_rss(struct net_device *dev, struct sk_buff *skb,struct ib_ah *address, u32 dqpn) {struct ipoib_dev_priv *priv ipoib_priv(dev);struct ipoib_tx_buf *tx_req;struct ipoib_send_ring *send_ring;u16 queue_index;int hlen…

SQL Povit函数使用及实例

PIVOT函数常用于数据的行转列&#xff0c;同时也可以用此函数实现类似于Excel中的数据透视表的效果。 PIVOT函数 PIVOT 函数的基本语法如下&#xff1a; -- PIVOT 语法 SELECT <非透视的列>,[第一个透视的列] AS <列名称>,[第二个透视的列] AS <列名称>,.…

Oracle 数据库备份与恢复的重要性与最佳实践

文章目录 一、备份的重要性二、备份工具-RMAN四、比较备份策略五、实例恢复六、完全恢复与不完全恢复七、备份与恢复脚本 引言&#xff1a; 在现代信息时代&#xff0c;数据已成为组织和企业最重要的资产之一。保护和恢复数据的能力对于确保业务连续性和减少潜在风险至关重要。…

探索 2024 年新副业:无人饮品机的新风向

随着科技的迅猛发展&#xff0c;无人饮品机作为一种全新的商业模式&#xff0c;正逐渐成为 2024 年副业的新风向。如果你还没有了解过这种全新的副业&#xff0c;那么现在是时候深入了解一下了。 D咖无人饮品机的优势在于其 24 小时不间断的营业模式&#xff0c;它可以在你睡觉…

【成功案例】首日ROI超70%!ROI目标超150%!看 NetMarvel如何助力棋牌游戏出海?

今天无论是线上线下&#xff0c;中国游戏广告在海外市场上屡见不鲜&#xff0c;甚至还会出现包场式营销&#xff0c;“中国人敢花钱”的印象已经深入人心&#xff0c;特别是休闲游戏的爆发给众多众多厂商带来新的增长机遇&#xff0c;大家花钱的态势更猛了。 棋牌类属于休闲体…

以后要做GIS开发的话是学GIS专业还是学计算机专业好一些?

GIS开发其实严格来说分为前后端以及底层开发。不同的方向&#xff0c;代表了不同的开发语言。 所以大家首先要了解自己具体要做的岗位类型是什么&#xff0c;其次才是选择专业侧重点。 但是严格来说&#xff0c;选择某个专业&#xff0c;到就业方向这个过程&#xff0c;并不是…

大疆笔试题目(2023-08-13)

1. 输出无重复3位数 时间限制&#xff1a; 3000MS 内存限制&#xff1a; 65536KB 题目描述&#xff1a; 从{1,2,3,4,5,6,7,8,9}中随机挑选不重复的5个数字作为输入数组’selectedDigits’&#xff0c;能组成多少个互不相同且无重复数字的3位数&#xff1f;请编写程序&#xff…

大创项目推荐 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

基于小波多普勒变换的回波信号检测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1小波变换基础 4.2 多普勒效应与多普勒变换 4.3 小波多普勒变换 4.4 回波信号检测 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 %回波…

QT自定义控件0-360°刻度尺

支持0到360&#xff0c;360到0的过度。 直接上代码&#xff0c;可以直接用&#xff0c;使用的paintevent事件实现的&#xff0c;没啥好讲的。 .cpp void Widget::drawCourse(QPainter& p,QPen pen,QFont font) {double currentNumber m_ang;p.setBrush(Qt::black);p.dra…

Docker-02-镜像项目部署

Docker-02-镜像&项目部署 文章目录 Docker-02-镜像&项目部署一、镜像①&#xff1a;镜像结构②&#xff1a;Dockerfile③&#xff1a;构建镜像01&#xff1a;构建02&#xff1a;查看镜像列表03&#xff1a;运行镜像 二、网络①&#xff1a;容器的网络IP地址②&#xff…

【动态规划】【二分查找】【C++算法】730. 统计不同回文子序列

作者推荐 【动态规划】【数学】【C算法】18赛车 涉及知识点 动态规划 二分查找 LeetCode730. 统计不同回文子序列 给你一个字符串 s &#xff0c;返回 s 中不同的非空回文子序列个数 。由于答案可能很大&#xff0c;请返回对 109 7 取余 的结果。 字符串的子序列可以经由…

PGSQL主键序列

PostgreSQL和 MySQL数据库还是有一定的区别。 下面了解一下 PGSQL的主键序列。 一、主键 1、系统自带主键序列 在 PostgreSQL 中&#xff0c;GENERATED BY DEFAULT 和 GENERATED ALWAYS 是用于定义自动生成的列&#xff08;Generated Column&#xff09;的选项。一般可作用…

可达性分析

可达性分析 这个算法的基本思路就是通过 一系列称为“GC Roots”的根对象作为起始节点集&#xff0c;从这些节点开始&#xff0c;根据引用关系向下搜索&#xff0c;搜索过 程所走过的路径称为“引用链”&#xff08;Reference Chain&#xff09;&#xff0c;如果某个对象到GC …

数学建模--比赛

内容来自数学建模BOOM&#xff1a;【快速入门】北海&#xff1a;数模建模基础MATLAB入门论文写作数学模型与算法(推荐数模美赛国赛小白零基础必看教程)_哔哩哔哩_bilibili 目录 1.学习内容 2.参赛须知 1&#xff09;参赛作品的组成 2)参赛作品的提交 3.软件安装 4.注意…

Electron中苹果支付 Apple Pay inAppPurchase 内购支付

正在开发中&#xff0c;开发好了&#xff0c;写一个完整详细的过程&#xff0c;保证无脑集成即可 一、先创建一个App 一般情况下&#xff0c;在你看这篇文章的时候&#xff0c;说明你已经开发的app差不多了。 但是要上架app到Mac App Store&#xff0c;则要在appstoreconnect…

pyspark 笔记:窗口函数window

窗口函数相关的概念和基本规范可以见&#xff1a;pyspark笔记&#xff1a;over-CSDN博客 1 创建Pyspark dataFrame from pyspark.sql.window import Window import pyspark.sql.functions as F employee_salary [("Ali", "Sales", 8000),("Bob&qu…

UI自动化Selenium 无头模式运行

1、导入浏览器参数设置 from selenium.webdriver.chrome.options import Options 2、创建参数&#xff0c;并使用无厘头模式创建driver对象 opt Options() # 新建参数对象 opt.add_argument("--headless") # 无头 self.driver webdriver.Chrome(optionsopt) …