Solved

directx directinput how to recognize mouse press on bitmap

Posted on 2010-11-19
11
864 Views
Last Modified: 2012-05-10
Hello,
I have an application in VC++ and directx, I am doing the initialization and the main loop and I insert a bitmap, what I want is how to recognize when I press the mouse (only when is down left button) on the bitmap, and when the mouse is pressed to change the bitmap with another bitmap and when is released to revert back to the fitst bitmap (I thing direct input is the right api).

Thank you
Kyriakos
(I will provide code if necessary)
0
Comment
Question by:kyriakos70
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
11 Comments
 
LVL 7

Expert Comment

by:lucky_james
ID: 34172644
you can check the mouse state.
check out:
http://www.two-kings.de/tutorials/dinput/dinput03.html
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34185082
What are you asking exactly?  How to use Direct Input to get mouse input?  How to change the bitmap?  How to detect the mouse is over the bitmap when you click?
0
 

Author Comment

by:kyriakos70
ID: 34190054
satsumo, all three you mention this is what I am asking, firstly how to detect when the mouse is over the bitmap, I know how to initialize directinput, and second when the mouse is pressed on the bitmap theprocedure of this so I can change the bitmap I think with something like this, I use quads to make a 2d game.
IDirect3DTexture9 *LoadTexture(char *fileName);

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:kyriakos70
ID: 34190311
Can I ask you something more? how can I use this code but put the sprite in a specific position on the window?

Thank you
D3DXCreateTextureFromFile(d3ddev, "Panel1.png", &sprite);

Open in new window

0
 

Author Comment

by:kyriakos70
ID: 34190344
I have this code I have to change the values to the specific area of the first or the second line?

Thank you
kYRIAKOS
D3DXVECTOR3 center(0.0f, 0.0f, 0.0f); //center at the upperleftcorner
D3DXVECTOR3 position(50.0f, 50.0f, 0.0f);

Open in new window

0
 

Author Comment

by:kyriakos70
ID: 34190474
OK,
What I want when the mouse is pressed on a specific x,y position to change the bitmap.
Code below.

I draw the sprite and put it in a  position (2nd line of code), I have the 4rth line of code can I use an if...then...else and insert in the function of the mouse the x,y of the sprite position? and how to enter the whole bitmap area?

Thank you
D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);    
D3DXVECTOR3 position(150.0f, 150.0f, 0.0f);
d3dspt->Draw(sprite1, NULL, &center, &position, D3DCOLOR_XRGB(255, 255, 255));
GetCursorPos(&MousePos);

Open in new window

0
 
LVL 12

Accepted Solution

by:
satsumo earned 500 total points
ID: 34191390
Thats a bit confusing.  I'm not sure which one to answer first.  The answer is going to be lots of information which is not always the best way to understand.

Question One:  You need to load two textures, something like this -

IDirect3DTexture9 *sprite[2];

D3DXCreateTextureFromFile(d3ddev, "Panel1.png", &sprite[0]);
D3DXCreateTextureFromFile(d3ddev, "Panel1.png", &sprite[1]);

You also need a variable for which texture is showing, for this example I will call this variable 'show', it could be either 0 or 1.  No reason you can't load 5 textures and have it go from 0 to 4, entirely up to you.

d3dspt->Draw (sprite[show], NULL, &center, &position, D3DCOLOR_XRGB (255, 255, 255));

Question Two: D3DXCreateTextureFromFile() only loads the texture, it dosen't display anything by itself.

Question Three: The two vectors you show do slightly different things.  Position defines where the sprite is in the view, if you want to move the sprite around you change position.

Center describes which part of the sprite is at that position, if center is [0,0], the top-left corner of the sprite is at position.  If center is [0.5, 0.5], the center of the sprite is at position.  This is useful sometimes, in a platform game, the position of a player is defined by his feet (where he stands).  In a shooter things are normally centered on their position.  In a breakout game the bat might be in the center and underneath its position (because the ball hits the top of it).

Question Four: I guess you already know the x and y of the cursor, the x and y of the sprite and its width and height.  All of these need to be in the same space, typically that means positions on the DirectX surface (rather than in screen or window coordinates).  The coordinates returned from GetCursorPos() are in screen coordinates.  If the app is fullscreen, screen coordinates and surface coordinates will match.

Otherwise you have to call ScreenToClient() for your Window.  If the projection/view matrix is scaling or translating the view, you have to account for that.  I don't know how the app is configured.

 When you have these coordinates it's a point-is-in-rectangle test.  The rectangle coordinates depend on the position an center vectors.  Something like the code below, I have used a texture height/width of 64, you will know what they should be -
#define TEXTURE_WIDTH 64
#define TEXTURE_HEIGHT 64

