Let's make 16 games in C++(十一):Bejeweled

1、准备游戏需要的背景图片

 

2、渲染一个740x480的屏幕

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

using namespace sf;

int ts = 54;
Vector2i offset(48, 24);

struct piece
{
	int x;
	int y;
	int col;
	int row;
	int kind;
	int match;
	piece() {
		match = 0;
	}
} grid[10][10];

int main()
{
	RenderWindow app(VideoMode(740, 480), "Match-3 Game!");
	app.setFramerateLimit(60);


	Texture t1;
	Texture t2;
	t1.loadFromFile("./Resources/images/background.png");
	t2.loadFromFile("./Resources/images/gems.png");

	Sprite background(t1);
	Sprite gems(t2);

	for (int i = 1; i <= 8; i++)
	{
		for (int j = 1; j <= 8; j++)
		{
			grid[i][j].kind = rand() % 7;
			grid[i][j].col = j;
			grid[i][j].row = i;
			grid[i][j].x = j * ts;
			grid[i][j].y = i * ts;

		}
	}

	while (app.isOpen())
	{
		Event e;
		while (app.pollEvent(e))
		{
			if (e.type == Event::Closed)
			{
				app.close();
			}
		}


		//draw
		app.draw(background);

		for (int i = 1; i <= 8 ; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				piece p = grid[i][j];
				gems.setTextureRect(IntRect(p.kind * 49, 0, 49, 49));
				gems.setPosition(p.x, p.y);
				gems.move(offset.x - ts, offset.y - ts);;
				app.draw(gems);
			}
		}
		app.display();

	}
	return 0;
}

3、增加交换功能(点击)

void swap(piece p1, piece 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;
}


...
...

//mouse click
if (click == 1)
{
	x0 = pos.x / ts + 1;
	y0 = pos.y / ts + 1;
}
if (click == 2)
{
	x = pos.x / ts + 1;
	y = pos.y / ts + 1;
	if (abs(x-x0) + abs(y-y0) == 1)
	{
		swap(grid[y0][x0], grid[y][x]);
		click = 0;
	}
	else
	{
		click = 1;
	}
}

//Moving animation
for (int i = 1; i <= 8; i++)
{
	for (int j = 1; j <= 8; j++)
	{
		piece &p = grid[i][j];
		int dx;
		int dy;
		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);
		}
	}
}

4、完善消除和自动添加逻辑

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

using namespace sf;

int ts = 54;
Vector2i offset(48, 24);

struct piece
{
	int x;
	int y;
	int col;
	int row;
	int kind;
	int match;

	piece()
	{
		match = 0;
	}
} grid[10][10];


void swap(piece p1, piece 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;
}



int main()
{
	srand(time(0));
	RenderWindow app(VideoMode(740, 480), "Match-3 Game!");
	app.setFramerateLimit(60);


	Texture t1;
	Texture t2;
	t1.loadFromFile("./Resources/images/background.png");
	t2.loadFromFile("./Resources/images/gems.png");

	Sprite background(t1);
	Sprite gems(t2);

	for (int i = 1; i <= 8; i++)
	{
		for (int j = 1; j <= 8; j++)
		{
			grid[i][j].kind = rand() % 7;
			grid[i][j].col = j;
			grid[i][j].row = i;
			grid[i][j].x = j * ts;
			grid[i][j].y = i * ts;
		}
	}

	int x0;
	int y0;
	int x;
	int y;
	int click = 0;
	Vector2i pos;
	bool isSwap = false;
	bool isMoving = false;

	while (app.isOpen())
	{
		Event e;
		while (app.pollEvent(e))
		{
			if (e.type == Event::Closed)
			{
				app.close();
			}
			if (e.type == Event::MouseButtonPressed)
			{
				if (e.key.code == Mouse::Left)
				{
					if (!isSwap && !isMoving)
					{
						click++;
					}
					pos = Mouse::getPosition(app) - offset;
				}
			}
		}

		//mouse click
		if (click == 1)
		{
			x0 = pos.x / ts + 1;
			y0 = pos.y / ts + 1;
		}
		if (click == 2)
		{
			x = pos.x / ts + 1;
			y = pos.y / ts + 1;
			if (abs(x-x0) + abs(y-y0) == 1)
			{
				swap(grid[y0][x0], grid[y][x]);
				isSwap = true;
				click = 0;
			}
			else
			{
				click = 1;
			}
		}

		//Match finding
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				if (grid[i][j].kind == grid[i + 1][j].kind)
				{
					if (grid[i][j].kind == grid[i - 1][j].kind)
						for (int n = -1; n <= 1; n++)
						{
							grid[i + n][j].match++;
						}
				}

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

		//Moving animation
		isMoving = false;
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				piece &p = grid[i][j];
				int dx;
				int dy;
				for (int n = 0; n < 4; n++)
				{
					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;
				}
			}
		}


		//Get score
		int score = 0;
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				score += grid[i][j].match;
			}
		}

		//Second swap if no match
		if (isSwap && !isMoving)
		{
			if (!score) swap(grid[y0][x0], grid[y][x]);
			{
				isSwap = false;
			}
		}
		//Update grid
		if (!isMoving)
		{
			for (int i = 8; i > 0; i--)
			{
				for (int j = 1; j <= 8; j++)
				{
					if (grid[i][j].match)
					{
						for (int n = i; n > 0; n--)
						{
							if (!grid[n][j].match)
							{ 
								swap(grid[n][j], grid[i][j]); 
								break; 
							};
						}
					}
				}
			}

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


		//draw
		app.draw(background);

		for (int i = 1; i <= 8 ; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				piece p = grid[i][j];
				gems.setTextureRect(IntRect(p.kind * 49, 0, 49, 49));
				gems.setPosition(p.x, p.y);
				gems.move(offset.x - ts, offset.y - ts);;
				app.draw(gems);
			}
		}
		app.display();

	}
	return 0;
}

