c++小游戏制作:01俄罗斯方块

先看效果图:

首先需要先下载安装SFML安装包,这里我下载的是64位的

 然后解压放在一个文件夹下,记好路径

然后要在VS中加入路径

在VC++目录中配置包含目录和库目录

包含目录的路径:D:\SFML-2.5.1\include

库目录的路径:D:\SFML-2.5.1\lib

然后在链接器-输入-添加依赖项中配置以下几个:

sfml-window-d.lib

sfml-system-d.lib

sfml-graphics-d.lib

sfml-audio-d.lib

 

 运行代码时弹出报错

由于找不到sfml-window-d-2.dll,无法继续执行代码。重新安装程序可能会解决此问题。

 这时候我们要把解压的sfml的bin文件夹下的内容,拷贝到当前代码程序的x64/Debug中去。

 再次运行就会发现可以了。

完整的代码如下:

#include <SFML/Graphics.hpp>
#include <time.h>
using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};

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()
{
    srand(time(0));

    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t1, t2, t3;
    t1.loadFromFile("images/tiles.png");
    t2.loadFromFile("images/background.png");
    t3.loadFromFile("images/frame.png");

    Sprite s(t1), background(t2), frame(t3);

    int dx = 0; bool rotate = 0; int colorNum = 1;
    float timer = 0, delay = 0.3;

    Clock clock;

    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }

        if (Keyboard::isKeyPressed(Keyboard::Down)) delay = 0.05;

        /*< -Move -> ///*/
            for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].x += dx; }
        if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
            if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];
        }

        ///Tick//
        if (timer > 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] = colorNum;

                colorNum = 1 + rand() % 7;
                int n = rand() % 7;
                for (int i = 0; i < 4; i++)
                {
                    a[i].x = figures[n][i] % 2;
                    a[i].y = figures[n][i] / 2;
                }
            }

            timer = 0;
        }

        ///check lines//
        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--;
        }

        dx = 0; rotate = 0; delay = 0.3;

        /// draw//
            window.clear(Color::White);
        window.draw(background);

        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * 18, i * 18);
                s.move(28, 31); //offset
                window.draw(s);
            }

        for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(colorNum * 18, 0, 18, 18));
            s.setPosition(a[i].x * 18, a[i].y * 18);
            s.move(28, 31); //offset
            window.draw(s);
        }

        window.draw(frame);
        window.display();
    }

    return 0;
}

 代码梳理:

首先是创建一个320×480的游戏屏幕,设置游戏的主循环事件


#include<SFML/Graphics.hpp>
#include<time.h>
 
using namespace sf;
 
int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");
 
    while (window.isOpen())
    {
        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
            {
                window.close();
            }
        }
 
        window.clear(Color::White);
        window.display();
    }
 
    return 0;
}

 把样式图片通过纹理渲染在界面上,这里我们读取的是当前代码文件夹下的images/tiles.png图片。

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

using namespace sf;

int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    //s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

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

        window.clear(Color::White);
        window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

 s.setTextureRect(IntRect(0, 0, 18, 18))将矩形不同颜色的小方块分割出第一个

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

using namespace sf;

int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

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

        window.clear(Color::White);
        window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}

 定义方框的样式(7种)

先定义一个8格的2x4矩形,然后根据编号定义形状。每个形状都是有四个小方块组成。

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};

int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    while (window.isOpen())
    {
        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
            {
                window.close();
            }
        }
        int n = 3;
        for (int i = 0; i < 4; i++)
        {
            a[i].x = figures[n][i] % 2;
            a[i].y = figures[n][i] / 2;
        }
        window.clear(Color::White);
        for (int i = 0; i < 4; i++)
        {
            s.setPosition(a[i].x * 18, a[i].y * 18);
            window.draw(s);
        }
        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

通过更改n的数值得到不同的俄罗斯方块n=5时

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};

int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    while (window.isOpen())
    {
        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
            {
                window.close();
            }
        }
        int n = 5;
        for (int i = 0; i < 4; i++)
        {
            a[i].x = figures[n][i] % 2;
            a[i].y = figures[n][i] / 2;
        }
        window.clear(Color::White);
        for (int i = 0; i < 4; i++)
        {
            s.setPosition(a[i].x * 18, a[i].y * 18);
            window.draw(s);
        }
        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

 

 实现按键进行旋转(向上建)和平移(左右建),旋转中心为任意形状的第二个小方格

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};