if (cursor.x >= (position.x - (center.x * TEXTURE_WIDTH)))
{
   if (cursor.x <= (position.x + ((1.f - center.x) * TEXTURE_WIDTH)))
   {
      if (cursor.y >= (position.y + (center.y * TEXTURE_HEIGHT)))
      {
         if (cursor.y <= (position.y + ((1.f - center.y) * TEXTURE_HEIGHT)))
         {
            // the cursor was clicked over the sprite
         }
      }
   }
}

Open in new window

0
 

Author Closing Comment

by:kyriakos70
ID: 34191921
Thank you,
That is all I wanted, by the way ir is a full screen 2d application...game.

Thank you satsumo
Kyriakos
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34193089
Thank you, and good luck with the game.
0
 

Author Comment

by:kyriakos70
ID: 34196238
One more thing how to change the position of the sprite I try the below code and nothing happens, I will include the code of the main loop too, there are two the main loop and renderframe procedures. And this code gives a continious frame rate or just one frame and how to make it continious?

Thank you
Kyriakos
while(TRUE)
    {
        DWORD starting_point = GetTickCount();

        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        render_frame();

       // check the 'escape' key
        if(KEY_DOWN(VK_ESCAPE))
            PostMessage(hWnd, WM_DESTROY, 0, 0);

        while ((GetTickCount() - starting_point) < 25);
    }

    // clean up DirectX and COM
    cleanD3D();

    return msg.wParam;
}


// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}



void render_frame(void)
{
    // clear the window to a deep blue
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->BeginScene();    // begins the 3D scene
    d3dspt->Begin(NULL);    // begin sprite drawing
   // draw the sprite
      	D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);    // center at the upper-left corner
    D3DXVECTOR3 position(150.0f, 150.0f, 0.0f);    // position at 50, 50 with no depth 
	d3dspt->Draw(sprite, NULL, &center, &position, D3DCOLOR_XRGB(255, 255, 255));
	d3dspt->End();    // end sprite drawing
    d3ddev->EndScene();    // ends the 3D scene
    d3ddev->Present(NULL, NULL, NULL, NULL);
    return;
}

Open in new window

0
 
LVL 12

Expert Comment

by:satsumo
ID: 34196482
That code should give continuous frames, not faster than 40 fps.  Which is a good idea, otherwise the game would probably run much too fast.

I think the game is rendering, its just that nothing changes.  You always set position to [150, 150] when you draw the sprite.  For it to move you need to position to be a variable.  You can change it either by programming, in response to keys presses or the mouse.

The last example is the most generally useful one.  Each of the moving objects in your game will have its own position vector.  You can combine these, have sprite one moving in a circle, sprite 2 following the mouse and sprite 3 moving with the keys.

Example code below:

This code move the sprite in a circle around [150, 150], the radius of the circle is 50 pixels:

#include <math.h>

float angle = 0.f;

void render_frame(void)
{
   D3DXVECTOR3 position(0.f, 0.f, 0.f);
   D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);
   position.x = 150 + (50.f * (float) sin (angle));
   position.y = 150 + (50.f * (float) cos (angle));
   angle += 0.01f;
   d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->BeginScene();
    d3dspt->Begin(NULL); 
    d3dspt->Draw(sprite, NULL, &center, &position, D3DCOLOR_XRGB(255, 255, 255));
    d3dspt->End(); 
    d3ddev->EndScene();
    d3ddev->Present(NULL, NULL, NULL, NULL);
}


This code makes the sprite follow the mouse:

void render_frame(void)
{
   POINT cursor;
   D3DXVECTOR3 position(0.f, 0.f, 0.f);
   D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);
   GetCursorPos (&cursor);
   position.x = (float) cursor.x;
   position.y = (float) cursor.y;

   d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->BeginScene();
    d3dspt->Begin(NULL); 
    d3dspt->Draw(sprite, NULL, &center, &position, D3DCOLOR_XRGB(255, 255, 255));
    d3dspt->End(); 
    d3ddev->EndScene();
    d3ddev->Present(NULL, NULL, NULL, NULL);
}


This code makes the sprite move when the keys are pressed, the sprite starts at [150, 150] and moves 2 pixels when you press the WASD keys:

D3DXVECTOR3 position(150.f, 150.f, 0.f);

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   switch(message)
   {
      case WM_CHAR:
         switch (wParam)
         {
            case 'd':
              position.x += 2;
              break;

            case 'a':
              position.x -= 2;
              break;

            case 's':
              position.y += 2;
              break;

            case 'w':
              position.y -= 2;
              break;
         }

         break;

      case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
   }

   return DefWindowProc (hWnd, message, wParam, lParam);
}

void render_frame(void)
{
   D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);

   d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->BeginScene();
    d3dspt->Begin(NULL); 
    d3dspt->Draw(sprite, NULL, &center, &position, D3DCOLOR_XRGB(255, 255, 255));
    d3dspt->End(); 
    d3ddev->EndScene();
    d3ddev->Present(NULL, NULL, NULL, NULL);
}

Open in new window

0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Socket Programming (Unix) 8 153
Dynamically allocate memory 9 70
C++ question 3 74
print bytes of an integer 6 27
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question