目录

设计一个简单的推箱子游戏

功能设计要求:

代码实现

数据定义头文件data_def.h

窗口设置头文件WindowsSet.h

WindowsSet.cpp

上移函数

矩阵旋转函数

游戏帧

菜单设置

总代码

main函数

成果

设计一个简单的推箱子游戏

该游戏是通过控制人的走向来移动箱子,箱子只能向前推,不能向后拉,且一次只能推动一个箱子。

功能设计要求:

  1. 人机操控平台:启动程序后,系统提供给用户一个操作界面,以便用户有效操作游戏。
  2. 创建并绘制地图:推箱子游戏需要创建不同的地图以增加游戏的趣味性。
  3. 选择地图:系统应提供两个及以上不同难度的地图以供用户选择。
  4. 移动操作:本游戏主要通过人或人和箱子的移动来进行的。系统接收用户输入一个字符(按键)来控制人的走向,并且可以在允许的情况下推动箱子。
  5. 移动步数和得分:移动步数是统计从开始游戏到游戏结束(通关)所走的总步数,在游戏过程中这是实时变化的。得分是统计每将一个箱子移动到目的地所获得的分数,只有当把所有箱子移动到指定目标位置后游戏结束(通关)。
  6. 游戏操作说明:系统给用户提供地图元素组成、操作规则等信息

代码实现

基础代码在用C语言实现推箱子小游戏基础程序_Cheat_Meric的博客-CSDN博客中实现。

在用C语言实现推箱子小游戏基础程序_Cheat_陈十一的博客-CSDN博客中的解释较为详细细致,在这里不再对代码进行过多的解释,下面直接介绍代码。

在上一代码的基础上,增加了菜单界面以及关卡选择

在上一代码中提出的代码优化中,提出的旋转矩阵+上移操作以达成左右下移操作,在编写程序过程中发现虽然代码量减少,但是运行时长是之前的数十倍。

数据定义头文件data_def.h

#ifndef __DATA_DEF_H__
#define __DATA_DEF_H__#define Box_Size 60
#define Box_Num 9
#define Round_Num 3//记录玩家位置
struct Player
{int x;int y;
};
Player player;enum Element { empty, wall, role, target, box, achieve, data_bg, role_target };
//1表示墙,0表示空地,2表示玩家位置,3目标位置,4箱子位置,5表示achieve,6表示data_bg,7表示role_target
int origin_Round[Round_Num][Box_Num][Box_Num + 1] = {{{1,1,1,1,1,1,1,1,1,6},{1,1,0,0,0,1,1,1,1,6},{1,1,0,0,0,1,0,0,1,6},{1,1,1,0,0,0,0,3,1,6},{1,1,1,0,1,1,1,3,1,6},{1,0,4,0,1,1,1,3,1,6},{1,0,4,4,1,1,1,1,1,6},{1,2,0,0,1,1,1,1,1,6},{1,1,1,1,1,1,1,1,1,6},},{{1,1,1,1,1,1,1,1,1,6},{1,1,1,3,3,5,3,1,1,6},{1,1,1,3,4,0,0,1,1,6},{1,1,1,1,0,4,0,1,1,6},{1,1,1,1,4,0,1,1,1,6},{1,1,1,2,4,0,1,1,1,6},{1,1,1,1,0,0,0,1,1,6},{1,1,1,1,1,1,1,1,1,6},},{{1,1,1,1,1,1,1,1,1,6},{1,1,target,0,0,0,box,0,1,6},{1,1,target,box,0,0,1,0,1,6},{1,1,target,1,0,1,0,0,1,6},{1,1,1,1,0,1,0,1,1,6},{1,1,1,0,box,0,0,1,1,6},{1,1,1,role,0,1,1,1,1,6},{1,1,1,1,1,1,1,1,1,6},},
};
//last_step[Box_Num][Box_Num + 1]用于悔棋,记录上一步操作
//First_Round[Box_Num][Box_Num + 1]每一关的矩阵
int last_step[Box_Num][Box_Num + 1], First_Round[Box_Num][Box_Num];/*
* targetNum目标数量
* achievementNum箱子推到目标的成功数量
* steps记录步数
* level当前关卡
*/
int targetNum = 0, achievementNum = 0, steps, level;/*
* Menu_Opt菜单选择
* Begin开始游戏的flag
* quit_flag退出判定
*/
int Menu_Opt = 0, Begin = 0, quit_flag = 0;
#endif // !__DATA_DEF_H__

