Thread: GDI sprite (Win32 API)

  1. #1
    Registered User
    Join Date
    Jun 2005
    Posts
    24

    GDI sprite (Win32 API)

    Please help... how can I make sprite (simple picture moving when pressed arrows)

    I thought something like this:
    when arrow pressed, then
    1) delete previous picture from screen
    2) calculate new coordinates
    3) show picture using BitBlt()

    I have done step 2 and step 3 (it works), put how can I do step 1 -> "delete" previous picture from screen? Or is there any better way making sprite?

    I have tried to delete previous picture using rectangle ->
    FillRect(..., ..., GetStockObject(WHITE_BRUSH)); but thats no solution what if the background is a image?... and using this the picture starts to blink.

    Here's my code and I' am using DevC++ compilator:

    Code:
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <math.h>
    #include <windows.h>
    #define KEYSTATE(vknum) ((GetAsyncKeyState(vknum) & 0x8000) ? TRUE : FALSE)
    using namespace std;
    
    HINSTANCE hInst;
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    
    double x = 50;
    double y = 50;
    double speed = 0.05;
    
    int max_x = 400;
    int max_y = 200;
    int min_x = 0;
    int min_y = 0;
    
    
    HWND hWnd;
    HDC hDC, MemDCExercising;
    HANDLE bmpExercising;  
        
    
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX  WndCls;
        static char szAppName[] = "BitmapIntro";
        MSG         Msg;
        
    	hInst       = hInstance;
        WndCls.cbSize        = sizeof(WndCls);
        WndCls.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
        WndCls.lpfnWndProc   = WindProcedure;
        WndCls.cbClsExtra    = 0;
        WndCls.cbWndExtra    = 0;
        WndCls.hInstance     = hInst;
        WndCls.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        WndCls.hCursor       = LoadCursor(NULL, IDC_ARROW);
        WndCls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        WndCls.lpszMenuName  = NULL;
        WndCls.lpszClassName = szAppName;
        WndCls.hIconSm       = LoadIcon(hInstance, IDI_APPLICATION);
        RegisterClassEx(&WndCls);
    
        hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                              szAppName,
                              "Sprite",
                              WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);
    
     
                      
            hDC = GetDC(hWnd);
               
    	    bmpExercising = LoadImage(hInst, "C:\\mypic.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    	    // Create a memory device compatible with the above DC variable
    	    MemDCExercising = CreateCompatibleDC(hDC);
                 // Select the new bitmap
         SelectObject(MemDCExercising, bmpExercising);
    
    
        while( GetMessage(&Msg, NULL, 0, 0) )
        {
            TranslateMessage(&Msg);
            DispatchMessage( &Msg);
        }
    
        return static_cast<int>(Msg.wParam);
    }
    
    
    void point (HWND hWnd)
    {
                
               int xC =  (int) round(x);
               int yC =  (int) round(y);           
               
               if(xC>max_x){ xC=max_x; x=max_x; }
               if(yC>max_y){ yC=max_y; y=max_y; }
               if(xC<min_x){ xC=min_x; x=min_x; }
               if(yC<min_y){ yC=min_y; y=min_y; }
    
    	     
    //////////////////////////////////////////////////////////////////////////
    /* THIS IS THE PLACE WHERE DELETE PREVOIUS IMAGE */
    ////////////////////////////////////////////////////////////////////////
    
    
    
    	    BitBlt(hDC, xC, yC, 400, 400, MemDCExercising, 0, 0, SRCCOPY);
    	      
    	      
    	    CancelDC(hDC);
            ReleaseDC(hWnd, hDC);
               
    }
    
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg,
    			   WPARAM wParam, LPARAM lParam)
    {
    
            if(KEYSTATE(VK_UP)){  y-=speed;  point(hWnd); }
            if(KEYSTATE(VK_DOWN)){  y+=speed;  point(hWnd); }
            if(KEYSTATE(VK_LEFT)){  x-=speed;  point(hWnd); }
            if(KEYSTATE(VK_RIGHT)){  x+=speed;  point(hWnd); }
    
            
        switch(Msg)
        {
                           
            
    	case WM_DESTROY:
    	    PostQuitMessage(WM_QUIT);
    	    break;
    	    case WM_PAINT:
    
    	    break;
    
    	default:
    	    return DefWindowProc(hWnd, Msg, wParam, lParam);
        }
        return 0;
    }

    Thank you!

  2. #2
    I am he who is the man! Stan100's Avatar
    Join Date
    Sep 2002
    Posts
    361
    Redraw the background picture?

    Draw the background picture again (it will draw over the old picture), then draw your new image.

    You'll also want to look up buffering to help stop the flicker. You draw the scene on an unseen screen, and then replace the old screen with the new re-drawn screen.

    Erm, if you find yourself getting deep into animation win win32 GUI, you may want to start looking at OpenGL or DirectX. They're MUCH faster than the win32 GUI


    *Edit*
    BTW, it's not a "compilator", it's called a "compiler"

    *Edit Again*
    You have an odd way of checking the keystate, why don't you put it inside your message handler's switch statement?
    Last edited by Stan100; 06-22-2005 at 07:33 AM.
    Stan The Man. Beatles fan

    When I was a child,
    I spoke as a child,
    I thought as a child,
    I reasoned as a child.
    When I became a man,
    I put childish ways behind me"
    (the holy bible, Paul, in his first letter to the Cor. 13:11)

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    24
    thank you for a reply.

    Quote Originally Posted by Stan100
    Redraw the background picture?

    Draw the background picture again (it will draw over the old picture), then draw your new image.
    that's it... but if there is another moving picture then redrawing the background will delete it (I guess, I just have to redraw another picture also)
    Is this a normal technlogy to show a simple animation in window. Is there an another(better) way to get the old picture deleted (after using BitBlt())?

    Quote Originally Posted by Stan100
    You'll also want to look up buffering to help stop the flicker. You draw the scene on an unseen screen, and then replace the old screen with the new re-drawn screen.
    How? Little example, please

    Quote Originally Posted by Stan100
    Erm, if you find yourself getting deep into animation win win32 GUI, you may want to start looking at OpenGL or DirectX. They're MUCH faster than the win32 GUI
    Not yet... but soon.

    Quote Originally Posted by Stan100
    *Edit*
    BTW, it's not a "compilator", it's called a "compiler"
    and I wondered why this word (compilator) looks so strange

    Quote Originally Posted by Stan100
    *Edit Again*
    You have an odd way of checking the keystate, why don't you put it inside your message handler's switch statement?
    WM_KEYPRESS message?


    Actually I am very grateful, if someone can give me a working code (or link) for something similary... I have searched so many days from Google and MSDN. Best way to learn is to examine working code.

  4. #4
    I am he who is the man! Stan100's Avatar
    Join Date
    Sep 2002
    Posts
    361
    Is this a normal technlogy to show a simple animation in window. Is there an another(better) way to get the old picture deleted (after using BitBlt())?
    Unless I missed something, that's the way I learned it.

    Quote Originally Posted by Stan100
    Originally Posted by Stan100
    You'll also want to look up buffering to help stop the flicker. You draw the scene on an unseen screen, and then replace the old screen with the new re-drawn screen.
    How? Little example, please
    Try the background thing, if you still get flicker come back. It's more an advanced thing. I didn't really use it that much until I moved on to DX.



    And to finish the post:
    Code:
    case WM_KEYDOWN:
    		switch((int)wParam)
    		{
    		case 'W':
                                            break;
    Stan The Man. Beatles fan

    When I was a child,
    I spoke as a child,
    I thought as a child,
    I reasoned as a child.
    When I became a man,
    I put childish ways behind me"
    (the holy bible, Paul, in his first letter to the Cor. 13:11)

  5. #5
    I am he who is the man! Stan100's Avatar
    Join Date
    Sep 2002
    Posts
    361
    You may also want to check this out: http://www.catch22.net/tuts/flicker.asp
    Stan The Man. Beatles fan

    When I was a child,
    I spoke as a child,
    I thought as a child,
    I reasoned as a child.
    When I became a man,
    I put childish ways behind me"
    (the holy bible, Paul, in his first letter to the Cor. 13:11)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Win32 API or Win32 SDK?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 07-20-2005, 03:26 PM
  2. GDI sprite (Win32 API)
    By fiff in forum C++ Programming
    Replies: 3
    Last Post: 06-22-2005, 03:08 PM
  3. OpenSSL and Win32 SSL API :: SSL/TLS
    By kuphryn in forum Networking/Device Communication
    Replies: 0
    Last Post: 03-10-2004, 07:46 PM
  4. FILES in WinAPI
    By Garfield in forum Windows Programming
    Replies: 46
    Last Post: 10-02-2003, 06:51 PM
  5. OLE Clipboard :: Win32 API vs. MFC
    By kuphryn in forum Windows Programming
    Replies: 3
    Last Post: 08-11-2002, 05:57 PM