2013-05-04 4 views
0

Я делаю игровой проект с SFML, и я столкнулся с небольшой проблемой,Клавиатура в SFML

Вот мой код:

#include <SFML/Graphics.hpp> 
#include <string> 
#include <iostream> 
using namespace std; 
using namespace sf; 
int main() { 

    sf::RenderWindow Window; 
    Window.create(sf::VideoMode(490, 485), "My First Sfml Game"); 

    sf::Texture pTexture1; 
    sf::Sprite playerImage; 



    if (!pTexture1.loadFromFile("Data/dots.png")) 
     std::cout << "error could not load player image" << std::endl; 

    playerImage.setTexture(pTexture1); 

    sf::Texture pTexture2; 
    sf::Sprite lineImage; 
    if (!pTexture2.loadFromFile("Data/line.png")) 
     std::cout << "error could not load player image" << std::endl; 
    lineImage.setTexture(pTexture2); 

    int v; 

    while (Window.isOpen()) { 
     sf::Event event; 
     while (Window.pollEvent(event)) { 
      switch (event.type) { 
      case sf::Event::Closed: 
       Window.close(); 
       break; 
      case Event::KeyPressed: 
       if (event.key.code == Keyboard::Right) 
        lineImage.move(5, 0); 
       else if (event.key.code == Keyboard::Left) 
        lineImage.move(-5, 0); 
       else if (event.key.code == Keyboard::Up) 
        lineImage.move(0, -5); 
       else if (event.key.code == Keyboard::Down) 
        lineImage.move(0, 5); 
       else if (event.key.code == Keyboard::Space) 
        lineImage.setRotation(90); 
       break; 
      case Event::KeyReleased: 
       if (event.key.code == Keyboard::Right) 
        lineImage.move(0, 0); 
       else if (event.key.code == Keyboard::Left) 
        lineImage.move(-0, 0); 
       else if (event.key.code == Keyboard::Up) 
        lineImage.move(0, -0); 
       else if (event.key.code == Keyboard::Down) 
        lineImage.move(0, 0); 
       else if (event.key.code == Keyboard::Space) 
        lineImage.setRotation(90); 
       break; 
      } 
      if (event.type == Event::KeyReleased && event.key.code == Keyboard::Space) 
       lineImage.setRotation(180); 
     } 


     Window.draw(playerImage); 
     Window.draw(lineImage); 
     Window.display(); 
    } 
    return 0; 
} 

изображения в коде здесь: postimg.org/gallery/ 71ufmoi/da508bc3/

проблема в том, что мне нужно повернуть lineImage, когда я нажимаю пробел, но когда я нажимаю пробел, он поворачивает 90, а затем снова 90! Мне нужно сделать его стабильным, когда я нажимаю пробел, он вращает 90, затем, когда я снова нажимаю пробел, он поворачивает 90 на оригинал! Еще одна проблема, с которой я сталкиваюсь, - это то, что я делаю игру в виде точек, так как я могу сделать логику линии, чтобы я мог позволить ей между двумя точками, когда я нажимаю клавишу ввода?

ответ

3

Мне нужно сделать его стабильным, когда я нажимаю пробел, он вращает 90, а затем, когда я нажимаю пробел, он поворачивает 90 к оригиналу!

Вместо использования setRotation вы можете использовать rotate и держать угол в переменной так, что программе:

  • имеет меньше магические числа! См (What is a magic number, and why is it bad?)
  • может инвертировать вращение, когда пробел ударен: angle = -angle;

Вы бы вращение только тогда, когда клавиша отпущена.

Кроме того, рассмотрите возможность использования switch вместо связки if-else. Это уменьшит дублирование кода event.key.code == и сделает ваш код более читаемым.

Обратите внимание, что переменная Window имеет несогласованное имя: все остальные переменные начинаются с нижнего регистра, но этого нет. Это не очень важно для такого небольшого фрагмента кода, но всегда рекомендуется придерживаться единого соглашения об именах по всей программе.

Таким образом, чтобы подвести итог, ваш код может выглядеть следующим образом:

// includes... 

int main(int, char**) { 
    // window and texture loading... 

    float rotationAngle = 90; 

    while (window.isOpen()) { 
     sf::Event event; 
     while (window.pollEvent(event)) { 
      switch (event.type) { 
       case Event::KeyReleased: 
        switch (event.key.code) { 
         case Keyboard::Space: 
          lineSprite.rotate(rotationAngle); 
          rotationAngle = - rotationAngle; 
          break; 

         // other cases... 
        } 
        break; 

       // other cases... 
      } 
     } 

     // drawing... 
    } 
} 

NB: Я переименовал lineImage в lineSprite, чтобы предотвратить путаницу с sf::Image и sf::Sprite.

EDIT:

Еще одна проблема, я это делаю многоточия игру так, как я могу сделать логику линии, поэтому я могу позволить его между двумя точками, когда я нажимаю клавишу ввода?

Вместо использования текстур я предпочел бы использовать вершины. См. the corresponding tutorial here

Обычно вы должны иметь (динамический) массив вершин для рисования линий.

EDIT 2:

Давайте более concreate и написать несколько строк кода.

Вы можете объявить массив вершин, как это:

sf::VertexArray lines(sf::Lines); 

Сначала она пуста, но вы можете легко добавить новые строки, когда это необходимо:

// the player connects dots d1 and d2 
lines.append(sf::Vertex(d1.position)); 
lines.append(sf::Vertex(d2.position)); 

И, как всегда, вы хотите чтобы нарисовать линии к окну. Вы можете добиться этого так:

window.draw(lines); 

Вы можете найти соответствующую документацию здесь:

+0

Большое спасибо это работает: D и о втором вероят Я играю в Dots, поэтому хочу подключить две точки с помощью lineSprite, когда пользователь нажимает enter, а второй пользователь делает то же самое, пока он не образует квадрат, это проблема, что я могу использовать для этого!? Потому что я новичок в SFML! Еще раз спасибо за помощь ^^ –

+0

Хорошо, получилось. См. Мой отредактированный ответ. – Hiura

+0

так что моего пути недостаточно!? , я вижу его более простым, чем массивы вершин: D, srry, но если вы можете прояснить его больше, я буду благодарен ^^ –

Смежные вопросы