SFML学习-写一个俄罗斯方块

SFML配置:
首先在官网下载最新的源代码,然后按照官方教程那样部署配置结果导致了一个奇怪的异常,参考了一个博客的解决方案是将源代码的bin文件夹中的所有文件全部复制到项目文件夹中就行了,试了一下确实是可以的。

创建一个简单的窗口来测试一下:

// sfml_test1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <SFML/Graphics.hpp>

int main()
{
	sf::RenderWindow window(sf::VideoMode(600, 800), "SFML works!");
	sf::CircleShape shape(100.f);
	shape.setFillColor(sf::Color::Green);

	while (window.isOpen())
	{
		sf::Event event;
		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed)
				window.close();
		}

		window.clear();
		window.draw(shape);
		window.display();
	}

	return 0;
}

在这里插入图片描述

基本的语法可以参考官方文档,因为在B站看到一个油管搬运的视频是用SFML写一些小游戏,看起来很简单,所以我就想自己试试。实际写代码的时候感觉没有想象中那么简单。由于SFML是基于opengl的,相比较opengl确实是简单了很多的,语法用起来甚至有点像pygame那样简单易用,当然它能实现的功能也是有限的,所以只适合写一些小游戏自娱自乐。

花了时间自己写了一个俄罗斯方块,上手也挺快的。相比较在那些引擎上用鼠标点击的方式来开发游戏,果然还是这种完全通过代码来开发游戏更有意思一些。

代码如下:

// sfml_test1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <SFML/Graphics.hpp>
#include<iostream>
#include<string>
#include<vector>
#include<time.h>
#include<algorithm>
//#include<math.h>
int main()
{
	const float width = 600, height = 800;
	sf::RenderWindow window(sf::VideoMode(width, height), "Tetris!");
	sf::CircleShape shape(100.f);
	shape.setFillColor(sf::Color::Green);
	
	sf::Font font;
	if (!font.loadFromFile("C:\\Windows\\Fonts\\ARIALN.TTF"))
	{
		std::cout << "Can not load the font" << std::endl;
	}
	sf::Text text,text1;
	text.setFont(font);
	text.setString("The Next");
	text.setCharacterSize(24);
	text.setFillColor(sf::Color::Blue);
	//text.setStyle(sf::Text::Bold | sf::Text::Underlined);
	text.setPosition(sf::Vector2f(150, 150));
	text1.setFont(font);
	text1.setString("Scores: 0");
	text1.setCharacterSize(24);
	text1.setFillColor(sf::Color::Black);

	const float w = width * 0.6f, h = w *2.f;
	const float xini = width * 0.05f, yini = height * 0.05f;
	sf::Vertex vertices[5] = {
		sf::Vertex(sf::Vector2f(xini,yini),sf::Color::Green),
		sf::Vertex(sf::Vector2f(xini+w,yini),sf::Color::Green),
		sf::Vertex(sf::Vector2f(xini+w,yini+h),sf::Color::Green),
		sf::Vertex(sf::Vector2f(xini,yini+h),sf::Color::Green),
		sf::Vertex(sf::Vector2f(xini,yini),sf::Color::Green),
	};
	text.setPosition(sf::Vector2f(xini + w + w/10.f, yini + w/10.f));
	text1.setPosition(sf::Vector2f(xini + w + w/10.f, yini + 5*w/10.f));
	bool Next = false, next1 = false, fillrow = true,endgame=false;//
	int scores = 0;
	sf::Sprite sprite;
	sf::Texture te1;
	if (!te1.loadFromFile("block.png")) {
		std::cout << "Can not load the pic \"block.png\"" << std::endl;
	}
	sprite.setTexture(te1);
	std::vector<sf::Vector2i> arr1 = {sf::Vector2i(4,0),sf::Vector2i(5,0),sf::Vector2i(6,0),sf::Vector2i(5,1)};
	std::vector<sf::Vector2i> arr2 = { sf::Vector2i(4,0),sf::Vector2i(4,1),sf::Vector2i(5,1),sf::Vector2i(5,2) };
	std::vector<sf::Vector2i> arr3 = { sf::Vector2i(4,0),sf::Vector2i(5,0),sf::Vector2i(6,0),sf::Vector2i(7,0) };
	std::vector<sf::Vector2i> arr4 = { sf::Vector2i(4,0),sf::Vector2i(5,0),sf::Vector2i(5,1),sf::Vector2i(4,1) };
	std::vector<sf::Vector2i> arr5 = { sf::Vector2i(4,0),sf::Vector2i(4,1),sf::Vector2i(4,2),sf::Vector2i(5,2) };
	std::vector<std::vector<sf::Vector2i>>arrs = { arr1,arr2,arr3,arr4 ,arr5};
	auto arr = arr1;
	//随机数
	srand((unsigned)time(NULL));
	int a = rand() % 5,b=0, Next_a = rand() % 5;
	arr = arrs[a];
	auto arr6 = arrs[Next_a];
	for (auto & ar : arr6) {
		ar.x += 7;
		ar.y += 2;
	}
	sprite.setPosition(sf::Vector2f(xini, yini));
	sprite.setColor(sf::Color::White);
	sprite.setScale(sf::Vector2f((w / 10.f)/ te1.getSize().x, (w / 10.f)/ te1.getSize().x));
	std::vector<sf::Sprite>sprites = { sprite,sprite,sprite,sprite },sp1= { sprite,sprite,sprite,sprite };
	for (int i = 0; i < arr.size(); ++i)
		sprites[i].setPosition(xini + arr[i].x*w / 10.f, yini + arr[i].y*w / 10.f);
	for (int i = 0; i < arr6.size(); ++i)
		sp1[i].setPosition(xini + arr6[i].x*w / 10.f, yini + arr6[i].y*w / 10.f);
	int tx = 0,speed = 1;

	std::vector<sf::Vector2i> allblocks;//所以的方块的集合
	std::vector<int>allx, ally;
	for (auto all : allblocks) {
		allx.push_back(all.x);
		ally.push_back(all.y);
	}
	while (window.isOpen())
	{

		for (int i = 0; i < arr.size(); ++i) {
			auto it = std::find(allblocks.begin(), allblocks.end(), arr[i]+sf::Vector2i(0,1));
			if(it!= allblocks.end()) {
				Next = true;
			}
		}
		for (auto alls : allblocks) {
			if (alls.y <= 3)
				endgame = true;
		}
		if (arr[3].y == 19 || arr[0].y == 19 || arr[1].y == 19|| arr[2].y == 19)
			Next = true;
		if (Next &&!endgame){
			scores += 100;
			sf::String str = "Scores: ";
			str.insert(str.getSize(),std::to_string(scores));
			text1.setString(str);
			speed = 1;
			std::cout << "the size of allblocks " << allblocks.size() << std::endl;
			for (auto ar : arr) {
				allblocks.push_back(ar);
				allx.push_back(ar.x);
				ally.push_back(ar.y);
			}

			for (int i = arr[0].y; i <= 19; ++i) {
				for (int j = 0; j < 10; ++j) {
					auto it = std::find(allblocks.begin(), allblocks.end(), sf::Vector2i(j, i));
					if (it == allblocks.end())
						fillrow = false;
				}
				if (fillrow) {
					scores += 1000;
					sf::String str = "Scores: ";
					str.insert(str.getSize(), std::to_string(scores));
					text1.setString(str);
					for (int j = 0; j < 10; ++j) {
						auto it = std::find(allblocks.begin(), allblocks.end(), sf::Vector2i(j, i));
						allblocks.erase(it);
					}
					for (auto &alls : allblocks) {
						if (alls.y < i)
							alls.y += 1;
					}
					sprites.clear();
					for (auto alls : allblocks) {
						sprite.setPosition(xini + alls.x*w / 10.f, yini + alls.y*w / 10.f);
						sprites.push_back(sprite);
					}
				}
				else {
					fillrow = true;
				}
			}
				
			Next = false;
			srand((unsigned)time(NULL));
			a = Next_a;
			Next_a = rand() % 5;
			b = 0;
			arr = arrs[a];
			arr6 = arrs[Next_a];
			for (auto & ar : arr6) {
				ar.x += 7;
				ar.y += 2;
			}
			for (int i = 0; i < arr6.size(); ++i)
				sp1[i].setPosition(xini + arr6[i].x*w / 10.f, yini + arr6[i].y*w / 10.f);
			for (int i = 0; i < arr.size(); ++i) {
				sprite.setPosition(xini + arr[i].x*w / 10.f, yini + arr[i].y*w / 10.f);
				sprites.push_back(sprite);
			}	
		}	
		++tx;
		tx = tx % 2000;
		sf::Event event;
		
		for (auto &ar : arr)
			if(tx%(1000/speed)==2 &&arr[3].y<20-1)
				ar.y += 1;
			//sp.move(0.f, 0.1f);//sp.setPosition(sp.getPosition().x, sp.getPosition().y + 0.1f);
		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed)
				window.close();
			else if (event.type == sf::Event::KeyPressed) {
				if (event.key.code == sf::Keyboard::Space) {//空格键
					std::cout << "press  "<<a<<","<<b << std::endl;
					if (a == 0) {
						if (b == 0) {
							arr[0] = arr[1] + sf::Vector2i(0, -1);
							arr[2] = arr[1] + sf::Vector2i(0, 1);
							arr[3] = arr[1] + sf::Vector2i(-1, 0);
							b = 1;
						}
						else if (b == 1 && arr[2].x<9) {
							arr[0] = arr[1] + sf::Vector2i(-1, 0);
							arr[2] = arr[1] + sf::Vector2i(1, 0);
							arr[3] = arr[1] + sf::Vector2i(0, -1);
							b = 2;
						}
						else if (b == 2) {
							arr[0] = arr[1] + sf::Vector2i(0, -1);
							arr[2] = arr[1] + sf::Vector2i(0, 1);
							arr[3] = arr[1] + sf::Vector2i(1, 0);
							b = 3;
						}
						else if(arr[0].x!=0&& b==3){
							arr[0] = arr[1] + sf::Vector2i(-1, 0);
							arr[2] = arr[1] + sf::Vector2i(1, 0);
							arr[3] = arr[1] + sf::Vector2i(0, 1);
							b = 0;
						}
					}else if (a == 1) {
							if (b == 0 &&arr[0].x>0) {
								arr[0] = arr[1] + sf::Vector2i(1, 0);
								arr[2] = arr[1] + sf::Vector2i(0, 1);
								arr[3] = arr[1] + sf::Vector2i(-1, 1);
								b = 1;
							}
							else if(b==0){
								arr[0] = arr[1] + sf::Vector2i(0, -1);
								arr[2] = arr[1] + sf::Vector2i(1, 0);
								arr[3] = arr[1] + sf::Vector2i(1, 1);
								b = 0;
							}
						}else if (a == 2) {
							if (b == 0 &&arr[3].y<17) {
								arr[0] = arr[1] + sf::Vector2i(0, -1);
								arr[2] = arr[1] + sf::Vector2i(0, 1);
								arr[3] = arr[1] + sf::Vector2i(0, 2);
								b = 1;
							}
							else if(b==1&&arr[0].x>0&&arr[0].x<8){
								arr[0] = arr[1] + sf::Vector2i(-1, 0);
								arr[2] = arr[1] + sf::Vector2i(1, 0);
								arr[3] = arr[1] + sf::Vector2i(2,0);
								b = 0;
							}
						}
						else if (a == 4) {
							if (b == 0 &&arr[0].x>0) {
								arr[0] = arr[1] + sf::Vector2i(1, 0);
								arr[2] = arr[1] + sf::Vector2i(-1, 0);
								arr[3] = arr[1] + sf::Vector2i(-1, 1);
								b = 1;
							}
							else if (b == 1) {
								arr[0] = arr[1] + sf::Vector2i(-1, -1);
								arr[2] = arr[1] + sf::Vector2i(0, -1);
								arr[3] = arr[1] + sf::Vector2i(0, 1);
								b = 2;
							}
							else if (b == 2 &&arr[1].x<9) {
								arr[0] = arr[1] + sf::Vector2i(1, -1);
								arr[2] = arr[1] + sf::Vector2i(1, 0);
								arr[3] = arr[1] + sf::Vector2i(-1, 0);
								b = 3;
							}
							else if (b == 3) {
								arr[0] = arr[1] + sf::Vector2i(0, -1);
								arr[2] = arr[1] + sf::Vector2i(0, 1);
								arr[3] = arr[1] + sf::Vector2i(1, 1);
								b = 0;
							}
						}
					for (int i = 0; i < arr.size(); ++i)
						sprites[sprites.size()-4+i].setPosition(xini + arr[i].x*w / 10.f, yini + arr[i].y*w / 10.f);
				}
				else if (event.key.code == sf::Keyboard::Left &&arr[0].x > 0 && arr[1].x > 0 && arr[2].x > 0 && arr[3].x > 0) {
					for (int i = 0; i < arr.size(); ++i) {
						auto it = std::find(allblocks.begin(), allblocks.end(), arr[i] + sf::Vector2i(-1, 0));
						if (it != allblocks.end()) {
							next1 = true;
						}
					}
					if (!next1) {
						for (auto &ar : arr)
							ar.x -= 1;
						next1 = false;
					}
				}
				else if (event.key.code == sf::Keyboard::Right && arr[2].x < 9 && arr[0].x < 9 && arr[1].x < 9 && arr[3].x < 9) {
					for (int i = 0; i < arr.size(); ++i) {
						auto it = std::find(allblocks.begin(), allblocks.end(), arr[i] + sf::Vector2i(1, 0));
						if (it != allblocks.end()) {
							next1 = true;
						}
					}if (!next1) {
						for (auto &ar : arr)
							ar.x += 1;
						next1 = false;
					}
				}		
				else if (event.key.code == sf::Keyboard::Down) speed = 10;
			}
		}
		window.clear(sf::Color::White);
		window.draw(text);
		window.draw(text1);
		for (int i = 0; i < arr.size(); ++i)
			sprites[sprites.size() - 4 + i].setPosition(xini + arr[i].x*w / 10.f, yini + arr[i].y*w / 10.f);
		for (auto sp : sprites)
			window.draw(sp);
		for (auto sp : sp1)
			window.draw(sp);
		window.draw(vertices, 5, sf::LineStrip);
		window.display();
	}
	return 0;
}

在这里插入图片描述
整个代码不是很简洁,一共300行,注释也很少,也存在一些小bug,可能看起来有点废劲。当然重要的是那个过程。有什么问题欢迎在评论区讨论。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值