int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    int dx = 0; bool rotate = 0; int colorNum = 1;

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

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }
        /*< -Move -> ///*/
        for (int i = 0; i < 4; i++) a[i].x += dx;

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
        }

        int n = 5;
        if(a[0].x==0)
        for (int i = 0; i < 4; i++)
        {
            a[i].x = figures[n][i] % 2;
            a[i].y = figures[n][i] / 2;
        }
        window.clear(Color::White);
        for (int i = 0; i < 4; i++)
        {
            s.setPosition(a[i].x * 18, a[i].y * 18);
            window.draw(s);
        }
        dx = 0; rotate = 0;
        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

 然后实现自由落体

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};

int main()
{
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    int dx = 0; bool rotate = 0; int colorNum = 1;
    float timer = 0, delay = 0.3;

    Clock clock;
    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }
        /*< -Move -> ///*/
        for (int i = 0; i < 4; i++) a[i].x += dx;

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
        }

        ///Tick//
        if (timer > delay)
        {
            for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].y += 1; }
            timer = 0;
        }

        int n = 5;
        if(a[0].x==0)
        for (int i = 0; i < 4; i++)
        {
            a[i].x = figures[n][i] % 2;
            a[i].y = figures[n][i] / 2;
        }
        window.clear(Color::White);
        for (int i = 0; i < 4; i++)
        {
            s.setPosition(a[i].x * 18, a[i].y * 18);
            window.draw(s);
        }
        dx = 0; rotate = 0;
        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

 这时候的自由落体会直接调出界面外,所以还需要加一个截止横线

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};


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()
{    
    srand(time(0));
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    int dx = 0; bool rotate = 0; int colorNum = 1;
    float timer = 0, delay = 0.3;

    Clock clock;
    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }
        /*< -Move -> ///*/
            for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].x += dx; }
        if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
        }

        ///Tick//
        if (timer > 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] = colorNum;

                colorNum = 1 + rand() % 7;
                int n = rand() % 7;
                for (int i = 0; i < 4; i++)
                {
                    a[i].x = figures[n][i] % 2;
                    a[i].y = figures[n][i] / 2;
                }
            }

            timer = 0;
        }

        
        dx = 0; rotate = 0;
        window.clear(Color::White);

        /// draw//
        window.clear(Color::White);

        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * 18, i * 18);
                window.draw(s);
            }


        for (int i = 0; i < 4; i++)
        {
            s.setPosition(a[i].x * 18, a[i].y * 18);
            window.draw(s);
        }

        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

 然后固定每次下落的颜色,并且有加速下落功能

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};


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()
{    
    srand(time(0));
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    int dx = 0; bool rotate = 0; int colorNum = 1;
    float timer = 0, delay = 0.3;

    Clock clock;
    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }

        if (Keyboard::isKeyPressed(Keyboard::Down)) delay = 0.05;


        /*< -Move -> ///*/
            for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].x += dx; }
        if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
        }

        ///Tick//
        if (timer > 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] = colorNum;

                colorNum = 1 + rand() % 7;
                int n = rand() % 7;
                for (int i = 0; i < 4; i++)
                {
                    a[i].x = figures[n][i] % 2;
                    a[i].y = figures[n][i] / 2;
                }
            }

            timer = 0;
        }

        
        dx = 0; rotate = 0; delay = 0.3;
        window.clear(Color::White);

        /// draw//
        window.clear(Color::White);

        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * 18, i * 18);
                window.draw(s);
            }


        for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(colorNum * 18, 0, 18, 18));
            s.setPosition(a[i].x * 18, a[i].y * 18);
            s.move(28, 31); //offset
            window.draw(s);
        }

        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

 在加上一行满足要求后,删除功能

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

using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};


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()
{    
    srand(time(0));
    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t;//++++++++++++++++++++++++
    t.loadFromFile("images/tiles.png");//++++++++++++++++++++++++
    Sprite s(t);//++++++++++++++++++++++++
    s.setTextureRect(IntRect(0, 0, 18, 18));//++++++++++++++++++++++++

    int dx = 0; bool rotate = 0; int colorNum = 1;
    float timer = 0, delay = 0.3;

    Clock clock;
    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }

        if (Keyboard::isKeyPressed(Keyboard::Down)) delay = 0.05;


        /*< -Move -> ///*/
            for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].x += dx; }
        if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
        }

        ///Tick//
        if (timer > 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] = colorNum;

                colorNum = 1 + rand() % 7;
                int n = rand() % 7;
                for (int i = 0; i < 4; i++)
                {
                    a[i].x = figures[n][i] % 2;
                    a[i].y = figures[n][i] / 2;
                }
            }

            timer = 0;
        }

        
        dx = 0; rotate = 0; delay = 0.3;
        window.clear(Color::White);
        ///check lines//
        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--;
        }

        dx = 0; rotate = 0; delay = 0.3;

        /// draw//
        window.clear(Color::White);

        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * 18, i * 18);
                window.draw(s);
            }


        for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(colorNum * 18, 0, 18, 18));
            s.setPosition(a[i].x * 18, a[i].y * 18);
            s.move(28, 31); //offset
            window.draw(s);
        }

        //window.draw(s);//++++++++++++++++++++++++
        window.display();
    }

    return 0;
}
 

最后加上背景图片即可,完整代码如下:

#include <SFML/Graphics.hpp>
#include <time.h>
using namespace sf;

const int M = 20;
const int N = 10;

int field[M][N] = { 0 };

struct Point
{
    int x, y;
} a[4], b[4];

int figures[7][4] =
{
    1,3,5,7, // I
    2,4,5,7, // Z
    3,5,4,6, // S
    3,5,4,7, // T
    2,3,5,7, // L
    3,5,7,6, // J
    2,3,4,5, // O
};

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()
{
    srand(time(0));

    RenderWindow window(VideoMode(320, 480), "The Game!");

    Texture t1, t2, t3;
    t1.loadFromFile("images/tiles.png");
    t2.loadFromFile("images/background.png");
    t3.loadFromFile("images/frame.png");

    Sprite s(t1), background(t2), frame(t3);

    int dx = 0; bool rotate = 0; int colorNum = 1;
    float timer = 0, delay = 0.3;

    Clock clock;

    while (window.isOpen())
    {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while (window.pollEvent(e))
        {
            if (e.type == Event::Closed)
                window.close();

            if (e.type == Event::KeyPressed)
                if (e.key.code == Keyboard::Up) rotate = true;
                else if (e.key.code == Keyboard::Left) dx = -1;
                else if (e.key.code == Keyboard::Right) dx = 1;
        }

        if (Keyboard::isKeyPressed(Keyboard::Down)) delay = 0.05;

        /*< -Move -> ///*/
        for (int i = 0; i < 4; i++) { b[i] = a[i]; a[i].x += dx; }
        if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];

        //Rotate//
        if (rotate)
        {
            Point p = a[1]; //center of rotation
            for (int i = 0; i < 4; i++)
            {
                int x = a[i].y - p.y;
                int y = a[i].x - p.x;
                a[i].x = p.x - x;
                a[i].y = p.y + y;
            }
            if (!check()) for (int i = 0; i < 4; i++) a[i] = b[i];
        }

        ///Tick//
        if (timer > 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] = colorNum;

                colorNum = 1 + rand() % 7;
                int n = rand() % 7;
                for (int i = 0; i < 4; i++)
                {
                    a[i].x = figures[n][i] % 2;
                    a[i].y = figures[n][i] / 2;
                }
            }

            timer = 0;
        }

        ///check lines//
        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--;
        }

        dx = 0; rotate = 0; delay = 0.3;

        /// draw//
        window.clear(Color::White);
        window.draw(background);

        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
            {
                if (field[i][j] == 0) continue;
                s.setTextureRect(IntRect(field[i][j] * 18, 0, 18, 18));
                s.setPosition(j * 18, i * 18);
                s.move(28, 31); //offset
                window.draw(s);
            }

        for (int i = 0; i < 4; i++)
        {
            s.setTextureRect(IntRect(colorNum * 18, 0, 18, 18));
            s.setPosition(a[i].x * 18, a[i].y * 18);
            s.move(28, 31); //offset
            window.draw(s);
        }

        window.draw(frame);
        window.display();
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34904125/article/details/125754260
今日推荐