中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C/C++百行代碼實現消消樂游戲的方法

發布時間:2020-07-01 16:18:36 來源:億速云 閱讀:359 作者:清晨 欄目:開發技術

這篇文章將為大家詳細講解有關C/C++百行代碼實現消消樂游戲的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

游戲設計

首先我們需要使用第三方框架,這里我使用的是sfml,不會使用sfml在我的上幾篇文章當中-掃雷(上)有詳細的開發環境搭建介紹

首先準備圖片資源

一張背景圖片,一張寶石圖片

C/C++百行代碼實現消消樂游戲的方法

窗口初始化加載圖片

Texture t1;
t1.loadFromFile(“images/bg2.png”);

C/C++百行代碼實現消消樂游戲的方法

當鼠標第一次單擊時,記錄下位置,第二次單擊又記錄一下位置,如果兩個小方塊相鄰就交換位置,如果不相鄰如圖c的位置則,不發生變化

C/C++百行代碼實現消消樂游戲的方法

判斷行或列如果三張一樣的圖片相鄰,清除一下圖片,進行刷新

實列

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <time.h>

using namespace sf;

#define GAME_ROWS_COUNT 8
#define GAME_COLS_COUNT 8

int ts = 57; // 每一個游戲小方塊區域的大小

bool isMoving = false;
bool isSwap = false;

// 相鄰位置的第幾次單擊,第2次單擊才交換方塊
int click = 0;

Vector2i pos; //鼠標單擊時的位置
Vector2i offset(15, 273);

int posX1, posY1; //第一次單擊的位置(記錄行和列的序號)
int posX2, posY2; //第二次單擊的位置(記錄行和列的序號)

struct Block {
	int x, y; //坐標值   x == col * ts  y == row * ts;
	int row, col; //第幾行,第幾列
	int kind; //表示第幾種小方塊
	bool match; //表示是否成三
	int alpha; //透明度

	Block() {
		match = false;
		alpha = 255;
		kind = -1;
	}
} grid[GAME_ROWS_COUNT + 2][GAME_ROWS_COUNT + 2];

void swap(Block p1, Block p2) {
	std::swap(p1.col, p2.col);
	std::swap(p1.row, p2.row);

	grid[p1.row][p1.col] = p1;
	grid[p2.row][p2.col] = p2;
}

void doEvent(RenderWindow* window) {
	Event e;
	while (window->pollEvent(e)) {
		if (e.type == Event::Closed) {
			window->close();
		}

		if (e.type == Event::MouseButtonPressed) {
			if (e.key.code == Mouse::Left) {
				if (!isSwap && !isMoving) click++;
				pos = Mouse::getPosition(*window) - offset;
			}
		}
	}

	if (click == 1) {
		posX1 = pos.x / ts + 1;
		posY1 = pos.y / ts + 1;
	}
	else if (click == 2) {
		posX2 = pos.x / ts + 1;
		posY2 = pos.y / ts + 1;

		// 是相鄰方塊就交換位置
		if (abs(posX2 - posX1) + abs(posY2 - posY1) == 1) {
			// 交換相鄰的兩個小方塊
			// 消消樂的方塊,怎么表示?
			swap(grid[posY1][posX1], grid[posY2][posX2]);
			isSwap = 1;
			click = 0;
		}
		else {
			click = 1;
		}
	}
}

void check() {
	for (int i = 1; i <= GAME_ROWS_COUNT; i++) {
		for (int j = 1; j <= GAME_COLS_COUNT; j++) {
			if (grid[i][j].kind == grid[i + 1][j].kind &&
				grid[i][j].kind == grid[i - 1][j].kind) {
				//grid[i - 1][j].match++;
				//grid[i][j].match++;
				//grid[i + 1][j].match++;
				for (int k = -1; k <= 1; k++) grid[i + k][j].match++;
			}

			if (grid[i][j].kind == grid[i][j - 1].kind &&
				grid[i][j].kind == grid[i][j + 1].kind) {
				//grid[i][j - 1].match++;
				//grid[i][j + 1].match++;
				//grid[i][j].match++;
				for (int k = -1; k <= 1; k++) grid[i][j + k].match++;
			}
		}
	}
}

void doMoving() {
	isMoving = false;

	for (int i = 1; i <= GAME_ROWS_COUNT; i++) {
		for (int j = 1; j <= GAME_COLS_COUNT; j++) {
			Block& p = grid[i][j]; // 引用p, 就是grid[i][j]的別名
			int dx, dy;

			for (int k = 0; k < 4; k++) {
				dx = p.x - p.col * ts;
				dy = p.y - p.row * ts;

				if (dx) p.x -= dx / abs(dx);
				if (dy) p.y -= dy / abs(dy);
			}

			if (dx || dy) isMoving = true;
		}
	}
}

