IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c语言之推箱子功能汇总 -> 正文阅读

[C++知识库]c语言之推箱子功能汇总

前言
先说说我写推箱子小游戏的过程。
第一版:没有图形化界面,不能选关。只有推箱子的最基础功能。
第二版:增加图形化界面,但是不能选择关卡。
最终版:增加选择关卡功能、播放/关闭音乐功能、退出游戏功能,捕获鼠标功能。

首先看一下最终版效果图
请添加图片描述
功能点分析:
打开/关闭音乐和退出游戏比较简单。
打开音乐所需调用的头文件

#include <graphics.h> //调用easyx图形库时所需增加的头文件
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")  //静态库资源

打开音乐调用的easyx内部函数

mciSendString("open 1.mp3", 0, 0, 0);//播放存放c代码同一路径的1.mp3音乐
mciSendString("play 1.mp3", 0, 0, 0);//循环播放音乐资源

关闭音乐调用的easyx内部函数

mciSendString("close 1.mp3", 0, 0, 0);

退出游戏功能:直接找一个图片,当鼠标点击退出游戏这个区域,那么就显示该退出游戏的图片,并退出控制台。

选择关卡可以用三维数组:
三维数组可以理解为多个二维数组。例如map[3][10][10]表示有三个10x10的二维数组。当我点击关卡1,那么就打印map[1][10][10]这个区域的地图。关卡二和关卡三类似。

捕获鼠标信息:

easyx图形库给我们提供了鼠标捕获函数getmessage(EM_MOUSE)。以及保存鼠标消息结构体:

// 鼠标消息的数据
struct
{
	bool ctrl		:1;		// Ctrl 键是否按下
	bool shift		:1;		// Shift 键是否按下
	bool lbutton	:1;		// 鼠标左键是否按下
	bool mbutton	:1;		// 鼠标中键是否按下
	bool rbutton	:1;		// 鼠标右键
	short x;				// 鼠标的 x 坐标
	short y;				// 鼠标的 y 坐标
	short wheel;			// 鼠标滚轮滚动值,为 120 的倍数
};

整体代码:

/*
问题:为什么通过一关后,再重新进入的话会进不去?也可以说闪退。
	因为如果箱子已经到目的地了,那么就不会进入while(!gamePass())这个while循环里面。
*/
#include <stdio.h>
#include <conio.h>  //键盘输入函数库
#include <stdlib.h> //这个头文件包含了清屏函数system("cls");
#include <graphics.h> //调用easyx图形库时所需增加的头文件
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")  //静态库资源

int flag;//0表示关卡1,1表示关卡2,2表示关卡3
EASYXMSG  m; // 定义消息变量
	
int map[3][10][10] = 
  {                  
	  1,1,1,1,1,1,1,1,1,1,
       1,0,0,0,0,0,3,0,0,1,
       1,0,0,5,4,0,0,0,0,1,
       1,0,0,1,1,0,0,0,0,1,
       1,0,1,0,0,0,1,0,0,1,
       1,0,0,4,0,0,1,0,0,1,
       1,0,0,0,0,0,0,0,0,1,
       1,0,0,3,0,0,0,0,0,1,
       1,0,0,0,0,0,0,0,0,1,
       1,1,1,1,1,1,1,1,1,1,
	  //关卡1

	  
	   1,1,1,1,1,1,1,1,1,1,
       1,0,0,1,0,0,0,0,0,1,
       1,0,0,1,4,0,3,0,0,1,
       1,0,0,0,0,0,0,0,0,1,
       1,0,1,0,0,0,1,0,0,1,
       1,0,1,4,0,0,1,0,0,1,
       1,0,1,0,0,0,0,0,0,1,
       1,3,0,0,0,0,5,0,0,1,
       1,0,0,0,0,0,0,0,0,1,
       1,1,1,1,1,1,1,1,1,1,//关卡2

	   1,1,1,1,1,1,1,1,1,1,
       1,1,0,0,1,1,0,0,0,1,
       1,1,0,4,0,0,0,0,0,1,
       1,1,0,1,1,0,0,0,0,1,
       1,0,0,0,0,0,1,0,3,1,
       1,0,0,4,0,0,1,0,0,1,
       1,0,0,0,0,0,0,4,1,1,
       1,0,0,3,0,5,0,0,1,1,
       1,0,0,0,0,0,0,3,0,1,
       1,1,1,1,1,1,1,1,1,1,//关卡3
	  
	  
 };




IMAGE img[9];		//9张图片,9个名字
void loadResource()
{
	loadimage(img + 0, "0.bmp", 50, 50);//50表示图片长宽,可以自己调的
	loadimage(img + 1, "1.bmp", 50, 50);
	loadimage(img + 2, "3.bmp", 50, 50);
	loadimage(img + 3, "4.bmp", 50, 50);
	loadimage(img + 4, "5.bmp", 50, 50);
	loadimage(img + 5, "7.bmp", 50, 50);
	loadimage(img + 6, "8.jpeg", 500, 200);
	loadimage(img + 7, "9.jfif", 500, 500);//退出游戏
	loadimage(img + 8, "10.jfif", 500, 500);//恭喜过关
}




void Printmap()
{
	int i,j;

		for (i = 0; i < 10; i++)
		{
			for (j = 0; j < 10; j++)
			{
			int x,y;
			x =  j* 50;
			y =  i* 50;
			switch (map[flag][i][j])
			{             
			//0:空地 1:墙 3:箱子要放的位置 4:箱子 5:人   7:箱子到达目的地       8:人到达目的地
			/*case 0: printf("  "); break;
			case 1: printf("■"); break;
			case 3: printf("☆"); break;
			case 4: printf("□"); break;

			case 5:
			case 8:
				printf("♀");
				break;
			case 7: printf("★"); break;
			*/
			case 0: putimage(x, y, img + 0); break; //把图片打印在控制台,从坐标点x,y开始显示图片
			case 1: putimage(x, y, img + 1); break;
			case 3: putimage(x, y, img + 2); break;
			case 4: putimage(x, y, img + 3); break;

			case 5:
			case 8: putimage(x, y, img + 4); break; 

			case 7: putimage(x, y, img + 5); break;
			default:
				break;
				}
			}	

		printf("\n");
	}
}


void PlayGame()
{
    char temp;
    //遍历整个地图,找到人所在的坐标,并把坐标值赋给i,j这两个变量。
    int x,y;
    int i,j;
    for(x=0;x<10;x++)
    {
        for(y=0;y<10;y++)
        {
            if(map[flag][x][y] == 5 || map[flag][x][y] == 8)
            {
                i=x;
                j=y;
            }
        }
    }

    temp = _getch();//键盘输入无回显函数

    switch (temp)
    {
        case 'W':
		case 'w':
        if (map[flag][i - 1][j] == 0 || map[flag][i - 1][j] == 3) //如果下一步是空地 或者是 箱子要放的位置
        {
            map[flag][i][j] -= 5;
            map[flag][i - 1][j] += 5;
        }
        if (map[flag][i - 1][j] == 4 || map[flag][i - 1][j] == 7)//如果下一步是箱子 或者是 箱子到达目的地
        {
            if (map[flag][i - 2][j] == 0 || map[flag][i - 2][j] == 3)//如果继续下一步是空地 或者是 箱子要放的位置
            {
                map[flag][i][j] -= 5;
                map[flag][i - 1][j] += 1;
                map[flag][i - 2][j] += 4;
            }
        }
        break;

		case 'S':
		case 's':
        if (map[flag][i + 1][j] == 0 || map[flag][i + 1][j] == 3)
        {
            map[flag][i][j] -= 5;
            map[flag][i + 1][j] += 5;
        }
        if (map[flag][i + 1][j] == 4 || map[flag][i + 1][j] == 7)
        {
            if (map[flag][i + 2][j] == 0 || map[flag][i + 2][j] == 3)
            {
                map[flag][i][j] -= 5;
                map[flag][i + 1][j] += 1;
                map[flag][i + 2][j] += 4;
            }
        }
        break;

		case 'A':
		case 'a':
        if (map[flag][i][j - 1] == 0 || map[flag][i][j - 1] == 3)
        {
            map[flag][i][j] -= 5;
            map[flag][i][j - 1] += 5;
        }
        if (map[flag][i][j - 1] == 4 || map[flag][i][j - 1] == 7)
        {
            if (map[flag][i][j - 2] == 0 || map[flag][i][j - 2] == 3)
            {
                map[flag][i][j] -= 5;
                map[flag][i][j - 1] += 1;
                map[flag][i][j - 2] += 4;
            }
        }
        break;

		case 'D':
		case 'd':
        if (map[flag][i][j + 1] == 0 || map[flag][i][j + 1] == 3)
        {
            map[flag][i][j] -= 5;
            map[flag][i][j + 1] += 5;
        }
        if (map[flag][i][j + 1] == 4 || map[flag][i][j + 1] == 7)
        {
            if (map[flag][i][j + 2] == 0 || map[flag][i][j + 2] == 3)
            {
                map[flag][i][j] -= 5;
                map[flag][i][j + 1] += 1;
                map[flag][i][j + 2] += 4;
            }
        }
        break;

    default:
        break;
    }
}



int gamePass() //游戏通关
{
    //地图上没有箱子就可以结束
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            if (map[flag][i][j] == 4)
            {
                return 0;
            }
        }
    }
    return 1;
}


