我们在对VS和easyx环境进行配置后,就可以开始我们羊了个羊的游戏编写啦。
问题1:能不能在手机上玩?
我们的开发暂时只适用于PC,我们需要使用Qt移植之后才可在移动端使用。
问题2:开发思路
问题3:开发步骤
#include
#include //easyx
int main(void) {
gameInit(); //游戏的初始化
return 0;
}
#define BLOCK_KINDS_1 3
#define WIN_W 504
#define WIN_H 900
int map[3][3];
//定义第一关的方格数
IMAGE imgBg; //用来表示背景图片
IMAGE imgBlocks[BLOCK_KINDS_1];
void gameInit() {
// 加载游戏的资源
// 背景图片、小方块
loadimage(&imgBg, "res/bg.png");
//(1)如果报错,则选择高级->字符集->多字符集
//(2)将res文件放在第二个test01中
char fileName[256];
for (int i = 0; i < BLOCK_KINDS_1; i++) {
sprintf_s(fileName,
sizeof(fileName),
"res/%d.png", i+1);
//发送经过格式化后的数据以“res/%d.png”的形式写入fileName数组中
loadimage(&imgBlocks[i], fileName);
//从fileName中读取图片放在imgBlocks数组里面
}
// 初始化地图,表示状态
initMap();
// 创建游戏的窗口
initgraph(WIN_W, WIN_H, EW_SHOWCONSOLE);
}
void initMap() {
//for (int i = 0; i < 3 * 3; i++) {
// map[i / 3][i % 3] = i / 3;
//}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
map[i][j] = i + 1; // 1 2 3
}
}
// 1 1 1
// 2 2 2
// 3 3 3
// 打乱
srand(time(NULL)); //配置随机种子
for (int i = 0; i < 20; i++) {
//例如选择a[0][1]和a[1][2],row1,col1,row2,col2代表俩个数字的行和列
int row1 = rand() % 3; //0..2
int col1 = rand() % 3;
int row2 = rand() % 3;
int col2 = rand() % 3;
//复习交换的三种算法
int tmp = map[row1][col1];
map[row1][col1] = map[row2][col2];
map[row2][col2] = tmp;
}
}
#define BLOCK_W 61
#define BLOCK_H 68
while (1) {
//刷新游戏窗口
update();
}
void update() {
//先刷新背景图片,再去刷新其他部分
// 问:怎样在游戏开发中,修改指定区域的图片
// 答案:不需要修改,所有的游戏,都是全部重新渲染出来的,就是覆盖!
putimage(0, 0, //图片的左上角的坐标位置
&imgBg);
// 绘制游戏的中心区域的, 多个小方块
/*
1 1 1
2 2 2
3 3 3
再随机打乱100次
*/
// 第一关
int off = 10;
int marginX = (WIN_W - BLOCK_W * 3 - off * 2) / 2;//左侧边距
int marginY = 270;//上下并没有居中
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (map[i][j] == 0) continue;
// 画的位置的计算
int x = marginX + j * (BLOCK_W + off);//每个小方块的x
int y = marginY + i * (BLOCK_H + off);
// 到底画哪一个
putimage(x, y, &imgBlocks[map[i][j] - 1]);
}
}
}
关于以上代码汇总如下,但会出现窗口不断抖动的问题
#include
#include //easyx
#include
#define BLOCK_KINDS_1 3
#define WIN_W 504
#define WIN_H 900
#define BLOCK_W 61
#define BLOCK_H 68
//定义第一关的方格数
IMAGE imgBg; //用来表示背景图片
IMAGE imgBlocks[BLOCK_KINDS_1];
int map[3][3];
void initMap() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
map[i][j] = i + 1; // 1 2 3
}
}
// 1 1 1
// 2 2 2
// 3 3 3
// 打乱
srand(time(NULL)); //配置随机种子
for (int i = 0; i < 20; i++) {
int row1 = rand() % 3; //0,1,2
int col1 = rand() % 3;
int row2 = rand() % 3;
int col2 = rand() % 3;
int tmp = map[row1][col1];
map[row1][col1] = map[row2][col2];
map[row2][col2] = tmp;
}
}
void gameInit() {
// 加载游戏的资源
// 背景图片
loadimage(&imgBg, "res/bg.png");
//小方块
char fileName[256];
for (int i = 0; i < BLOCK_KINDS_1; i++) {
sprintf_s(fileName,
sizeof(fileName),
"res/%d.png", i + 1);
loadimage(&imgBlocks[i], fileName);
}
// 初始化地图
initMap();
// 创建游戏的窗口
initgraph(WIN_W, WIN_H, EW_SHOWCONSOLE);
}
void update() {
//BeginBatchDraw();
//先刷新背景图片,再去刷新其他部分
// 问:怎样在游戏开发中,修改指定区域的图片
// 答案:不需要修改,所有的游戏,都是全部重新渲染出来的,就是覆盖!
putimage(0, 0, //图片的左上角的坐标位置
&imgBg);
// 绘制游戏的中心区域的, 多个小方块
/*
1 1 1
2 2 2
3 3 3
再随机打乱100次
*/
// 第一关
int off = 10;
int marginX = (WIN_W - BLOCK_W * 3 - off * 2) / 2;
int marginY = 270;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (map[i][j] == 0) continue;
// 位置的计算
int x = marginX + j * (BLOCK_W + off);
int y = marginY + i * (BLOCK_H + off);
// 到底画哪一个
putimage(x, y, &imgBlocks[map[i][j] - 1]);
}
}
//marginX = 26;
//marginY = 691;
//for (int i = 0; i < 7; i++) {
// if (chao[i]) {
// int x = marginX + i * 64.7;
// int y = marginY + 5;
// putimage(x, y, &imgBlocks[chao[i] - 1]);
// }
//}
//EndBatchDraw();
}
int main(void) {
gameInit(); //游戏的初始化
while (1) {
//刷新游戏窗口
update();
}
return 0;
}
在内存先一次性画好,然后再一次呈现(双缓存机制)
#include
#include //easyx
#include
#define BLOCK_KINDS_1 3
#define WIN_W 504
#define WIN_H 900
#define BLOCK_W 61
#define BLOCK_H 68
//定义第一关的方格数
IMAGE imgBg; //用来表示背景图片
IMAGE imgBlocks[BLOCK_KINDS_1];
int map[3][3];
void initMap() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
map[i][j] = i + 1; // 1 2 3
}
}
// 1 1 1
// 2 2 2
// 3 3 3
// 打乱
srand(time(NULL)); //配置随机种子
for (int i = 0; i < 20; i++) {
int row1 = rand() % 3; //0,1,2
int col1 = rand() % 3;
int row2 = rand() % 3;
int col2 = rand() % 3;
int tmp = map[row1][col1];
map[row1][col1] = map[row2][col2];
map[row2][col2] = tmp;
}
}
void gameInit() {
// 加载游戏的资源
// 背景图片
loadimage(&imgBg, "res/bg.png");
//小方块
char fileName[256];
for (int i = 0; i < BLOCK_KINDS_1; i++) {
sprintf_s(fileName,
sizeof(fileName),
"res/%d.png", i + 1);
loadimage(&imgBlocks[i], fileName);
}
// 初始化地图
initMap();
// 创建游戏的窗口
initgraph(WIN_W, WIN_H, EW_SHOWCONSOLE);
}
void update() {
BeginBatchDraw();
//先刷新背景图片,再去刷新其他部分
// 问:怎样在游戏开发中,修改指定区域的图片
// 答案:不需要修改,所有的游戏,都是全部重新渲染出来的,就是覆盖!
putimage(0, 0, //图片的左上角的坐标位置
&imgBg);
// 绘制游戏的中心区域的, 多个小方块
/*
1 1 1
2 2 2
3 3 3
再随机打乱100次
*/
// 第一关
int off = 10;
int marginX = (WIN_W - BLOCK_W * 3 - off * 2) / 2;
int marginY = 270;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (map[i][j] == 0) continue;
// 位置的计算
int x = marginX + j * (BLOCK_W + off);
int y = marginY + i * (BLOCK_H + off);
// 到底画哪一个
putimage(x, y, &imgBlocks[map[i][j] - 1]);
}
}
//marginX = 26;
//marginY = 691;
//for (int i = 0; i < 7; i++) {
// if (chao[i]) {
// int x = marginX + i * 64.7;
// int y = marginY + 5;
// putimage(x, y, &imgBlocks[chao[i] - 1]);
// }
//}
EndBatchDraw();
}
int main(void) {
gameInit(); //游戏的初始化
while (1) {
//刷新游戏窗口
update();
}
return 0;
}
struct location {
int row;
int col;
};
int main(void) {
gameInit(); //游戏的初始化
while (1) {
//刷新游戏窗口
// 按键处理: 接口设计
if (userClick(&loc)) {
work(&loc);
}
//如果用户单击的正确,则继续work
update();
}
return 0;
}
bool userClick(struct location* loc) {
ExMessage msg;
if (peekmessage(&msg) && msg.message==WM_LBUTTONDOWN) {
//如果有用户单击这条消息的存在(peekmessage代表如果有的话获取一个bool)
//鼠标左键按下去
//思路一:逐个比较当前位置和各个方块的位置(low)
//思路二:直接计算
//(1)边界量
int off = 10;
int marginY = 270;
int marginX = (WIN_W - BLOCK_W * 3 - off * 2) / 2;
float x = (msg.x - marginX)*1.0 / (BLOCK_W + off);
//每个消息的x坐标-左边界/(盒子宽+off)
//容错处理:如果是点到边框,其中0,1表示点到最左侧方块10%的位置,最后转为int(可解决太小)
//0.2
int col = (x + 1) - 0.1;
//解决太大
float tail = (x + 1) - 0.1 - col; //得到小数部分
if (col < 1 || col > 3 || tail > 0.6) {
return false;
}
float y = (msg.y - marginY)*1.0 / (BLOCK_H + off);
float y2 = y + 1 - 0.1;
int row = y2;
tail = y2 - row;
if (row < 1 || row > 3 || tail > 0.6) {
return false;
}
loc->row = row;
loc->col = col;
printf("[%d,%d]", row, col);
//图形化界面printf默认打不出来
return true;
}
return false;
}
int chao[7] = { 0 };
void work(struct location* loc) {
int index = map[loc->row - 1][loc->col - 1];
map[loc->row - 1][loc->col - 1] = 0;
// 放到羊槽的合适位置
// 0 0 0 0 0 0 0
// 2 1 0 0 0 0 0
int i = 0;
for (; chao[i] && i < 7; i++);
if (i < 7) {
chao[i] = index;
}
}
marginX = 26;
marginY = 691;
for (int i = 0; i < 7; i++) {
if (chao[i]) {
//如果非0则开始放
int x = marginX + i * 64.7;
int y = marginY + 5;
putimage(x, y, &imgBlocks[chao[i] - 1]);
}
}
#include
#include //easyx
#include
#include
#define BLOCK_KINDS_1 3
#define WIN_W 504
#define WIN_H 900
#define BLOCK_W 61
#define BLOCK_H 68
//定义第一关的方格数
IMAGE imgBg; //用来表示背景图片
IMAGE imgBlocks[BLOCK_KINDS_1];
int map[3][3];
int chao[7] = { 0 };
struct location {
int row;
int col;
};
void initMap() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
map[i][j] = i + 1; // 1 2 3
}
}
// 1 1 1
// 2 2 2
// 3 3 3
// 打乱
srand(time(NULL)); //配置随机种子
for (int i = 0; i < 20; i++) {
int row1 = rand() % 3; //0,1,2
int col1 = rand() % 3;
int row2 = rand() % 3;
int col2 = rand() % 3;
int tmp = map[row1][col1];
map[row1][col1] = map[row2][col2];
map[row2][col2] = tmp;
}
}
void gameInit() {
// 加载游戏的资源
// 背景图片
loadimage(&imgBg, "res/bg.png");
//小方块
char fileName[256];
for (int i = 0; i < BLOCK_KINDS_1; i++) {
sprintf_s(fileName,
sizeof(fileName),
"res/%d.png", i + 1);
loadimage(&imgBlocks[i], fileName);
}
// 初始化地图
initMap();
// 创建游戏的窗口
initgraph(WIN_W, WIN_H, EW_SHOWCONSOLE);//控制台
}
bool userClick(struct location* loc) {
ExMessage msg;
if (peekmessage(&msg) && msg.message == WM_LBUTTONDOWN) {
// 判断具体的位置
int off = 10;
int marginY = 270;
int marginX = (WIN_W - BLOCK_W * 3 - off * 2) / 2;
float x = (msg.x - marginX) * 1.0 / (BLOCK_W + off);
// 0.0 - n.n
// 0.09 最左边方块的左侧10%左右
// 1.09
// 0.99
// 0
int col = (x + 1) - 0.1;
float tail = (x + 1) - 0.1 - col; //得到小数部分
if (col < 1 || col > 3 || tail > 0.6) {
return false;
}
float y = (msg.y - marginY) * 1.0 / (BLOCK_H + off);
float y2 = y + 1 - 0.1;
int row = y2;
tail = y2 - row;
if (row < 1 || row > 3 || tail > 0.6) {
return false;
}
loc->row = row;
loc->col = col;
printf("[%d,%d]", row, col);
return true;
}
return false;
}
void update() {
BeginBatchDraw();
//先刷新背景图片,再去刷新其他部分
// 问:怎样在游戏开发中,修改指定区域的图片
// 答案:不需要修改,所有的游戏,都是全部重新渲染出来的,就是覆盖!
putimage(0, 0, //图片的左上角的坐标位置
&imgBg);
// 绘制游戏的中心区域的, 多个小方块
/*
1 1 1
2 2 2
3 3 3
再随机打乱100次
*/
// 第一关
int off = 10;
int marginX = (WIN_W - BLOCK_W * 3 - off * 2) / 2;
int marginY = 270;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (map[i][j] == 0) continue;//如果为0则不渲染
// 位置的计算
int x = marginX + j * (BLOCK_W + off);
int y = marginY + i * (BLOCK_H + off);
// 到底画哪一个
putimage(x, y, &imgBlocks[map[i][j] - 1]);
}
}
marginX = 26;
marginY = 691;
for (int i = 0; i < 7; i++) {
if (chao[i]) {
int x = marginX + i * 64.7;
int y = marginY + 5;
putimage(x, y, &imgBlocks[chao[i] - 1]);
}
}
EndBatchDraw();
}
//点击谁就把谁放在羊槽,下面第一一个数组。
//如果被点击数字,上面变成0则删掉,下面添加相应数字,然后渲染
void work(struct location* loc) {
int index = map[loc->row - 1][loc->col - 1];
map[loc->row - 1][loc->col - 1] = 0;
// 放到羊槽的合适位置
// 0 0 0 0 0 0 0
// 2 1 0 0 0 0 0
//从左向右数,直到遇到第一个为0的位置
int i = 0;
for (; chao[i] && i < 7; i++);
if (i < 7) {
chao[i] = index;
}
}
int main(void) {
gameInit(); //游戏的初始化
struct location loc; //表示玩家有效点击的位置
while (1) {
//刷新游戏窗口
// 按键处理: 接口设计
if (userClick(&loc)) {
work(&loc);
}
update();
//clear(&loc);
}
return 0;
}