iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
Software Development

三十天內用C++寫出一個小遊戲系列 第 27

Day 27 - 看起來很無聊又很好玩的遊戲開發

Intro

這篇主要會講解一些 SFML 中常用到的內容,效果,還有要怎麼用他們。

然後我會照 影片中寫的程式照做一遍 。

Getting Started

EX1:

會讓我們畫出視窗,還有一個圓形的圖案。

接下來

shape.move(2.5f, 0.f); // 這行就是讓圓形可以往我們設定的方向移動。
window.draw(shape); // 這行可以讓視窗畫出我們的 shape(也就是圓形)
#include<SFML/Graphics.hpp>
using namespace sf;
int main()
{
    RenderWindow window(VideoMode(800, 600), "My window");// for size, "name"
    window.setFramerateLimit(60); // limit fps to prevent overloading on graphic card.

    CircleShape shape(50.f); // 呼叫一個 圓形 叫做 shape
 

        // run the program as long as the window is open
        while (window.isOpen()) // if not, it'll shut down as soon as you open it
        {
            // check all the window's events that were triggered since the last iteration of the loop
            Event event;
            while (window.pollEvent(event))
            {
                // "close requested" event: we close the window
                if (event.type == Event::Closed)
                    window.close();
            }

            // Update: for charcters [press w] -> [move forward]
            // you have to update the screen to see the position change.
            shape.move(5.f, 0.f); //讓圓形可以動

            // Draw: draw new things on the 
            window.clear(Color::Red); // 每一次畫的時候都需要把原本的清掉 

            window.draw(shape); // 要讓螢幕可以畫出來

            window.display();// 就是展示你前面做的更新 & draw
        }

    return 0;
}

那如果我們沒有把 window.clear() 寫上去的話,這時候那個圓形又在動,就會變成這樣:


前面的圖片沒有刪掉,後面又跑出來。

那如果你想要讓背景換顏色,就可以用 window.clear(Color::Red); 你的背景就會變成紅色!

EX2:

#include<SFML/Graphics.hpp>
using namespace sf;
int main()
{
    RenderWindow window(VideoMode(1080, 720), "My window");
    window.setFramerateLimit(60); 

    // Vector2f Vector2i SFML會把兩個 float 或是 integer 宣告在一起 (一起使用)
    //Vector2f vec(10.f, 12.f);
    //vec.x; //會得到 x value
    //vec.y; //就會得到 y

    CircleShape circle(50.f); // 圓形
    circle.setPosition(Vector2f(0.f, 0.f));
    circle.setFillColor(Color(144, 156, 189));
    
    RectangleShape rect(Vector2f(400.f, 200.f)); // 矩形
    rect.setPosition(Vector2f(100.f, 100.f));
    rect.setFillColor(Color(255, 255, 200, 200));

    Vertex line[] =

    {
        Vertex(Vector2f(900.f, 500.f)), // 起點
        Vertex(Vector2f(1000.f, 500.f)) // 終點
    };

    //凸多邊形:
    ConvexShape convex;
    convex.setPosition(Vector2f(400.f, 600.f));
    convex.setPointCount(5);
 
    //define the points
    convex.setPoint(0, Vector2f(0, 0));
    convex.setPoint(1, Vector2f(150, 10));
    convex.setPoint(2, Vector2f(120, 90));
    convex.setPoint(3, Vector2f(30, 100));
    convex.setPoint(4, Vector2f(0, 50));

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

        // Update:

        // Draw:
        window.clear(); 
        //draw things
        window.draw(circle);
        window.draw(rect);
        window.draw(line, 2, Lines);
        window.draw(convex);
        //display
        window.display();
    }

    return 0;
}

這段教你怎麼印出圖形,還有一些功能的介紹。

這些圖形跑出來會長這樣:


圖形功能介紹:

要製造甚麼形狀:

  • 圓形: CircleShape
  • 正多邊形:
    • CircleShape circle(半徑(就是這個圖形外切圓半徑), 幾邊)
    • 也可以用 .setRadius 設置半徑;.setPointCount 設置邊數
  • 長方形: RectangleShape rec(Vectorsf(長, 寬))
  • 線: RectangleShape line(Vectorsf(150.f, 5.f))
  • 沒粗度的線:
//製作
Vertex line[] = 

{
	Vertex(Vector2f(10.f, 10.f)), // 起點
	Vertex(Vector2f(150.f, 150.f)) // 終點
};

//畫
window.draw(line, 2, Lines);

圖形可以做甚麼事?

  • shapeName.setFillColor(Color(R, G, B)) →上色(整塊)
  • shapeName.setOutlineThickness(10.f); →設定外框粗細,外框預設會在圖形的最外側
  • shapeName.setOutlineColor(R, G, B);→設定外框顏色。
  • shapeName.rotate(45.f) →按照 45.f 這個速度旋轉(以圖形的坐上角為軸)。
  • shapeName.setPosition(Vector2f(x, y)) → 放在(x, y)位置。
  • shapeName.setScale() → 縮放大小。

EX3:

#include<iostream>
#include<SFML\Graphics.hpp>
#include<SFML\Window.hpp>
#include<SFML\System.hpp>
using namespace sf;
// 做出一個小遊戲,用 WSAD控制前後左右

void Update(int &keyTime, RenderWindow &window, RectangleShape &square);
void Draw(RenderWindow &window, RectangleShape& square);

int main() 
{	
	int keyTime = 8;

	RenderWindow window(VideoMode(640, 480), "Simple Square Swag", Style::Default);
	window.setFramerateLimit(120);

	RectangleShape square(Vector2f(100.f, 100.f));
	square.setFillColor(Color::Red);
	square.setPosition(window.getSize().x / 2, window.getSize().y / 2);

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

			if (event.KeyPressed && event.key.code == Keyboard::Escape)
				window.close();
		}

		//Update
		Update(keyTime, window, square);
		//Draw
		Draw(window, square);

	}

}

void Update(int &keyTime, RenderWindow &window, RectangleShape& square) // 控制方塊的前後左右
{
	if (keyTime < 8)
		keyTime++;

	if (Keyboard::isKeyPressed(Keyboard::A) && square.getPosition().x > 0) //  square.getPosition().x > 0 是設置邊界
	{
		square.move(-5.f, 0.f);
		keyTime = 0;
	}
	if (Keyboard::isKeyPressed(Keyboard::D) && square.getPosition().x + square.getSize().x < window.getSize().x) //square.getPosition().x (方塊的(0, 0)) + square.getSize().x (方塊的長度) < window.getSize().x(視窗的長度)
	{	
		square.move(5.f, 0.f);
		keyTime = 0;
	}
	if (Keyboard::isKeyPressed(Keyboard::W) && square.getPosition().y > 0)
	{
		square.move(0.f, -5.f);
		keyTime = 0;
	}
	if (Keyboard::isKeyPressed(Keyboard::S) && square.getPosition().y + square.getSize().y < window.getSize().y) //
	{	
		square.move(0.f, 5.f);
		keyTime = 0;
	}
	if (Mouse::isButtonPressed(Mouse::Left)) // 左鍵按下去會變成藍色
	{	
		square.setFillColor(Color::Blue);
		keyTime = 0;
	}
	else
	{
		square.setFillColor(Color::Red); //不按左鍵就是紅色
	}
}

void Draw(RenderWindow &window, RectangleShape& square)
{	
	window.clear(Color::White); 

	//Draw stuff
	window.draw(square);
	window.display();
}

在這段程式,可以學到把一個方塊印出來,如何用WSAD去控制這個方塊,還有設置邊界(就是到邊邊就不能動了)。

影片
(超出去是因為螢幕錄影不知道為什麼會這樣QQ)
大概長這樣。

Thoughts

我先把我的這次的遊戲目標分成三個部分

  • 要處理地圖 (也就是背景)
  • 要處理角色顯示 (前後左右移動、滑鼠瞄準)
  • 要處理滑鼠問題

Ref

  • 一樣也是 這個 YouTuber 的影片!

SFML Tutorials


上一篇
Day 26 - 你有沒有玩過LOL、特、CS、SF、楓之谷、APEX?
下一篇
Day 28 - 設籍有關涉及射擊的射擊遊戲
系列文
三十天內用C++寫出一個小遊戲30

尚未有邦友留言

立即登入留言