void draw_initgraph()//游戏首页界面
{
	initgraph(500, 500);//创建一个大小为500 x 500 的窗口
	loadResource();//加载资源函数
	putimage(0, 0, &img[6]);//图1的左上角的顶点为(0,0)	
    setbkmode(TRANSPARENT);	//设置填制背景为透明,这样填充文字时背景才是图片的颜色                    
    //在左上角坐标为(x,y)处输出文字
	//outtextxy(215, 50, "推箱子");			
	outtextxy(120, 250, "关卡1");
	outtextxy(240, 250, "关卡2");
	outtextxy(360, 250, "关卡3");
	outtextxy(105, 300, "打开音乐");
	outtextxy(105, 350, "关闭音乐");
	outtextxy(345, 350, "退出游戏");

    //在左上角(x1,y1)和右下角(x2,y2)范围画一个矩形,这个是设置的鼠标点击各按键时的范围
	rectangle(100, 245, 175, 270);//关卡1				
	rectangle(220, 245, 295, 270);//关卡2	
	rectangle(340, 245, 415, 270);//关卡3	
	rectangle(100, 295, 175, 320);//打开音乐
	//rectangle(390, 295, 465, 320);
	rectangle(100, 345, 175, 370);//关闭音乐
	rectangle(340, 345, 415, 370);//退出游戏

}

int  main()
{	
level:
	draw_initgraph();

    while (1)
    {
		m = getmessage(EM_MOUSE);//获取鼠标信息

		if (m.x >= 100 && m.x <= 175 && m.y >= 295 && m.y <= 320) 
		{//如果光标在打开音乐
			setlinecolor(RED);
			rectangle(95, 290, 180, 325);
			if (m.lbutton) 
			{		//如果按下鼠标左键实现相应功能.
				mciSendString("open 1.mp3", 0, 0, 0);//播放音乐
				mciSendString("play 1.mp3", 0, 0, 0);//循环播放音乐资源
			}
		}

		else if(m.x >= 100 && m.x <= 175 && m.y >= 345 && m.y <= 370)
		{//如果光标在关闭音乐
			setlinecolor(RED);
			rectangle(95, 340, 180, 375);
			if (m.lbutton) 
			{		//如果按下鼠标左键实现相应功能.
				mciSendString("close 1.mp3", 0, 0, 0);//关闭音乐
			}
		}

		else if(m.x >= 340 && m.x <= 415 && m.y >= 345 && m.y <= 370)
		{//如果光标在退出游戏
			setlinecolor(RED);
			rectangle(335, 340, 420, 375);
			if (m.lbutton) 
			{		//如果按下鼠标左键实现相应功能.
					putimage(0, 0, &img[7]);//图3的左上角的顶点为(0,0)
					Sleep(2000);
					closegraph();
					break;
			}
		}

		else if(m.x >= 100 && m.x <= 175 && m.y >= 245 && m.y <= 270)
		{//如果光标在关卡1
			setlinecolor(RED);
			rectangle(95, 240, 180, 275);
			flag = 0;
			if (m.lbutton) 
			{		//如果按下鼠标左键实现相应功能.	
							
				while(!gamePass())
				{				
					Printmap();
					PlayGame();
					system("cls");
				}
				putimage(0, 0, &img[8]);//图3的左上角的顶点为(0,0)
				Sleep(1500);
				goto level;
			}
		}

		else if(m.x >= 220 && m.x <= 295 && m.y >= 245 && m.y <= 270)
		{//如果光标在关卡2

			setlinecolor(RED);
			rectangle(215, 240, 300, 275);
			flag = 1;
			if (m.lbutton) 
			{		//如果按下鼠标左键实现相应功能.
				while(!gamePass())
				{			
					Printmap();
					PlayGame();
					system("cls");
				}
				putimage(0, 0, &img[8]);//图3的左上角的顶点为(0,0)
				Sleep(1500);
				goto level;
			}
		}


		else if(m.x >= 340 && m.x <= 415 && m.y >= 245 && m.y <= 270)
		{//如果光标在关卡3

			setlinecolor(RED);
			rectangle(335, 240, 420, 275);
			flag = 2;
			if (m.lbutton) 
			{		//如果按下鼠标左键实现相应功能.
				while(!gamePass())
				{					
					Printmap();
					PlayGame();
					system("cls");
				}
				putimage(0, 0, &img[8]);//图3的左上角的顶点为(0,0)
				Sleep(1500);
				goto level;
			}
		}

		else
		{	//当鼠标不在目标位置就用背景色覆盖之前的蓝色边框.
			setlinecolor(BLACK);	
			rectangle(95, 290, 180, 325);

			setlinecolor(BLACK);	
			rectangle(95, 340, 180, 375);

			setlinecolor(BLACK);	
			rectangle(335, 340, 420, 375);			
			
			setlinecolor(BLACK);	
			rectangle(95, 240, 180, 275);

			setlinecolor(BLACK);	
			rectangle(215, 240, 300, 275);

			setlinecolor(BLACK);	
			rectangle(335, 240, 420, 275);
		}
    }





	//closegraph();//关闭窗口
 
	return 0;    
}



ps:这里面需要用到的图片和音乐素材可以自己寻找,也可以在评论区留下邮箱我看到了就发给你。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:03:37  更:2021-08-09 10:05:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 19:18:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码