字库文件“arial.ttf”要拷贝到同目录下
sfml没有自带字库,如果要使用sf::Text,就一定要使用sf::Font,那么必须要用到外部字库,否则不显示。
#include <SFML/Graphics.hpp>
#include <time.h>
#include <ctime>
void Delay(int time)//time*1000为秒数
{
clock_t now = clock();
while (clock() - now < time);
}
const int M = 20; //高
const int N = 10; //宽
int size = 30;
int field[M][N] = { 0 }; //积木池
struct Point
{
int x, y;
}a[4], b[4]; //积木坐标保存
int f[7][4] =
{
1,3,5,7,
2,4,5,7,
3,5,4,6,
3,5,4,7,
2,3,5,7,
3,5,7,6,
2,3,4,5,
};
// 0,1
// 0,1
// 0,1
// 0,1 对应的数组序列是1,3,5,7
// 0,0
// 1,0
// 1,1
// 0,1 对应的数组序列是2,4,5,7
bool check() //检测积木位置是否合理
{
for (int i = 0; i < 4; i++)
{
if (a[i].x < 0 || a[i].x >= N || a[i].y >= M)
return 0;
else if (field[a[i].y][a[i].x]) return 0;
}
return 1;
};
int main()
{
int dx = 0;
bool rotate = 0;
float times = 0;
float delay = 0.4;
int layer = 0;
sf::Clock clock;
sf::RenderWindow window(sf::VideoMode(N*size, (M+1)*size), "tetris");
sf::RectangleShape rect1(sf::Vector2f(size-1, size-1)); // 创建底色
rect1.setFillColor(sf::Color::White);
sf::RectangleShape rect2(sf::Vector2f(size - 1, size - 1)); // 创建积木
rect2.setFillColor(sf::Color::Red);
sf::RectangleShape rect3(sf::Vector2f(size - 1, size - 1)); // 已落地积木
rect3.setFillColor(sf::Color::Green);
sf::RectangleShape rect4(sf::Vector2f(size - 1, size - 1)); // 待销积木
rect4.setFillColor(sf::Color::Yellow);
int n = rand() % 7;
for (int i = 0; i < 4; i++) //将f数组对应的积木转化为坐标
{
a[i].x = f[n][i] % 2;
a[i].y = f[n][i] / 2;
}
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
return EXIT_FAILURE;
sf::Text text("Hello Tetris", font,25);
text.setPosition(1 * size,(M)*size );
text.setFillColor(sf::Color ::Yellow);
window.draw(text);
while (window.isOpen())
{
float time = clock.getElapsedTime().asSeconds();
clock.restart();
times += time;
sf::Event e;
while (window.pollEvent(e))
{
if (e.type == sf::Event::Closed)
window.close();
if (e.type == sf::Event::KeyPressed)
if (e.key.code == sf::Keyboard::Up)
rotate = true;
else if (e.key.code == sf::Keyboard::Left)
dx = -1;
else if (e.key.code == sf::Keyboard::Right)
dx = 1;
else if (e.key.code == sf::Keyboard::Down)
delay = 0;
else if (e.key.code == sf::Keyboard::B) //重新开始
{
dx = 0;
rotate = 0;
times = 0;
delay = 0.4;
layer = 0;
n = rand() % 7;
for (int i = 0; i < 4; i++)
{
a[i].x = f[n][i] % 2;
a[i].y = f[n][i] / 2;
}
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
{
field[i][j] =0;
}
std::string s_layer;
s_layer = std::to_string(layer);
s_layer = "layer:" + s_layer;
text.setString(s_layer);
window.draw(text);
Delay(0.2 * 1000);
}
}
//移动
for (int i = 0; i < 4; i++)
{
b[i] = a[i];
}
for (int i = 0; i < 4; i++)
a[i].x += dx;
if (!check())
{
for (int i = 0; i < 4; i++)
{
a[i] = b[i];
}
}
//旋转:公式如下:
//A(ax,ay),绕P(px,py)点,旋转β角度,得到的新位置C(cx,cy).
//x0=(ax-px)*cos(β)-(ay-py)*sin(β);
//y0=(ay-py)*cos(β)+(ax-px)*sin(β);
//cx=x0+px;
//cy=y0+py;
if (rotate)
{
for (int i = 0; i < 4; i++)
{
b[i] = a[i];
}
Point p = a[1];//旋转中心点
for (int i = 0; i < 4; i++)
{
int x0 = - (a[i].y - p.y);
int y0 = (a[i].x - p.x);
a[i].x = p.x + x0;
a[i].y = p.y + y0;
}
rotate = 0;
if (!check())
{
for (int i = 0; i < 4; i++)
{
a[i] = b[i];
}
}
}
//下落
if (times > delay)
{
for (int i = 0; i < 4; i++)
{
b[i] = a[i];
a[i].y += 1;
}
if (!check())
{
for (int i = 0; i < 4; i++)
{
field[b[i].y][b[i].x] = 1;
}
int n = rand()%7;
for (int i = 0; i < 4; i++)
{
a[i].x = f[n][i] % 2;
a[i].y = f[n][i] / 2;
}
}
times = 0;
}
//消层
int k = M - 1;
for (int i = M - 1; i > 0; i--)
{
int count = 0;
for (int j = 0; j < N; j++)
{
if (field[i][j]) count++;
field[k][j] = field[i][j];
}
if (count < N)
k--;
else
{
for (int j = 0; j < N; j++)
{
rect4.setPosition(j * size, i* size);
window.draw(rect4);
}
layer++;
std::string s_layer;
s_layer = std::to_string(layer);
s_layer = "layer:" + s_layer;
text.setString(s_layer);
window.draw(text);
window.display();
Delay(0.2 * 1000);
}
}
//绘图
dx = 0; rotate = 0; delay = 0.4;
window.clear();
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
rect1.setPosition(i * size, j * size);
window.draw(rect1);
}
}
for(int i=0;i<M;i++)
for (int j = 0; j < N; j++)
{
if (field[i][j] == 0) continue;
rect3.setPosition(j * size, i* size);
window.draw(rect3);
}
for (int i = 0; i < 4; i++)
{
rect2.setPosition(a[i].x * size, a[i].y* size);
window.draw(rect2);
}
window.draw(text);
window.display();
}
}