void xiaochu() {
	for (int i = 1; i <= GAME_ROWS_COUNT; i++) {
		for (int j = 1; j <= GAME_COLS_COUNT; j++) {
			if (grid[i][j].match && grid[i][j].alpha > 10) {
				grid[i][j].alpha -= 10;
				isMoving = true;
			}
		}
	}
}

void huanYuan() {
	if (isSwap && !isMoving) {
		// 如果此時沒有產生匹配效果,就要還原
		int score = 0;
		for (int i = 1; i <= GAME_ROWS_COUNT; i++) {
			for (int j = 1; j <= GAME_COLS_COUNT; j++) {
				score += grid[i][j].match;
			}
		}

		if (score == 0) {
			swap(grid[posY1][posX1], grid[posY2][posX2]);
		}

		isSwap = false;
	}
}

void updateGrid() {
	for (int i = GAME_ROWS_COUNT; i > 0; i--) {
		for (int j = 1; j <= GAME_COLS_COUNT; j++) {
			if (grid[i][j].match) {
				for (int k = i - 1; k > 0; k--) {
					if (grid[k][j].match == 0) {
						swap(grid[k][j], grid[i][j]);
						break;
					}
				}

			}
		}
	}

	for (int j = 1; j <= GAME_COLS_COUNT; j++) {
		int n = 0;
		for (int i = GAME_ROWS_COUNT; i > 0; i--) {
			if (grid[i][j].match) {
				grid[i][j].kind = rand() % 7;
				grid[i][j].y = -ts * n;
				n++;
				grid[i][j].match = false;
				grid[i][j].alpha = 255;
			}
		}
	}
}

void drawBlocks(Sprite* sprite, RenderWindow* window) {
	for (int i = 1; i <= GAME_ROWS_COUNT; i++) {
		for (int j = 1; j <= GAME_COLS_COUNT; j++) {
			Block p = grid[i][j];
			sprite->setTextureRect(
				IntRect(p.kind * 52, 0, 52, 52));
			// 設置透明度
			sprite->setColor(Color(255, 255, 255, p.alpha));
			sprite->setPosition(p.x, p.y);
			// 因為數組gird中的Block, 每個Block的行標,列標是從1計算的,
			// 并根據行標和列表來計算的x,y坐標
			// 所以坐標的偏移,需要少便宜一些,也就是相當于在正方形區域的左上角的左上角方向偏移一個單位
			// 在這個位置開發存放第0行第0列(實際不繪制第0行第0列)
			sprite->move(offset.x - ts, offset.y - ts); // to do
			window->draw(*sprite);
		}
	}
}

void initGrid() {
	for (int i = 1; i <= GAME_ROWS_COUNT; i++) {
		for (int j = 1; j <= GAME_COLS_COUNT; j++) {
			grid[i][j].kind = rand() % 3;
			grid[i][j].col = j;
			grid[i][j].row = i;
			grid[i][j].x = j * ts;
			grid[i][j].y = i * ts;
		}
	}
}

int main(void) {
	srand(time(0));

	RenderWindow window(VideoMode(485, 917), "canxin-xiaoxiaole");
	// 設置刷新的最大幀率
	window.setFramerateLimit(60);

	Texture t1, t2;
	t1.loadFromFile("images/bg2.png");
	if (!t2.loadFromFile("images/1.png")) {
		return -1;
	}
	Sprite spriteBg(t1);
	Sprite spriteBlock(t2);

	initGrid();

	while (window.isOpen()) {
		// 處理用戶的點擊事件
		doEvent(&window);

		// 檢查匹配情況
		check();

		// 移動處理
		doMoving();

		// 消除
		if (!isMoving) {
			xiaochu();
		}

		// 還原處理
		huanYuan();

		if (!isMoving) {
			updateGrid();
		}

		// 渲染游戲畫面
		window.draw(spriteBg);
		// 渲染所有的小方塊 
		drawBlocks(&spriteBlock, &window);
		// 顯示
		window.display();
	}

	return 0;
}

關于C/C++百行代碼實現消消樂游戲的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

铜鼓县| 江安县| 保靖县| 渑池县| 襄汾县| 宜黄县| 靖宇县| 通城县| 衡南县| 新平| 汨罗市| 五常市| 夏河县| 漳州市| 陵水| 全椒县| 凤冈县| 大同市| 西安市| 昌图县| 新田县| 从江县| 镇宁| 兴城市| 隆尧县| 集贤县| 宝应县| 应城市| 赤壁市| 乐清市| 白城市| 武穴市| 闸北区| 沙河市| 马龙县| 湄潭县| 东台市| 隆子县| 武汉市| 云梦县| 清水河县|