一些会用到的数据的定义,由于origin_Round关卡数组比较多,所以单独存放在一个头文件中。

窗口设置头文件WindowsSet.h

#ifndef __WINDOWSSET_H__
#define __WINDOWSSET_H__#ifndef __DATA_DEF_H__
#define __DATA_DEF_H__
#include "data_def.h"
#endif // !__DATA_DEF_H__int check_lose_win(void);//检查游戏是否结束
void Windows_Init(void);//窗口初始化
void Windows_Show(void);//展示游戏窗口
void Flash_Frame(void);//游戏帧轮询
void Next_Round(void);//下一关
void Start_Up(void);//开始界面
void clear_opt(void);//菜单界面选择的覆盖,覆盖之前的'@'
void Menu_Flash_Frame(void);//菜单界面帧
void matrix_up(void);//上移操作
void matrix_rotate(int m);//矩阵顺时针旋转m次#endif // !__WINDOWSSET_H__

WindowsSet.cpp

可以直接跳到最后一条总代码页看总代码

上移函数

//上移操作
void matrix_up(void)
{int role_x, role_y;role_x = player.x - 1;if (First_Round[role_x][player.y] == empty){if (First_Round[player.x][player.y] == role)//如果此处是roleFirst_Round[player.x][player.y] = empty;else//如果此处是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role;player.x = role_x;steps++;}else if (First_Round[role_x][player.y] == target){if (First_Round[player.x][player.y] == role)//如果此处是roleFirst_Round[player.x][player.y] = empty;else//如果此处是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role_target;player.x = role_x;steps++;}else if ((First_Round[role_x][player.y] == box || First_Round[role_x][player.y] == achieve) && (First_Round[role_x - 1][player.y] == empty || First_Round[role_x - 1][player.y] == target))//判断有wall{if (First_Round[role_x][player.y] == box){if (First_Round[player.x][player.y] == role)//如果此处是roleFirst_Round[player.x][player.y] = empty;else//如果此处是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role;player.x = role_x;if (First_Round[role_x - 1][player.y] == target)//如果box和target重叠,合为achieve{First_Round[role_x - 1][player.y] = achieve;achievementNum++;}elseFirst_Round[role_x - 1][player.y] = box;}else if (First_Round[role_x][player.y] == achieve){achievementNum--;if (First_Round[player.x][player.y] == role)//此位置是玩家位置First_Round[player.x][player.y] = empty;//此位置变为空else //此位置是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role_target; //将box从target中推走,则此位置变成role_targetplayer.x = role_x;if (First_Round[role_x - 1][player.y] == target)//如果box和target重叠,合为achieve{First_Round[role_x - 1][player.y] = achieve;achievementNum++;}elseFirst_Round[role_x - 1][player.y] = box;}steps++;}
}

矩阵旋转函数

player结构体也要随着矩阵的旋转而旋转

可以看到旋转矩阵操作要遍历多次数组

顺时针旋转m阶矩阵就是将a[i][j]放在(j,m-i-1)处,所以使用temp来进行临时存储。

这里也可以将matrix_rotate函数化为左移右移和下移函数

#左移函数:行列交换后进行上移操作再换回

#下移函数:按行倒序

#右移函数:行列交换后的下移操作

代码量比上一程序少且比这一程序的时间少,属于折中。

//矩阵顺时针旋转m次
//那么左移旋转1次,右移旋转3次,下移旋转2次
void matrix_rotate(int m)
{int temp[Box_Num][Box_Num];int temp_player_x, temp_player_y;for (int i = 0; i < m; i++)//旋转次数{for (int j = 0; j < Box_Num; j++)//行{for (int k = 0; k < Box_Num; k++)//列{temp[k][Box_Num - j - 1] = First_Round[j][k];}}for (int j = 0; j < Box_Num; j++){for (int k = 0; k < Box_Num; k++){First_Round[j][k] = temp[j][k];}}temp_player_x = player.y;temp_player_y = Box_Num - player.x - 1;player.x = temp_player_x;player.y = temp_player_y;}
}

游戏帧

        相应的,Flash_Frame函数的代码量显著减少

//游戏帧,轮询键盘
void Flash_Frame(void)
{char input;//_kbhit检查当前是否有键盘输入,若有则返回一个非0值,否则返回0if (_kbhit()){input = _getch();switch (input){case('w')://上移matrix_up();break;case('s')://下移matrix_rotate(2);matrix_up();matrix_rotate(2);break;case('a')://左移matrix_rotate(1);matrix_up();matrix_rotate(3);break;case('d')://右移matrix_rotate(3);matrix_up();matrix_rotate(1);break;case('r')://重玩Windows_Init();break;default:break;}}
}

菜单设置

菜单设置还是用到基础的操作

//菜单界面
//暂未实现作者信息功能
void Start_Up(void)
{//背景色setfillcolor(RGB(255, 255, 255));fillrectangle(0, 0, Box_Num * Box_Size + 200, Box_Num * Box_Size);//菜单界面方块按钮样式setfillcolor(RGB(0x6f,0xf6,0xeb));setlinecolor(RGB(150, 150, 150));fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2 - 120, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 - 70);fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2 - 60, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 - 10);fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 + 50);fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2 + 60, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 + 110);settextstyle(20, 0, _T("宋体"));outtextxy(Box_Size * Box_Num + 5, Box_Num * Box_Size / 2 + 150, _T("确定:空格"));//菜单界面的展示wchar_t level_str[3];setbkmode(OPAQUE);settextcolor(RGB(0, 0, 0));settextstyle(40, 0, _T("宋体"));_stprintf_s(level_str, _T("%d"), level+1);outtextxy(Box_Size * Box_Num/2 + 30, Box_Num * Box_Size / 2 - 115, _T("开始游戏"));outtextxy(Box_Size * Box_Num / 2 + 30, Box_Num * Box_Size / 2 - 55, _T("关卡选择"));outtextxy(Box_Size * Box_Num - 40, Box_Num * Box_Size / 2 - 55, level_str);outtextxy(Box_Size * Box_Num / 2, Box_Num * Box_Size / 2 + 5, _T("查看作者信息"));outtextxy(Box_Size * Box_Num / 2 + 30, Box_Num * Box_Size / 2 + 65, _T("结束游戏"));switch (Menu_Opt)//标识选择的位置{case(0):break;case(1):outtextxy(Box_Size * Box_Num / 2 + 10, Box_Num * Box_Size / 2 - 115, _T("@"));break;case(2):outtextxy(Box_Size * Box_Num / 2 + 10, Box_Num * Box_Size / 2 - 55, _T("@"));break;case(3):outtextxy(Box_Size * Box_Num / 2 - 20, Box_Num * Box_Size / 2 + 5, _T("@"));break;case(4):outtextxy(Box_Size * Box_Num / 2 + 10, Box_Num * Box_Size / 2 + 65, _T("@"));break;default:break;}FlushBatchDraw();
}
void Menu_Flash_Frame(void)
{char input;if (_kbhit()){input = _getch();switch (input){case('w')://选择按钮上移clear_opt();Menu_Opt--;if (Menu_Opt <= 0)Menu_Opt = 4;break;case('s')://选择按钮下移clear_opt();Menu_Opt++;if (Menu_Opt > 4)Menu_Opt = 1;break;case(' ')://确定按钮switch (Menu_Opt){case(1):Begin = 1; Windows_Init(); break;//如果在'开始游戏'按钮处确定,则开始游戏case(2)://关卡选择level++;//关卡增加if (level >= Round_Num)//关卡越界则回到第一关level = 0;break;case(3):break;//作者信息界面case(4):quit_flag = 1; break;//退出程序default:break;}break;default:break;}Start_Up();}
}
//菜单界面选择的覆盖,覆盖之前的'@'
void clear_opt(void)
{switch (Menu_Opt){case(0):break;case(1):outtextxy(Box_Size * Box_Num / 2 + 20, Box_Num * Box_Size / 2 - 115, _T(" "));break;case(2):outtextxy(Box_Size * Box_Num / 2 + 20, Box_Num * Box_Size / 2 - 55, _T(" "));break;case(3):outtextxy(Box_Size * Box_Num / 2 - 10, Box_Num * Box_Size / 2 + 5, _T(" "));break;case(4):outtextxy(Box_Size * Box_Num / 2 + 20, Box_Num * Box_Size / 2 + 65, _T(" "));break;default:break;}
}

总代码

#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include "data_def.h"
#include "WindowsSet.h"//上移操作
void matrix_up(void)
{int role_x, role_y;role_x = player.x - 1;if (First_Round[role_x][player.y] == empty){if (First_Round[player.x][player.y] == role)//如果此处是roleFirst_Round[player.x][player.y] = empty;else//如果此处是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role;player.x = role_x;steps++;}else if (First_Round[role_x][player.y] == target){if (First_Round[player.x][player.y] == role)//如果此处是roleFirst_Round[player.x][player.y] = empty;else//如果此处是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role_target;player.x = role_x;steps++;}else if ((First_Round[role_x][player.y] == box || First_Round[role_x][player.y] == achieve) && (First_Round[role_x - 1][player.y] == empty || First_Round[role_x - 1][player.y] == target))//判断有wall{if (First_Round[role_x][player.y] == box){if (First_Round[player.x][player.y] == role)//如果此处是roleFirst_Round[player.x][player.y] = empty;else//如果此处是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role;player.x = role_x;if (First_Round[role_x - 1][player.y] == target)//如果box和target重叠,合为achieve{First_Round[role_x - 1][player.y] = achieve;achievementNum++;}elseFirst_Round[role_x - 1][player.y] = box;}else if (First_Round[role_x][player.y] == achieve){achievementNum--;if (First_Round[player.x][player.y] == role)//此位置是玩家位置First_Round[player.x][player.y] = empty;//此位置变为空else //此位置是role_targetFirst_Round[player.x][player.y] = target;First_Round[role_x][player.y] = role_target; //将box从target中推走,则此位置变成role_targetplayer.x = role_x;if (First_Round[role_x - 1][player.y] == target)//如果box和target重叠,合为achieve{First_Round[role_x - 1][player.y] = achieve;achievementNum++;}elseFirst_Round[role_x - 1][player.y] = box;}steps++;}
}//矩阵顺时针旋转m次
//那么左移旋转1次,右移旋转3次,下移旋转2次
void matrix_rotate(int m)
{int temp[Box_Num][Box_Num];int temp_player_x, temp_player_y;for (int i = 0; i < m; i++)//旋转次数{for (int j = 0; j < Box_Num; j++)//行{for (int k = 0; k < Box_Num; k++)//列{temp[k][Box_Num - j - 1] = First_Round[j][k];}}for (int j = 0; j < Box_Num; j++){for (int k = 0; k < Box_Num; k++){First_Round[j][k] = temp[j][k];}}temp_player_x = player.y;temp_player_y = Box_Num - player.x - 1;player.x = temp_player_x;player.y = temp_player_y;}
}//菜单界面选择的覆盖,覆盖之前的'@'
void clear_opt(void)
{switch (Menu_Opt){case(0):break;case(1):outtextxy(Box_Size * Box_Num / 2 + 20, Box_Num * Box_Size / 2 - 115, _T(" "));break;case(2):outtextxy(Box_Size * Box_Num / 2 + 20, Box_Num * Box_Size / 2 - 55, _T(" "));break;case(3):outtextxy(Box_Size * Box_Num / 2 - 10, Box_Num * Box_Size / 2 + 5, _T(" "));break;case(4):outtextxy(Box_Size * Box_Num / 2 + 20, Box_Num * Box_Size / 2 + 65, _T(" "));break;default:break;}
}//菜单界面帧
void Menu_Flash_Frame(void)
{char input;if (_kbhit()){input = _getch();switch (input){case('w')://选择按钮上移clear_opt();Menu_Opt--;if (Menu_Opt <= 0)Menu_Opt = 4;break;case('s')://选择按钮下移clear_opt();Menu_Opt++;if (Menu_Opt > 4)Menu_Opt = 1;break;case(' ')://确定按钮switch (Menu_Opt){case(1):Begin = 1; Windows_Init(); break;//如果在'开始游戏'按钮处确定,则开始游戏case(2)://关卡选择level++;//关卡增加if (level >= Round_Num)//关卡越界则回到第一关level = 0;break;case(3):break;//作者信息界面case(4):quit_flag = 1; break;//退出程序default:break;}break;default:break;}Start_Up();}
}//菜单界面
//暂未实现作者信息功能
void Start_Up(void)
{//背景色setfillcolor(RGB(255, 255, 255));fillrectangle(0, 0, Box_Num * Box_Size + 200, Box_Num * Box_Size);//菜单界面方块按钮样式setfillcolor(RGB(0x6f,0xf6,0xeb));setlinecolor(RGB(150, 150, 150));fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2 - 120, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 - 70);fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2 - 60, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 - 10);fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 + 50);fillrectangle(Box_Num * Box_Size / 2 - 50, Box_Num * Box_Size / 2 + 60, Box_Num * Box_Size / 2 + 300, Box_Num * Box_Size / 2 + 110);settextstyle(20, 0, _T("宋体"));outtextxy(Box_Size * Box_Num + 5, Box_Num * Box_Size / 2 + 150, _T("确定:空格"));//菜单界面的展示wchar_t level_str[3];setbkmode(OPAQUE);settextcolor(RGB(0, 0, 0));settextstyle(40, 0, _T("宋体"));_stprintf_s(level_str, _T("%d"), level+1);outtextxy(Box_Size * Box_Num/2 + 30, Box_Num * Box_Size / 2 - 115, _T("开始游戏"));outtextxy(Box_Size * Box_Num / 2 + 30, Box_Num * Box_Size / 2 - 55, _T("关卡选择"));outtextxy(Box_Size * Box_Num - 40, Box_Num * Box_Size / 2 - 55, level_str);outtextxy(Box_Size * Box_Num / 2, Box_Num * Box_Size / 2 + 5, _T("查看作者信息"));outtextxy(Box_Size * Box_Num / 2 + 30, Box_Num * Box_Size / 2 + 65, _T("结束游戏"));switch (Menu_Opt)//标识选择的位置{case(0):break;case(1):outtextxy(Box_Size * Box_Num / 2 + 10, Box_Num * Box_Size / 2 - 115, _T("@"));break;case(2):outtextxy(Box_Size * Box_Num / 2 + 10, Box_Num * Box_Size / 2 - 55, _T("@"));break;case(3):outtextxy(Box_Size * Box_Num / 2 - 20, Box_Num * Box_Size / 2 + 5, _T("@"));break;case(4):outtextxy(Box_Size * Box_Num / 2 + 10, Box_Num * Box_Size / 2 + 65, _T("@"));break;default:break;}FlushBatchDraw();
}//检查是否成功或失败
int check_lose_win(void)
{int i, j;for (i = 1; i < Box_Num - 1; i++){for (j = 1; j < Box_Num - 1; j++){if (First_Round[i][j] == box && (First_Round[i + 1][j] == wall && First_Round[i][j + 1] == wall || First_Round[i - 1][j] == wall && First_Round[i][j - 1] == wall))return 0;//loseelse if (First_Round[i][j] == box && (First_Round[i + 1][j] == wall && First_Round[i][j - 1] == wall || First_Round[i - 1][j] == wall && First_Round[i][j + 1] == wall))return 0;}}if (achievementNum == targetNum)return 1;//winreturn -1;
}/*
* 游戏界面初始化
* 用于重玩
*/
void Windows_Init(void)
{initgraph(Box_Num * Box_Size + 150, Box_Num * Box_Size);setbkcolor(RGB(255, 255, 255));BeginBatchDraw();Start_Up();int i, j;targetNum = 0;//遍历第level关关卡给first_roundfor (i = 0; i < Box_Num; i++){for (j = 0; j < Box_Num; j++){First_Round[i][j] = origin_Round[level][i][j];if (origin_Round[level][i][j] == role){player.x = i;player.y = j;}else if (origin_Round[level][i][j] == target)targetNum++;}}achievementNum = 0;steps = 0;
}//在游戏win之后可以进入下一关卡
void Next_Round(void)
{while (1){if (_kbhit()){char n;n = _getch();if (n == 'n'){level++;Windows_Init();break;}}}
}//游戏场景
void Windows_Show(void)
{int i, j;cleardevice();//遍历二维关卡数据for (i = 0; i < Box_Num; i++){for (j = 0; j < Box_Num; j++){//空格子或数据背景色if (First_Round[i][j] == empty || First_Round[i][j] == data_bg){setfillcolor(RGB(255, 255, 255));setlinecolor(RGB(255, 255, 255));fillrectangle(j * Box_Size, i * Box_Size, (j + 1) * Box_Size, (i + 1) * Box_Size);}else if (First_Round[i][j] == wall)//墙样式{setfillcolor(RGB(0x93, 0x84, 0x5c));setlinecolor(RGB(255, 255, 255));fillrectangle(j * Box_Size, i * Box_Size, (j + 1) * Box_Size, (i + 1) * Box_Size);}else if (First_Round[i][j] == role || First_Round[i][j] == role_target)//角色和角色与目标重合的样式{setfillcolor(RGB(0xf5, 0xc3, 0x42));setlinecolor(RGB(255, 255, 255));fillcircle((j + 0.5) * Box_Size, (i + 0.5) * Box_Size, 0.5 * Box_Size);}else if (First_Round[i][j] == box)//盒子样式{setfillcolor(RGB(0, 0, 255));setlinecolor(RGB(255, 255, 255));fillrectangle(j * Box_Size, i * Box_Size, (j + 1) * Box_Size, (i + 1) * Box_Size);}else if (First_Round[i][j] == target)//目标样式{setfillcolor(RGB(0, 255, 150));setlinecolor(RGB(255, 255, 255));fillrectangle((j + 0.3) * Box_Size, (i + 0.3) * Box_Size, (j + 0.7) * Box_Size, (i + 0.7) * Box_Size);}else if (First_Round[i][j] == achieve)//成功的目标样式{setfillcolor(RGB(15, 99, 60));setlinecolor(RGB(255, 255, 255));fillcircle((j + 0.5) * Box_Size, (i + 0.5) * Box_Size, 0.5 * Box_Size);}}}//OPAQUE不透明//SetBkMode函数来设置DrawText函数的输出方式wchar_t step_str[10], score_str[10];setbkmode(OPAQUE);settextcolor(RGB(0, 0, 0));settextstyle(30, 0, _T("宋体"));outtextxy(Box_Size * Box_Num + 5, 40, _T("操作:wsad"));outtextxy(Box_Size * Box_Num + 5, 80, _T("重玩:r"));outtextxy(Box_Size * Box_Num + 5, 160, _T("steps:"));_stprintf_s(step_str, _T("%d"), steps);outtextxy(Box_Size * Box_Num + 100, 160, step_str);outtextxy(Box_Size * Box_Num + 5, 200, _T("score:"));_stprintf_s(score_str, _T("%d"), achievementNum);outtextxy(Box_Size * Box_Num + 100, 200, score_str);if (check_lose_win() == 0){//TRANSPARENT透明setbkmode(TRANSPARENT);settextcolor(RGB(255, 0, 0));settextstyle(80, 0, _T("宋体"));outtextxy(80, 200, _T("lose"));}else if (check_lose_win() == 1){setbkmode(TRANSPARENT);settextcolor(RGB(0, 0, 0));settextstyle(80, 0, _T("宋体"));outtextxy(120, 150, _T("win"));settextstyle(40, 0, _T("宋体"));outtextxy(80, 220, _T("press 'n'to next round"));}FlushBatchDraw();
}//游戏帧,轮询键盘
void Flash_Frame(void)
{char input;//_kbhit检查当前是否有键盘输入,若有则返回一个非0值,否则返回0if (_kbhit()){input = _getch();switch (input){case('w')://上移matrix_up();break;case('s')://下移matrix_rotate(2);matrix_up();matrix_rotate(2);break;case('a')://左移matrix_rotate(1);matrix_up();matrix_rotate(3);break;case('d')://右移matrix_rotate(3);matrix_up();matrix_rotate(1);break;case('r')://重玩Windows_Init();break;default:break;}}
}

main函数

#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include "WindowsSet.h"extern int Begin, quit_flag;//引入外部变量int main()
{Windows_Init();while (1){if (Begin)//开始游戏,游戏界面轮询{Windows_Show();if (check_lose_win() == 1)Next_Round();Flash_Frame();}else//菜单界面轮询{Menu_Flash_Frame();}if (quit_flag)//退出游戏{break;}};return 0;
}

这里必须要用extern声明外部变量,否则无法引用

暂时还没有查询到为什么在#include "data_def.h"后还是显示未声明变量。

成果

将各个总代码整合便可得到最终成果

用C语言实现推箱子小游戏基础程序plus相关推荐

  1. c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  2. C语言实现推箱子小游戏

    一.设计目的 用简单的C语言知识制作的推箱子游戏,通过上下左右键将所有箱子移动到目标位置. 2.让我们更好地了解和巩固C语言知识,并实际运用,同时运用一些不太常见的知识点. 二.功能描述 1.模块功能 ...

  3. 控制台推箱子小游戏C语言

    自己开发的C语言控制台推箱子小游戏,基于二维数组实现,功能不多但是游戏整体较为完整,因为技术有限,所以代码暂未优化且整体显得较为臃肿,整体架构简单,代码全自主设计编写,仅作交流学习,还望大佬多多指点. ...

  4. PLC也能制作小游戏----Codesys编写推箱子小游戏

    1.序言 前文已介绍,Codesys编程软件拥有的各种编译方式,以及强大的可视化功能,完全可以实现类似的小游戏程序编写,让疲惫的工控人员在调机的空闲之余可以休闲下,本文编写另一个小游戏,也是十几年前的 ...

  5. 用 Dev-C++ 编写简单的推箱子小游戏

    用 Dev-C++ 编写简单的推箱子小游戏 前言 基础版 优化版 前言 以下是显示效果 B站视频讲解:[小游戏]用 Dev-C++ 编写简单的控制台推箱子小游戏 [小游戏]用 Dev-C++ 编写简单 ...

  6. 大一C语言课程设计之推箱子小游戏

    大一C语言课程设计之推箱子小游戏 先看一下效果 因为技术原因,开发说明没有加进去 按任意键以后 )] 同时响起来 你笑起来真好看的bgm 胜利界面会弹出一个弹出框 私信我或者加我qq:65245534 ...

  7. c 语言推箱子vs,C语言推箱子小游戏教程

    作者GitHub-Pages个人主页 本教程GitHub-Pages链接 本教程百度云下载地址 本教程编写于2016/11/22 Dawson Lee edited this page on Beij ...

  8. 简单的c语言推箱子程序,完整版本的推箱子小游戏,最简单的纯C语言打造

    /*推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 左 ...

  9. c#推箱子小游戏代码_推箱子小游戏V1.0制作

    小游戏实践 推箱子简易版 大家好,我是努力学习争取成为优秀的Game Producer的路人猿,今天来一起做一个推箱子的简易版本V1.0!下面跟我一起做吧~ 我们用到的软件如下: 编辑类 Visual ...

最新文章

  1. Linux新增开放端口
  2. java startswith忽略大小写_Java String startsWith()方法与示例
  3. C++静态全局变量问题
  4. html标签处理数据时合并空格
  5. hdu3033---加限制条件的0-1背包
  6. Linux Shell之一 Shell简介
  7. 二分图匹配之匈牙利算法
  8. 【图像分割】基于matlab粒子群优化T熵图像分割【含Matlab源码 286期】
  9. AAC音频的解码算法
  10. GET和POST的区别?
  11. java j2se下载_安装JDK(J2SE)
  12. 1_科普—什么是GNU?什么是GPL协议?GNU和Linux是怎么结合在一起的?
  13. Gazebo仿真WARN-The root link base_link has an inertia specified in the URDF, but KDL does not support
  14. 基于JAVA宠物喂养资讯分享平台的设计与实现计算机毕业设计源码+系统+lw文档+部署
  15. 爱心代码表白(可直接复制运行)
  16. Hack The Box——Tabby
  17. java邮件中添加excel_Java以邮件附件的方式发送excel文件
  18. 关于使用Swagger-ui时文档显示实体类中隐藏部分字段的问题
  19. 为什么Quora选择用Python语言?
  20. 推荐一个API接口git地址

热门文章

  1. 加州大学河滨分校计算机科学专业,加州大学河滨分校UCR计算机科学Computer Science专业排名第176-200位(2021年THE世界大学商科排名)...
  2. Android LVDS格式(JEIDA与VESA)
  3. 2021年机械员-岗位技能(机械员)考试题及机械员-岗位技能(机械员)免费试题
  4. docker 默认配置文件
  5. java实现电子发票中的发票税号等信息识别的几种可用方案
  6. public class 和 class 的区别
  7. 那一夜, 我懂了视频帧
  8. MySQL 06 事务、视图、索引、备份和恢复
  9. 关于系统中的流水帐号
  10. 树的高度,节点的深度和高度