结果图

*5、增加额外功能(自动消除)

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

using namespace sf;

int ts = 54;
Vector2i offset(48, 24);

struct piece
{
	int x;
	int y;
	int col;
	int row;
	int kind;
	int match;
	int alpha;

	piece()
	{
		match = 0;
		alpha = 255;
	}
} grid[10][10];


void swap(piece p1, piece 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;
}



int main()
{
	srand(time(0));
	RenderWindow app(VideoMode(740, 480), "Match-3 Game!");
	app.setFramerateLimit(60);


	Texture t1;
	Texture t2;
	t1.loadFromFile("./Resources/images/background.png");
	t2.loadFromFile("./Resources/images/gems.png");

	Sprite background(t1);
	Sprite gems(t2);

	for (int i = 1; i <= 8; i++)
	{
		for (int j = 1; j <= 8; j++)
		{
			grid[i][j].kind = rand() % 7;
			grid[i][j].col = j;
			grid[i][j].row = i;
			grid[i][j].x = j * ts;
			grid[i][j].y = i * ts;
		}
	}

	int x0;
	int y0;
	int x;
	int y;
	int click = 0;
	Vector2i pos;
	bool isSwap = false;
	bool isMoving = false;

	while (app.isOpen())
	{
		Event e;
		while (app.pollEvent(e))
		{
			if (e.type == Event::Closed)
			{
				app.close();
			}
			if (e.type == Event::MouseButtonPressed)
			{
				if (e.key.code == Mouse::Left)
				{
					if (!isSwap && !isMoving)
					{
						click++;
					}
					pos = Mouse::getPosition(app) - offset;
				}
			}
		}

		//mouse click
		if (click == 1)
		{
			x0 = pos.x / ts + 1;
			y0 = pos.y / ts + 1;
		}
		if (click == 2)
		{
			x = pos.x / ts + 1;
			y = pos.y / ts + 1;
			if (abs(x-x0) + abs(y-y0) == 1)
			{
				swap(grid[y0][x0], grid[y][x]);
				isSwap = true;
				click = 0;
			}
			else
			{
				click = 1;
			}
		}

		//Match finding
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				if (grid[i][j].kind == grid[i + 1][j].kind)
				{
					if (grid[i][j].kind == grid[i - 1][j].kind)
						for (int n = -1; n <= 1; n++)
						{
							grid[i + n][j].match++;
						}
				}

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

		//Moving animation
		isMoving = false;
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				piece &p = grid[i][j];
				int dx;
				int dy;
				for (int n = 0; n < 4; n++)
				{
					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;
				}
			}
		}
		
		//Deleting animation
		if (!isMoving)
		{
			for (int i = 1; i <= 8; i++)
			{
				for (int j = 1; j <= 8; j++)
				{
					if (grid[i][j].match)
					{
						if (grid[i][j].alpha > 10)
						{
							grid[i][j].alpha -= 10;
							isMoving = true;
						}
					}
				}
			}
		}

		//Get score
		int score = 0;
		for (int i = 1; i <= 8; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				score += grid[i][j].match;
			}
		}

		//Second swap if no match
		if (isSwap && !isMoving)
		{
			if (!score) swap(grid[y0][x0], grid[y][x]);
			{
				isSwap = false;
			}
		}
		//Update grid
		if (!isMoving)
		{
			for (int i = 8; i > 0; i--)
			{
				for (int j = 1; j <= 8; j++)
				{
					if (grid[i][j].match)
					{
						for (int n = i; n > 0; n--)
						{
							if (!grid[n][j].match)
							{ 
								swap(grid[n][j], grid[i][j]); 
								break; 
							};
						}
					}
				}
			}

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


		//draw
		app.draw(background);

		for (int i = 1; i <= 8 ; i++)
		{
			for (int j = 1; j <= 8; j++)
			{
				piece p = grid[i][j];
				gems.setTextureRect(IntRect(p.kind * 49, 0, 49, 49));
				gems.setColor(Color(255, 255, 255, p.alpha));
				gems.setPosition(p.x, p.y);
				gems.move(offset.x - ts, offset.y - ts);;
				app.draw(gems);
			}
		}
		app.display();

	}
	return 0;
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值