crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> KeyPress и KeyRelease, Реализация игровых клавиш (WASD)
AlexSMG95
  опции профиля:
сообщение 12.10.2014, 13:00
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 12.10.2014
Пользователь №: 4246

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем доброго времени суток.
Вообщем нужно реализовать отслеживание клавиш WASD как в играх, только в зависимости от нажатых клавиш должен формироваться массив из 4 значений принимающих 1 или 0 ,
Раскрывающийся текст
то есть зажал w получил массив 1000, зажал s получил 0100, зажал a получил 0010, зажал d получил 0001.
w+a - 1010
w+d - 1001
s+a - 0110
s+d - 0101

посоветовали использовать keypress и keyrelease
набросал такой код
Раскрывающийся текст

#include "dialog.h"
#include "ui_dialog.h"
#include<QKeyEvent>

Dialog:: Dialog(QWidget *parent) :
  QDialog(parent),
  ui(new Ui:: Dialog)
{
  ui->setupUi(this);
}

Dialog::~Dialog()
{
  delete ui;
}
int A[4];
bool key_w = false;
bool key_a = false;
bool key_s = false;
bool key_d = false;
QString Astr;
QString clear;
void Dialog::keyPressEvent(QKeyEvent *PressEvent)
{
  const int firstkeyEvent = PressEvent->key();

      if(firstkeyEvent == Qt::Key_W)
        {
          ui->UP_lb->setText("pressed");
          key_w = true;
        }
      if(firstkeyEvent == Qt::Key_S)
        {
          ui->DW_lb->setText("Pressed");
          key_s = true;
        }
      if(firstkeyEvent == Qt::Key_A)
        {
          ui->L_lb->setText("Pressed");
          key_a = true;
        }
      if(firstkeyEvent == Qt::Key_D)
        {
          ui->R_lb->setText("Pressed");
          key_d = true;
        }
      if(key_w == true){A[0] = 1;}
      else{A[0] = 0;}
      if(key_s == true){A[1] = 1;}
      else{A[1] = 0;}
      if(key_a == true){A[2] = 1;}
      else{A[2] = 0;}
      if(key_d == true){A[3] = 1;}
      else{A[3] = 0;}
      if(key_w == true && key_s == true){A[0] = 0;A[1] = 0;}
      if(key_a == true && key_d == true){A[2] = 0;A[3] = 0;}
      if(key_w == true && key_a == true && key_d){A[0] = 0;A[2] = 0;A[3] = 0;}
      if(key_s == true && key_a == true && key_d){A[1] = 0;A[2] = 0;A[3] = 0;}
      for(int i = 0; i < 4; i++)
      {
           Astr += QString::number(A[i]);
      }
      ui->SIG_lb->setText(Astr);
      Astr = clear;
}
void Dialog::keyReleaseEvent(QKeyEvent *ReleaseEvent)
{
  const int secondkeyEvent = ReleaseEvent->key();
      if(secondkeyEvent == Qt::Key_W)
        {
          ui->UP_lb->setText("UP");
          key_w = false;
        }
      if(secondkeyEvent == Qt::Key_S)
        {
          ui->DW_lb->setText("Down");
          key_s = false;
        }
      if(secondkeyEvent == Qt::Key_D)
        {
          ui->R_lb->setText("Right");
          key_d = false;
        }
      if(secondkeyEvent == Qt::Key_A)
        {
          ui->L_lb->setText("Left");
          key_a = false;
        }
      if(key_w == true){A[0] = 1;}
      else{A[0] = 0;}
      if(key_s == true){A[1] = 1;}
      else{A[1] = 0;}
      if(key_a == true){A[2] = 1;}
      else{A[2] = 0;}
      if(key_d == true){A[3] = 1;}
      else{A[3] = 0;}
      if(key_w == true && key_s == true){A[0] = 0;A[1] = 0;}
      if(key_a == true && key_d == true){A[2] = 0;A[3] = 0;}
      if(key_w == true && key_a == true && key_d){A[0] = 0;A[2] = 0;A[3] = 0;}
      if(key_s == true && key_a == true && key_d){A[1] = 0;A[2] = 0;A[3] = 0;}
      for(int i = 0; i < 4; i++)
      {
           Astr += QString::number(A[i]);
      }
      ui->SIG_lb->setText(Astr);
      Astr = clear;
}

И столкнулся с проблемой на форме клавиши определяются правильно и массив тоже формируется правильно, но при отправки данных в порт (если важно TCP порт) то получается при зажатии W получаю такую картину сигналов
Раскрывающийся текст
1000
0000
1000
0000

зажал W+A получаю следующее
Раскрывающийся текст
1010
1000
1010
1000

И дальше в таком духе!
Подскажите где ошибка!
Заранее благодарю!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 12.10.2014, 15:57
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Это происходит из за автоповтора.
События, сгенерированные автоповтором можно отделить по флагу isAutoRepeat
http://qt-project.org/doc/qt-4.8/qkeyevent.html#isAutoRepeat
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AlexSMG95
  опции профиля:
сообщение 12.10.2014, 17:29
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 12.10.2014
Пользователь №: 4246

Спасибо сказали: 0 раз(а)




Репутация:   0  


Спасибо!
Если не затруднит приведите пожалуйста пример как использовать данное свойство, а то с английским у меня туговато!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 13.10.2014, 0:05
Сообщение #4


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


void Dialog::keyPressEvent(QKeyEvent *PressEvent)
{
  if( PressEvent->isAutoRepeat() ) { ...; return; }
  ... // Обработка клавиш
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AlexSMG95
  опции профиля:
сообщение 13.10.2014, 9:20
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 12.10.2014
Пользователь №: 4246

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 13.10.2014, 0:05) *
void Dialog::keyPressEvent(QKeyEvent *PressEvent)
{
  if( PressEvent->isAutoRepeat() ) { ...; return; }
  ... // Обработка клавиш



Благодарю!
И еще последний вопрос, если я правильно понял "isAutoRepeat" возвращает всем булеан значениям false, и получается использовать keyRelease не нужно?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AlexSMG95
  опции профиля:
сообщение 13.10.2014, 11:13
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 12.10.2014
Пользователь №: 4246

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(AlexSMG95 @ 13.10.2014, 9:20) *
Цитата(lanz @ 13.10.2014, 0:05) *
void Dialog::keyPressEvent(QKeyEvent *PressEvent)
{
  if( PressEvent->isAutoRepeat() ) { ...; return; }
  ... // Обработка клавиш



Благодарю!
И еще последний вопрос, если я правильно понял "isAutoRepeat" возвращает всем булеан значениям false, и получается использовать keyRelease не нужно?


Все вопрос снят! Большое спасибо!

В итоге сделал так
void Dialog::keyPressEvent(QKeyEvent *keyEvent)
{
    if(keyEvent->key() == Qt::Key_W && !keyEvent->isAutoRepeat())
      {
        ui->UP_lb->setText("pressed");
        key_w = true;
      }
void Dialog::keyReleaseEvent(QKeyEvent *keyEvent)
{

      if(keyEvent->key() == Qt::Key_W && !keyEvent->isAutoRepeat())
        {
          ui->UP_lb->setText("Up");
          key_w = false;
        }
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 2:45