iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 5
0
自我挑戰組

寫遊戲初體驗系列 第 5

Day5 SFML input

  • 分享至 

  • xImage
  •  

輸入

輸入偵測有兩種:Real-time 跟 Event,主要的差別在於:

  • Real-time
    • 可以預期在特定時間發生
    • 是「實時」的,意思是當下的狀態
    • e.g.
      • gameplay
  • Event
    • 不預期發生時間,只關心狀態的轉變 e.g. 從沒按下到按下按鍵
    • e.g.
      • GUI的文字輸入框

一個最明顯的例子是:偵測按鍵持續按下
如果是用 real-time 則不會有延遲
如果適用 event 則會有 delay 才會是連續的

這裡我主要介紹的會是 Real-time的輸入,一般對於角色的輸入都是用 Real-time的輸入。

  • 滑鼠按鍵
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
    // 左鍵按下
}
  • 滑鼠位置

    • 獲取位置
    // global position (相對於整個桌面的座標)
    sf::Vector2i globalPos = sf::Mouse::getPosition();
    
    // window position (相對於視窗的座標)
    sf::Vector2i localPos = sf::Mouse::getPosition(window);
    
    • 設定位置
    // Set global position (相對於整個桌面的座標)
    sf::Mouse::setPosition(sf::Vector2i(10, 50));
    // Set local position (相對於視窗的座標)
    sf::Mouse::setPosition(sf::Vector2i(10, 50), window);
    
  • 滑鼠滾輪只能透過 event 偵測 by MouseWheelScrolled event

小試身手

既然我們知道如何創建窗口,如何畫圖以及如何處裡輸入,我們就來試試看一個能夠根據鍵盤輸入移動的Sprite吧!

GoGo

include 我們所要的library

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>

int main() {

    return EXIT_SUCCESS;
}

接著創建視窗以及視窗的事件處理

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>

int main() {

    sf::RenderWindow window(sf::VideoMode(1280, 720), "SFML window");

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

    window.display();
    
    return EXIT_SUCCESS;
}

接著匯入Texture建立Sprite並將它繪製到螢幕上

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>

int main() {

    sf::RenderWindow window(sf::VideoMode(1280, 720), "SFML window");

    sf::Texture texture;
    if (!texture.loadFromFile("1.png"))
        return EXIT_FAILURE;
    sf::Sprite sprite(texture);

    sprite.setPosition(sf::Vector2f(400.f, 260.f));
    sprite.setScale(sf::Vector2f(0.1f, 0.1f));

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

    window.clear();

    window.draw(sprite);

    window.display();
    
    return EXIT_SUCCESS;
}

記得每次draw()之前要將window清掉,不清掉畫部的畫前一次畫的會繼續留在螢幕上喔

最後的最後加上使用著輸入

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(1280, 720), "SFML window");

    sf::Texture texture;
    if (!texture.loadFromFile("1.png"))
        return EXIT_FAILURE;
    sf::Sprite sprite(texture);

    sprite.setPosition(sf::Vector2f(400.f, 260.f));
    sprite.setScale(sf::Vector2f(0.1f, 0.1f));

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

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
            sprite.move(-0.1, 0);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
            sprite.move(0.1, 0);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
            sprite.move(0, -0.1);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
            sprite.move(0, 0.1);


        window.clear();

        window.draw(sprite);

        window.display();
    }
    return EXIT_SUCCESS;
}

這樣就大功告成啦!


上一篇
Sprite and Texture
下一篇
Day6 基本的遊戲循環
系列文
寫遊戲初體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言