mouse movment

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Cleves
Posts: 224
Joined: Mon Sep 08, 2003 6:40 pm

mouse movment

Post by Cleves »

Hey,

Does anybody know how can I get to what direction the mouse moved. For example, If I want to move my ship left, I move the mouse left, how can I know that ingame? I've tried playing with mouse cursor and it's position but didn't get anything. Think of it like Freelancer(the game) camera.

Any ideas?

Thanks a lot :D
William Finlayson
Posts: 61
Joined: Mon Oct 25, 2004 12:11 am

Post by William Finlayson »

I think what you are after is the relative mouse movement. I'm assuming you know how to obtain the x and y coordinates when the mouse has moved, if so, then simply store the previous x and y, and subtract that from the new x and y to get the amount the mouse has moved since the last event. From the sound of it, that should be all the info you need from it.

As an example, if the mouse coordinates were 100, 100 when you received the last mouse event, and the mouse is moved to 120, 80, then on the new mouse event, subtract the new coordinates from the old ones, to get a relative movement of 20, -20. That lets you know that the mouse has moved 20 pixels 'left', and 20 pixels 'up'.

For smooth movement at all resolutions you would want to scale to a virtual mouse resolution. If you decide a virtual resolution of 1000x1000 for mouse movement, and the screen resolution is 640x480, then multiply all x mouse coordinates by 1000/640, and all y coordinates from the mouse by 1000/480 (simply virtual x/y resolution devided by actual screen x/y resolution). That will ensure that if the mouse moves accross half the screen at 640x480 (320 pixels), or at 800x600 (400 pixels), you will still see it as moving accross half the screen (500 in the example virtual resolution):

320*(1000/640)=500
400*(1000/800)=500
Namek Kural
Posts: 81
Joined: Sun Sep 09, 2007 7:01 pm
Location: BW, Germany

Post by Namek Kural »

Hey, this is an old thread but it is the only one that could help me.

I did exactly what William Finlayson told Cleves on my own but the problem is that I have to use something like device->sleep() so the two x coordinates have a difference greater than 0.

I hope you understand my problem. Sleep stops the whole game until the time is up. The effect is that when I hold the mouse button (I only compare the x positions when a mouse button is held down), the game stops until I release it.

Here's a sample application. As you can see, by holding one mouse button the animation of Sydney stops. If you move the cursor to the lower right corner for example while holding the left mouse button, Sydney will begin to jump. I want to do some Mouse gestures with it.

http://www.uploading.com/files/M64AB64S/Test.zip.html
Namek Kural
Posts: 81
Joined: Sun Sep 09, 2007 7:01 pm
Location: BW, Germany

Post by Namek Kural »

Sorry for pushing this thread but I really need help :cry:
CuteAlien
Admin
Posts: 9718
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Sorry, downloading zip's is not fun and even less from a service where you have to wait for the download. Can't you just post some code here? If you can't reduce it to a post then you haven't isolated your problem enough.

But if I understand your problem correctly you call sleep() after getting the first coordinates just to wait for a while and then get the next coordinate set? Maybe I understood you false, but if that's the case, then it's the wrong approach. Don't call sleep. Just save the coordinates when you get them in an event. Save them as membervariable so you can still access the old coordiantes on the next event. Then do compare it. No need for sleeping...
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Code: Select all

#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#pragma comment(lib, "Irrlicht.lib")

static IrrlichtDevice * globalDevice = 0;

class MyEventReceiver : public IEventReceiver
{
public:
    f32 cursorSensitivity; // Change this to alter the sensitivity

    MyEventReceiver(f32 sensitivity = 5.f) 
        : requiredMovement(0.f, 0.f), lastEventTime(0), cursorSensitivity(sensitivity)
    { }

    virtual bool OnEvent(const SEvent & event)
    {
        // Handle mouse movement events only
        if(EET_MOUSE_INPUT_EVENT == event.EventType  &&
            EMIE_MOUSE_MOVED == event.MouseInput.Event)
        {
            // To allow continuous movement, we have to keep moving the cursor back 
            // to the middle of the screen (and compare it with that position)
            const position2di screenCentre(globalDevice->getVideoDriver()->getScreenSize().Width / 2,
                                            globalDevice->getVideoDriver()->getScreenSize().Height / 2);

            // Ignore any event where the cursor is at the screen centre
            // as that's likely generated by us moving it there
            if(screenCentre.X == event.MouseInput.X
               &&
               screenCentre.Y == event.MouseInput.Y)
               return false;

            // We need to know how fast the cursor is being moved
            const u32 now = globalDevice->getTimer()->getTime();

            if(0 != lastEventTime && now != lastEventTime)
            {
                // The less time that's passed since the last movement, the faster
                // the cursor is moving, so *divide* by the delta time.
                f32 magnitude = cursorSensitivity / (f32)(now - lastEventTime);

                // Now work out how big a movement this represents
                requiredMovement.set((f32)(event.MouseInput.X - screenCentre.X),
                                    (f32)(event.MouseInput.Y - screenCentre.Y));
                requiredMovement *= magnitude;
            }

            // Remember this movement time
            lastEventTime = now;

            // And move the cursor back to the screen centre
            globalDevice->getCursorControl()->setPosition(screenCentre);
        }

        return false;
    }

    // Use this to get the required movement (if any).  This resets the 
    // stored value when it is called.
    vector2df getRequiredMovement(void)
    {
        vector2df returnMe(requiredMovement);
        requiredMovement.set(0.f, 0.f);
        return returnMe;
    }

private:
    vector2df requiredMovement;
    u32 lastEventTime;
};

int main()
{
    MyEventReceiver receiver(10.f /* increase the sensitivity */);

    // This is all generic
    globalDevice = createDevice( video::EDT_OPENGL, core::dimension2d<s32>(640, 480),
        32, false, false, false, &receiver);
    video::IVideoDriver* driver = globalDevice->getVideoDriver();
    scene::ISceneManager* smgr = globalDevice->getSceneManager();
    IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/sydney.md2"));
    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, false);
        node->setMD2Animation ( scene::EMAT_STAND );
        node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
    }
    smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

    // I presume that you want to hide the cursor
    globalDevice->getCursorControl()->setVisible(false);

    while(globalDevice->run())
    {
        // Find out how big a movement is required.  It may be (0, 0)
        vector2df requiredMovement(receiver.getRequiredMovement());

        // Act on the X (horizontal) movement only
        node->setRotation(node->getRotation() + vector3df(0.f, requiredMovement.X, 0.f));
    
        driver->beginScene(true, true, SColor(255,100,101,140));
        smgr->drawAll();
        driver->endScene();
    }

    globalDevice->drop();
    
    return 0;
}
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Namek Kural
Posts: 81
Joined: Sun Sep 09, 2007 7:01 pm
Location: BW, Germany

Post by Namek Kural »

Sorry, I was away for a while.
Thanks alot! Did you try your code?

I really appreciate your hard work, thanks!! :)
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Did I try my code? Yes, I tried it. However, re-reading it, it should add to the current requiredMovement inside OnEvent() instead of replacing it. I'll leave that as exercise for the reader.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply