Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. mouse pos() returns wrong position
Forum Updated to NodeBB v4.3 + New Features

mouse pos() returns wrong position

Scheduled Pinned Locked Moved Solved Game Development
9 Posts 4 Posters 2.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    FlyDoodle
    wrote on last edited by FlyDoodle
    #1

    Hello !,
    So whenever i press right click, my character moves towards that position and its all working just fine till i get to the land
    check this video :
    https://streamable.com/cjo0d

    you can see when i print character current position and the positioning of the mouse ( when i press right click ) it gives me wrong coordinates ( from the mouse ) and i don't know why... Sea and Land are two different items ( classes ), both are QPixmap so maybe it has to do something with that ?
    Here is the main class code:

    Game.h:

    #ifndef GAME_H
    #define GAME_H
    #include "player.h"
    #include "button.h"
    #include "sea.h"
    #include "land.h"
    
    #include <QGraphicsView>
    #include <QGraphicsScene>
    #include <QObject>
    #include <QMouseEvent>
    #include <QGraphicsSceneMouseEvent>
    #include <QGraphicsScene>
    #include <QWidget>
    #include <QKeyEvent>
    
    class Game: public QGraphicsView{
        Q_OBJECT
    public:
        // this class stuff
        static QString in_room;
        Game(QWidget *parent=NULL);
        QGraphicsScene *scene;
        void menu();
        void createMap();
        void createPlayer();
        QPixmap darkenImage(QString image, float num);
    
        // other class stuff
        Player *player;
        Button *startButton;
        Button *quitButton;
        Land *land;
        Sea *sea;
    
        // static stuff
        int curr_pos_in_menu;
        void changeColorOfButton();
    
    public slots:
        void start();
        void mousePressEvent(QMouseEvent *event);
    };
    
    #endif // GAME_H
    

    Game.cpp:

    #include "game.h"
    #include "player.h"
    #include "button.h"
    
    #include <QGraphicsRectItem>
    #include <QGraphicsScene>
    #include <QDebug>
    #include <QApplication>
    #include <QTimer>
    #include <QFont>
    #include <QMessageBox>
    #include <fstream>
    #include <cmath>
    #include <QRect>
    #include <QDesktopWidget>
    #include <QtMath>
    
    QString Game::in_room = "menu";
    
    Game::Game(QWidget *parent)
    {
        scene = new QGraphicsScene();
        scene->setSceneRect(0,0,350,300);
        setFixedSize(350,300);
        setScene(scene);
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setBackgroundBrush(QBrush(QImage("red")));
        show();
        menu();
    }
    
    void Game::menu()
    {
        QGraphicsTextItem *title = new QGraphicsTextItem("NIGHTLESS");
        title->setPos(10,30);
        title->setFont(QFont("comic sans",40,70));
        scene->addItem(title);
    
        qDebug() << width();
        startButton = new Button("START", 200, 50);
        startButton->setPos(width()/2-startButton->rect().width()/2,125);
        connect(startButton,SIGNAL(clicked()),this,SLOT(start()));
        scene->addItem(startButton);
    
        quitButton = new Button("QUIT", 200, 50);
        quitButton->setPos(width()/2-quitButton->rect().width()/2,200);
        connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));
        scene->addItem(quitButton);
    
    }
    
    void Game::createMap()
    {
        land = new Land;
        land->setPos(0,0);
        scene->addItem(land);
    
        sea = new Sea;
        sea->setPos(0,0);
        scene->addItem(sea);
    }
    
    void Game::createPlayer()
    {
        player = new Player;
        player->setFlag(QGraphicsItem::ItemIsFocusable);
        player->setFocus();
        centerOn(player);
        scene->addItem(player);
    }
    
    QPixmap Game::darkenImage(QString file_name, float num)
    {
        QImage tmp( file_name );
    
        for(int i=0;i<tmp.height();i++)
        {
            for(int k=0;k<tmp.width();k++)
            {
                QColor color( tmp.pixel( k, i ) );   // changed this from pixelColor() to ensure alpha is copied
                if ( tmp.pixel(k,i) !=  0)    // modify only the pixels with non-zero alpha
                {
                    color.setRgb(color.red()*num,color.blue()*num,color.green()*num);
                    tmp.setPixelColor(k,i,color);
                }
            }
        }
    
        // Now, convert the image to a pixmap and set it on the graphics object
        QPixmap t = QPixmap::fromImage( tmp );
        return t;
    }
    
    void Game::start()
    {
        scene->clear();
        in_room = "world";
        // semi-transparent background
        /*
        QRect rec = QApplication::desktop()->screenGeometry();
        int height = rec.height();
        int width = rec.width();
        */
    
        setSceneRect(0,0,7097,7298);
        setFixedSize(1000,800);
        //setBackgroundBrush(QBrush(QImage(":/Images/Grass.png")));
        //showFullScreen();
    
        createMap();
        createPlayer();
    }
    
    void Game::mousePressEvent(QMouseEvent *event)
    {
        if(event->buttons() == Qt::RightButton && in_room!="menu"){
    
            QLineF ln(event->pos(),player->pos());
            int angle = -1 * ln.angle() + 460;
    
            int tmp = angle + 80;
            if(tmp>360)
                tmp-=360;
    
            if(angle > 360)
                angle += -360;
    
            player->setPlayerRotation(angle,tmp);
    
            QPointF t(event->pos());
            player->setDestination(event->pos());
    
        }
    }
    

    In the Land and Sea class i just setPixmap to the image, put them into the scene,set position and that is it.

    And i have one more question, how do i make a player stop when he reaches his destination ? i was thinking about making an QGraphicsRectItem whenever i press a right button and then checking if player has collided with that item and when he does he stops and then that item gets deleted or is there a better and easier way to do that, cause comparing mouse pos() and player pos() is not working.

    Any kind of help or advice is appreciated !!!

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      For the "collision" checking, you can take a look at the colliding mice example.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      F 1 Reply Last reply
      1
      • SGaistS SGaist

        Hi,

        For the "collision" checking, you can take a look at the colliding mice example.

        F Offline
        F Offline
        FlyDoodle
        wrote on last edited by
        #3

        @SGaist
        Hi thanks for the reply, i know how to do the collision thingy i just don't know if its worth doing it like that

        1 Reply Last reply
        0
        • BondrusiekB Offline
          BondrusiekB Offline
          Bondrusiek
          wrote on last edited by
          #4

          @FlyDoodle
          Hi,
          for collision detection you can use shape() method. The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.
          https://doc.qt.io/archives/qt-4.8/qgraphicsitem.html#shape
          For better conversion between view coordinates and scene coordinates you can use mapToScene(QPoint) method. This method returns the viewport coordinate point mapped to scene coordinates. See more:
          https://doc.qt.io/archives/qt-4.8/qgraphicsview.html#mapToScene
          Lastly, you can see my repo. I did simple game which use collision detecion. It may help you:

          bool Hero::onCollisionEnter(QString collider)
          {
              //Calculate a type of collision
              int sumOfCollision = 0;
              QList<QGraphicsItem*> colliderList = collidingItems();
              for(int idx = 0; idx < colliderList.size(); ++idx)
              {
                  if(collider == "Background")
                  {
                      //QGraphicsItem *item = qgraphicsitem_cast<BlueBackground*>(colliderList[idx]);
                      if(qgraphicsitem_cast<BlueBackground*>(colliderList[idx]))
                      {
                          sumOfCollision += 1;
                      }
                      //Brick | Evil1 | Bullet |
                      else if(qgraphicsitem_cast<Brick*>(colliderList[idx]) ||
                              qgraphicsitem_cast<Ground*>(colliderList[idx]) ||
                              qgraphicsitem_cast<Evil1*>(colliderList[idx]) ||
                              qgraphicsitem_cast<Bullet*>(colliderList[idx])
                              )
                      {
                          sumOfCollision += 1;
                      }
                  }
              }
              if(sumOfCollision == 1)
              {
                  return true;
              }
              return false;
          }
          

          Link to this repo: https://github.com/Przemekkkth/Qt-C-SimpleGame

          F 1 Reply Last reply
          1
          • BondrusiekB Bondrusiek

            @FlyDoodle
            Hi,
            for collision detection you can use shape() method. The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.
            https://doc.qt.io/archives/qt-4.8/qgraphicsitem.html#shape
            For better conversion between view coordinates and scene coordinates you can use mapToScene(QPoint) method. This method returns the viewport coordinate point mapped to scene coordinates. See more:
            https://doc.qt.io/archives/qt-4.8/qgraphicsview.html#mapToScene
            Lastly, you can see my repo. I did simple game which use collision detecion. It may help you:

            bool Hero::onCollisionEnter(QString collider)
            {
                //Calculate a type of collision
                int sumOfCollision = 0;
                QList<QGraphicsItem*> colliderList = collidingItems();
                for(int idx = 0; idx < colliderList.size(); ++idx)
                {
                    if(collider == "Background")
                    {
                        //QGraphicsItem *item = qgraphicsitem_cast<BlueBackground*>(colliderList[idx]);
                        if(qgraphicsitem_cast<BlueBackground*>(colliderList[idx]))
                        {
                            sumOfCollision += 1;
                        }
                        //Brick | Evil1 | Bullet |
                        else if(qgraphicsitem_cast<Brick*>(colliderList[idx]) ||
                                qgraphicsitem_cast<Ground*>(colliderList[idx]) ||
                                qgraphicsitem_cast<Evil1*>(colliderList[idx]) ||
                                qgraphicsitem_cast<Bullet*>(colliderList[idx])
                                )
                        {
                            sumOfCollision += 1;
                        }
                    }
                }
                if(sumOfCollision == 1)
                {
                    return true;
                }
                return false;
            }
            

            Link to this repo: https://github.com/Przemekkkth/Qt-C-SimpleGame

            F Offline
            F Offline
            FlyDoodle
            wrote on last edited by
            #5

            @Bondrusiek
            Hello !
            I tried using mapToScene before and i realized that when i was creating a QLine item between the player and the mouse position i forgot to use it and now it's working all fine.
            About that colliding thingy i will take a look, thank you !
            I have taken a look at your game and it's amazing, but i couldn't find how you did that player movement ? i tried looking for it and i found keyPressedEvent functions but there were no == Qt::key_W stuff and so on for movement, only for space.

            Tho i have one more question, how do i put waves (image) around my island in the game as the background. I want to make it so that for example 60 x 60 pixels waves fill the background ( or the item that is around the island ). Doing setBackgroundBrush(QBrush(QImage("path"))); will set the background the way i want it to, but the problem is when the player is moving and he gets near the water, he has to stop. I want to check if he is near the water using collision.I have class Land and class Sea and they are both QGraphicsPixmapItems and i could just check if the player has collided with the Sea class but the problem comes when i want the sea to be moving, and i would do that using 2 pictures and changing between them but changing pictures takes time especially if the image is that big and that's not optimal...

            BondrusiekB 1 Reply Last reply
            0
            • F FlyDoodle

              @Bondrusiek
              Hello !
              I tried using mapToScene before and i realized that when i was creating a QLine item between the player and the mouse position i forgot to use it and now it's working all fine.
              About that colliding thingy i will take a look, thank you !
              I have taken a look at your game and it's amazing, but i couldn't find how you did that player movement ? i tried looking for it and i found keyPressedEvent functions but there were no == Qt::key_W stuff and so on for movement, only for space.

              Tho i have one more question, how do i put waves (image) around my island in the game as the background. I want to make it so that for example 60 x 60 pixels waves fill the background ( or the item that is around the island ). Doing setBackgroundBrush(QBrush(QImage("path"))); will set the background the way i want it to, but the problem is when the player is moving and he gets near the water, he has to stop. I want to check if he is near the water using collision.I have class Land and class Sea and they are both QGraphicsPixmapItems and i could just check if the player has collided with the Sea class but the problem comes when i want the sea to be moving, and i would do that using 2 pictures and changing between them but changing pictures takes time especially if the image is that big and that's not optimal...

              BondrusiekB Offline
              BondrusiekB Offline
              Bondrusiek
              wrote on last edited by Bondrusiek
              #6

              @FlyDoodle , I used GetAsyncKeyState() (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate) to control my hero. This function monitore the status of the keyboard keys used by the function of the WinAPI.
              When you want to collide one object with another object, Objects must be QGraphicsItem or descendant. You can creater bigger geometry for shape() than bouncingRect() for detect collision and next:

                  QList<QGraphicsItem*> colliderList = collidingItems();
                  for(int idx = 0; idx < colliderList.size(); ++idx)
                  {
                          if(qgraphicsitem_cast<Land*>(colliderList[idx]))
                         {
                             //collide with Land
                         }
                         else if(qgraphicsitem_cast<Sea*>(colliderList[idx]))
                         {
                             //collide with Sea
                         }
              
              F 1 Reply Last reply
              1
              • BondrusiekB Bondrusiek

                @FlyDoodle , I used GetAsyncKeyState() (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate) to control my hero. This function monitore the status of the keyboard keys used by the function of the WinAPI.
                When you want to collide one object with another object, Objects must be QGraphicsItem or descendant. You can creater bigger geometry for shape() than bouncingRect() for detect collision and next:

                    QList<QGraphicsItem*> colliderList = collidingItems();
                    for(int idx = 0; idx < colliderList.size(); ++idx)
                    {
                            if(qgraphicsitem_cast<Land*>(colliderList[idx]))
                           {
                               //collide with Land
                           }
                           else if(qgraphicsitem_cast<Sea*>(colliderList[idx]))
                           {
                               //collide with Sea
                           }
                
                F Offline
                F Offline
                FlyDoodle
                wrote on last edited by
                #7

                @Bondrusiek
                Oh i see, I'll check that out !
                And thank you for the code, everything is working fine now !

                C 1 Reply Last reply
                0
                • F FlyDoodle

                  @Bondrusiek
                  Oh i see, I'll check that out !
                  And thank you for the code, everything is working fine now !

                  C Offline
                  C Offline
                  Cheng shi hua
                  wrote on last edited by
                  #8

                  @FlyDoodle why not use QML?

                  F 1 Reply Last reply
                  0
                  • C Cheng shi hua

                    @FlyDoodle why not use QML?

                    F Offline
                    F Offline
                    FlyDoodle
                    wrote on last edited by
                    #9

                    @Cheng-shi-hua
                    QML ?

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved