羊了个羊(第二关)easyx 源码加素材

本文描述了一位刚学习C语言的新手在开发羊了个羊游戏过程中遇到的问题,如满槽图片渲染、工具栏功能实现等,展示了作者的编程学习过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚学C语言不久,写了一个羊了个羊第二关的代码。目前还有一些问题,一是在7个槽都满的时候,无法渲染出来失败那张图片,不知道是什么原因,暂时呢用了个窗口来作为提示;二是下方三个工具栏,第一个本来是要推出去三个卡牌,但是不知道要怎么做,就设为了直接消除,这个在看广告复活那里也是一样的,然后是第二个“撤回”工具是空着的没写,第三个工具有个BUG,点了后会把全部卡牌刷新成最初的样子,就是还没有开始消时候。

这些问题在我以后会解决的,毕竟我现状只是个菜鸟。

下面就附上源码:

#include<stdio.h>
#include<easyx.h>
#include<graphics.h>
#include<time.h>
#include<Windows.h>
#include<mmsystem.h>
//#include<fstream>
#include"tools.h"

#pragma comment (lib,"winmm.lib")
#define CEN 59

bool update = true;


struct fang_kuai
{
	int ceng;//第几层
	int row, col;//第几行,第几列
	int x, y;
	int lei_xing;//方块类型
	bool top;//true没有被覆盖,false被覆盖
	int bian_jie_x, bian_jie_y;//这一层的第一个方块的边界
};

struct fang_kuai** maps[CEN] = { 0 };
struct fang_kuai* clickedBlock;

IMAGE imgb_j[2];//背景
IMAGE FANG_KUAI[15][2];
IMAGE fu_huo;
IMAGE jie_shu;

int cao[7] = { 0 };
int h = 0;
int mn = 0;

//加载图片
void loading() {
	loadimage(&imgb_j[0], "./res/bg1.png");
	loadimage(&imgb_j[1], "./res/bg2.png");
	srand(time(NULL));
	char fileName[256];
	for (int i = 0; i < 15; i++) {
		for (int j = 0; j < 2; j++) {
			sprintf_s(fileName, sizeof(fileName), "./res/%d_%d.png", i + 1, j);
			loadimage(&FANG_KUAI[i][j], fileName);
		}
	}
	loadimage(&fu_huo, "./res/tishi.png");
	loadimage(&jie_shu, "./res/false.png");
}


//绘制图片
void hui_zhi() {
	putimage(0, 0, &imgb_j[0]);
	for (int i = 0; i < CEN; i++) {
		for (int k = 0; maps[i][k]; k++) {
			struct fang_kuai* p = maps[i][k];
			if (p->lei_xing == 0) {
				continue;
			}
			IMAGE* img = &FANG_KUAI[p->lei_xing - 1][p->top];
			putimagePNG(p->x, p->y, img);
		}
	}
	//槽中方块的绘制
	for (int s = 0; s < 7; s++) {
		if (cao[s]) {
			int x = 26 + s * 64.7;
			int y = 778;
			putimagePNG(x, y, &FANG_KUAI[cao[s] - 1][1]);
		}
	}
}

//初始化层
void CENG(int ceng, int rows, int cols, int bian_jie_x, int bian_jie_y) {
	maps[ceng] = (struct fang_kuai**)malloc(sizeof(struct fang_kuai*) * (rows * cols + 1));
	for (int row = 0; row < rows; row++) {
		for (int col = 0; col < cols; col++) {
			maps[ceng][row * cols + col] = (struct fang_kuai*)malloc(sizeof(struct fang_kuai));
			maps[ceng][row * cols + col]->bian_jie_x = bian_jie_x;
			maps[ceng][row * cols + col]->bian_jie_y = bian_jie_y;
			maps[ceng][row * cols + col]->row = row;
			maps[ceng][row * cols + col]->col = col;
			maps[ceng][row * cols + col]->lei_xing = 1 + rand() % 15;
			maps[ceng][row * cols + col]->top = true;
			maps[ceng][row * cols + col]->x = bian_jie_x + col * 61;
			maps[ceng][row * cols + col]->y = bian_jie_y + row * 68;
			maps[ceng][row * cols + col]->ceng = ceng;
		}
	}
	maps[ceng][rows * cols] = NULL;
}

//方块的布局构建
void initMAP() {
	int i = 0;
	for (i; i < 12; i++) {
		CENG(i, 1, 1, 30, 440 + i * 11);
	}
	for (i; i < 24; i++) {
		CENG(i, 1, 1, 414, 440 + (i - 12) * 11);
	}
	for (i; i < 30; i++) {
		CENG(i, 1, 1, 94, 583 + (i - 24) * 11);
	}
	for (i; i < 36; i++) {
		CENG(i, 1, 1, 346, 583 + (i - 30) * 11);
	}
	for (i; i < 42; i++) {
		CENG(i, 1, 1, 30 + (i - 36) * 11, 130);
	}
	for (i; i < 48; i++) {
		CENG(i, 1, 1, 413 - (i - 42) * 11, 130);
	}
	CENG(i++, 4, 3, 159, 309);
	CENG(i++, 5, 3, 159, 228);
	CENG(i++, 5, 4, 129, 204);
	CENG(i++, 5, 5, 99, 180);
	CENG(i++, 3, 6, 70, 209);
	CENG(i++, 1, 4, 134, 133);
	CENG(i++, 1, 4, 134, 118);
	CENG(i++, 1, 4, 134, 103);
	CENG(i++, 2, 5, 100, 258);
	CENG(i++, 2, 5, 100, 243);
	CENG(i++, 2, 5, 100, 228);
}

