sfml c++ 俄罗斯方块

字库文件“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();
    }
}
 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值