//判断是否发生覆盖
bool fu_gai(struct fang_kuai* b1, struct fang_kuai* b2) {
	int off = 4;//加上偏移量,防止距离较近的方块误判
	return rectIntersect(b1->x + off, b1->y + off, b1->x + 61 - off, b1->y + 68 - off,
		b2->x + off, b2->y + off, b2->x + 61 - off, b2->y + 68 - off);
}

//方块的亮暗
void ming_an() {
	for (int i = CEN - 1; i >= 0; i--) {
		for (int j = 0; maps[i][j]; j++) {
			if (maps[i][j]->lei_xing == 0) {
				continue;
			}
			for (int n = 0; n < i; n++) {
				for (int index = 0; maps[n][index]; index++) {
					if (maps[n][index]->lei_xing == 0) {
						continue;
					}
					//判断是否发生覆盖
					if (fu_gai(maps[n][index], maps[i][j])) {
						maps[n][index]->top = false;
					}
				}
			}
		}
	}
}

//用户点击
bool dian_ji() {
	ExMessage msg;
	if (peekmessage(&msg) && msg.message == WM_LBUTTONDOWN) {
		for (int c = CEN - 1; c >= 0; c--) {
			for (int k = 0; maps[c][k]; k++) {
				struct fang_kuai* p = maps[c][k];
				if (p->lei_xing && msg.x > p->x && msg.x < p->x + 61 && msg.y > p->y && msg.y < p->y + 68) {
					clickedBlock = p;
					return p->top;
				}
			}
		}
	}
	return false;
}

//方块的更新,暗->亮
void geng_xin(struct fang_kuai* block) {
	if (!block || block->lei_xing == 0)return;
	for (int z = 0; z < block->ceng; z++) {
		for (int index = 0; maps[z][index]; index++) {
			if (maps[z][index]->lei_xing == 0)continue;
			if (fu_gai(maps[z][index], block)) {
				maps[z][index]->top = true;
			}
		}
	}
}

//
void work() {
	geng_xin(clickedBlock);
	int cnt = 0;
	int ii = 0;
	for (ii; cao[ii] && ii < 7; ii++);//将点击到的方块填到卡槽中
	//槽中一样的三个方块清除
	if (ii < 7) {
		cao[ii] = clickedBlock->lei_xing;
		for (int j = 0; j < 7; j++) {
			if (cao[j] == clickedBlock->lei_xing) {
				cnt++;
			}
		}
		if (cnt == 3) {
			for (int j = 0; j < 7; j++) {
				if (cao[j] == clickedBlock->lei_xing) {
					cao[j] = 0;
				}
			}
		}
	}
	else {
		h += 1;
		//putimage(0, 0, &fu_huo);

	}
	clickedBlock->lei_xing = 0;

}

//工具栏
void gong_jv() {
	ExMessage asd;
	if (peekmessage(&asd) && asd.message == WM_LBUTTONDOWN) {
		//移出方块
		//同样暂时是直接消除,且暂时只能移出后三个
		if (asd.x > 47 && asd.x < 143 && asd.y>892 && asd.y < 976) {
			for (int i = 4; i < 7; i++) {
				cao[i] = 0;
			}
		}
		//撤回
		//后期完善
		/*if (asd.x > 204 && asd.x < 301 && asd.y>892 && asd.y<976) {

		}*/
		//洗牌
		if (asd.x > 360 && asd.x < 457 && asd.y>892 && asd.y < 976) {
			initMAP();
			ming_an();
			hui_zhi();
		}
	}
}

//音乐
void BGM() {
	mciSendString("play res/sheep.mp3", 0, 0, 0);
}

int main() {
	initgraph(504, 1000);
	loading();
	initMAP();
	clickedBlock = 0;
	BGM();
	int Time = 0;
	while (1) {
		/*for (int i = 0; i < 2; i++) {
			putimage(0, 0, &imgb_j[i]);
			Sleep(300);
		}*/
		//这里两个背景图的交替实现动态,后期完善
		BeginBatchDraw();
		Time += getDelay();
		if (Time >= 10) {
			Time = 0;
			update = true;
		}

		if (update) {
			ming_an();
			hui_zhi();
		}
		if (dian_ji()) {
			update = true;
			work();//点击的方块放在槽中

		}
		if (h != 0)//这里int h是在work函数中else,cao[]>7时控制弹出看广告复活或者直接结束游戏
		{
			if (mn == 0) {
				putimage(0, 0, &fu_huo);
				ExMessage xuan;
				if (peekmessage(&xuan) && xuan.message == WM_LBUTTONDOWN) {
					//如果点击广告,就弹出广告
					if (xuan.x > 142 && xuan.x < 361 && xuan.y>562 && xuan.y < 615) {
						//播放广告,广告先不放
						//暂时先让后三个直接消失,后期再完善
						for (int a = 4; a < 7; a++) {
							cao[a] = 0;
						}
						h = 0;//看了广告后h归0,便于第二次卡槽满后的 else if语句执行
						mn = 1;//这里是为了控制只能有一次复活的机会
					}
					else if (xuan.x > 142 && xuan.x < 361 && xuan.y>640 && xuan.y < 695)
					{
						//游戏结束
						MessageBox(GetHWnd(), "7个卡槽已满", "游戏结束", MB_OKCANCEL);//下面这条语句渲染不出来,只能用窗口来提示
						//putimage(0, 0, &jie_shu);//不知道为什么渲染不出来,下面那个也一样
						Sleep(300);
						closegraph();
						//break;
					}
				}
			}
			else {
				MessageBox(GetHWnd(), "1次机会用完\n7个卡槽已满", "游戏结束", MB_OKCANCEL);
				//putimage(0, 0, &jie_shu);
				Sleep(3000);
				closegraph();
				break;
			}
		}
		gong_jv();
		FlushBatchDraw();
	}

	return 0;
}

欢迎指正。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值