bitmap animation with Timer???

Started by
5 comments, last by Colin Jeanne 17 years, 9 months ago
Im trying to use bitmaps in rapid succession with a timer, but it is all a blur. PLEASE HELP.
shanelaffond13
Advertisement
Your post is less then discriptive but i'll take a shot at it. If your animation is literally a blur its probably due to the fact that the bitmap is animating at the full speed of the computer. you could slow it down by adding sleep statements or by having an internal counter that would trigger the animation
int main(){     X.Animate();}void Class::Animate(){     if(Counter < 1000)    {        ++Counter;        return;    else        //next frame of animation}

or using sleep it would just beint main(){    Sleep(10);    X.Animate();}void Class:Animate(){    //next frame}


I recommend the first one because it alows you to have control over each bitmaps animation speed (you could pass the value of counter as a constructor param). If this is not what you mean by "its all a blur", such as "I learned it somewhere but have a hard time remembering the details" feel free to correct my assumption

Hope I Helped [smile]
____________________________"This just in, 9 out of 10 americans agree that 1 out of 10 americans will disagree with the other 9"- Colin Mochrie
That sorta worked. It slowed down a bit. But I decided that I would use somebody else's class, which used QueryPerformanceCounter(). I start the counter, if the time that hasn't passed isn't enough, then I update the time.

All of this is embedded into my Draw() function. Here is my code.

void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey, bool timer, int time) //Draw with delay
{
HINSTANCE hDraw = hThisInstance;
HDC hDCdraw = GetDC(hwnd);
HANDLE draw = LoadImage( hDraw, FileName, IMAGE_BITMAP, sizex, sizey, LR_LOADFROMFILE | LR_CREATEDIBSECTION );
HDC hDCdrawOFF = CreateCompatibleDC( GetDC(hwnd) );
CreateCompatibleBitmap( hDCdrawOFF, sizex, sizey );
hDCdraw = BeginPaint(hwnd, &ps); //Start paint with backbuffer DC
SelectObject(hDCdrawOFF, draw);
GetObject( draw, sizeof(BITMAP), NULL );

if(timer)
{
double Counter = InitTimer(); //Start Timer
Counter = CurrentTime(); //Start counting time
if (Counter < time) //If time not passed by
Counter = CurrentTime(); //Update time

else
BitBlt( GetDC(hwnd), x, y, sizex, sizey, hDCdrawOFF, 0, 0, SRCCOPY); //If time gone by, draw BMP
}

//Cleanup
ReleaseDC( hwnd, hDCdrawOFF);
ReleaseDC( hwnd, hDCdraw );
DeleteDC( hDCdrawOFF);
DeleteDC( hDCdraw);
DeleteObject( draw );
EndPaint(hwnd, &ps); //End paint

}

And here is the timer function

double InitTimer() //Start Timer
{
__int64 time;
QueryPerformanceFrequency((LARGE_INTEGER*)&TimeFrequency);
QueryPerformanceCounter((LARGE_INTEGER*)&time);
TimeBegin = (double)time / TimeFrequency;
return TimeBegin;
}

double CurrentTime() //Get time
{
__int64 time;
QueryPerformanceCounter((LARGE_INTEGER*)&time);
return ((double)time / TimeFrequency) - TimeBegin;
}

I don't know. Please help me.

P.S. I have a four KB memory leak. I can't find it. I will post my full code next.
shanelaffond13
As I said I would, here is my entire code, so maybe someone can find my 4KB memory leak. Please help. Thx.

Main.cpp
#include "main.h"/*  Declare Windows procedure  */LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);/*  Make the class name into a global variable  */char szClassName[ ] = "GOH";sPlayer Player;sEnemy Demon;int WINAPI WinMain (HINSTANCE hThisInstance,                     HINSTANCE hPrevInstance,                     LPSTR lpszArgument,                     int nFunsterStil)             /* This is the handle for our window */{    MSG messages;            /* Here messages to the application are saved */    WNDCLASSEX wincl;        /* Data structure for the windowclass */    /* The Window structure */    wincl.hInstance = hThisInstance;    wincl.lpszClassName = szClassName;    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */    wincl.style = 0;                 /* Catch double-clicks */    wincl.cbSize = sizeof (WNDCLASSEX);    /* Use default icon and mouse-pointer */    wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(GOH_ICON));    wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(GOH_ICON));    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);    wincl.lpszMenuName = NULL;                 /* No menu */    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */    wincl.cbWndExtra = 0;                      /* structure or the window instance */    /* Use Windows's default color as the background of the window */    wincl.hbrBackground = CreateSolidBrush(BG);;    /* Register the window class, and if it fails quit the program */    if (!RegisterClassEx (&wincl))        return 0;    /* The class is registered, let's create the program*/    hwnd = CreateWindowEx (           0,                   /* Extended possibilites for variation */           szClassName,         /* Classname */           "Gates of Heaven",       /* Title Text */           WS_MINIMIZEBOX | WS_SYSMENU, /* default window */           CW_USEDEFAULT,       /* Windows decides the position */           CW_USEDEFAULT,       /* where the window ends up on the screen */           900,                 /* The programs width */           600,                 /* and height in pixels */           HWND_DESKTOP,        /* The window is a child-window to desktop */           NULL,                /* No menu */           hThisInstance,       /* Program Instance handler */           NULL                /* No Window Creation data */           );    /* Make the window visible on the screen */    ShowWindow (hwnd, nFunsterStil);    /* Run the message loop. It will run until GetMessage() returns 0 */    while (GetMessage (&messages, NULL, 0, 0))    {        /* Translate virtual-key messages into character messages */        TranslateMessage(&messages);        /* Send message to WindowProcedure */        DispatchMessage(&messages);    }    /* The program return-value is 0 - The value that PostQuitMessage() gave */    return messages.wParam;}/*  This function is called by the Windows function DispatchMessage()  */LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    switch (message)                  /* handle the messages */    {        case WM_DESTROY:        if(MessageBox( hwnd, "Do you want to save your current progress before you exit?", "Save Current Progress?", MB_YESNO | MB_ICONQUESTION) == IDYES)            save();            //DeleteDC(hdc);            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */        break;        case WM_CREATE:            SetRect( &pHealth, 0, 0, 100, 20 );            SetRect( &pMana, 0, 30, 100, 50 );            SetRect( &pAttack, 0, 60, 100, 80);            SetRect( &pLevel, 0, 90, 100, 120);            SetRect( &pXP, 0, 120, 100, 160);            Player.facing = 2;  //Facing east            hdc = BeginPaint(hwnd, &ps);            SetRect( &stats, 0, 550, 100, 600 );            FillRect(hdc, &stats, CreateSolidBrush(Black));            EndPaint(hwnd, &ps);            if(MessageBox( hwnd, "Do you want to load a saved game?", "Load Saved Game?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    load();                    InvalidateRect(hwnd,NULL,TRUE);                }                else                {                    Init();                    InvalidateRect(hwnd,NULL,TRUE);                }            eInit(1);            Player.dead = false;        break;        case WM_KEYUP:        switch(wParam)        {            case VK_F1:                if(MessageBox( hwnd, "Are you sure that you want to save your current progress?", "Save Game?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    save();                }                else                return (1);                break;            case 0x41:  //A                while (!Demon.dead)                {                    AttackE();                    Sleep(aDelay);                    attack = true;                    Attack(false);                    Attack(true);                }                if(Demon.dead)                {                    if(attack)                    {                    Player.xp = Player.xp + Demon.xp;                    InvalidateRect(hwnd,NULL,TRUE);                    }                    attack = false;                }                if(Player.xp >= 1000)                {                LevelUp(2);                InvalidateRect(hwnd,NULL,TRUE);                }                if(Player.xp >= 2000)                {                LevelUp(3);                InvalidateRect(hwnd,NULL,TRUE);                }                if(Player.xp >= 3000)                {                LevelUp(4);                InvalidateRect(hwnd,NULL,TRUE);                }                if(Player.xp >= 4000)                {                LevelUp(5);                InvalidateRect(hwnd,NULL,TRUE);                }                if(Player.xp >= 5000)                {                LevelUp(6);                InvalidateRect(hwnd,NULL,TRUE);                }                break;            case 0x4E: //N            if(MessageBox( hwnd, "Are you sure that you want to start a new game and lose your current progress?", "New Game?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    Init();                    InvalidateRect(hwnd,NULL,TRUE);                }                else                return (1);                break;            case 0x4C: //L                if(MessageBox( hwnd, "Are you sure that you want to load and lose your current progress?", "Load?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    load();                    InvalidateRect(hwnd,NULL,TRUE);                }                else                return (1);                break;            case VK_ESCAPE:                if(MessageBox( hwnd, "Do you want to save your current progress before you exit?", "Save Current Progress?", MB_YESNO | MB_ICONQUESTION) == IDYES)                save();                ReleaseDC(hwnd, hdc);                DeleteDC(hdc);                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */                break;        }        break;        case WM_KEYDOWN:        switch(wParam)        {            case VK_UP:                if(testY != 0)  //If not leaving screen                {                Player.facing = 1;                testY = (testY - speed);                InvalidateRect(hwnd,NULL,FALSE);                }                break;            case VK_DOWN:            if(testY != (550 - 96))  //If not leaving screen                {                Player.facing = 3;                testY = (testY + speed);                InvalidateRect(hwnd,NULL,FALSE);                }                break;            case VK_LEFT:            if( testX != 100)  //If not hitting stats                {                        Player.facing = 4;  //Move left                        testX = (testX - speed);                        InvalidateRect(hwnd,NULL,FALSE);                }            break;            case VK_RIGHT:            if(testX != (900 - testS))  //If not leaving screen                {                    Player.facing = 2;                    testX = (testX + speed);                    InvalidateRect(hwnd,NULL,FALSE);                }            break;        }        break;        case WM_PAINT:                wsprintf(Phealth,"Health: %d", Player.health);                wsprintf(Pmana,"Mana: %d", Player.mana);                wsprintf(Pattack, "Attack: %d", Player.attack);                wsprintf(Plevel,"Level: %d", Player.level);                wsprintf(Pxp, "XP: %d", Player.xp);                hdc = BeginPaint(hwnd, &ps);                SetBkMode(hdc, TRANSPARENT);                SetTextColor( hdc, TXT );                if(Player.dead)                {                    GetClientRect (hwnd, &screen);                    FillRect(hdc, &screen, CreateSolidBrush(BG));                    DrawText( hdc, "YOU DIED!!!", -1, &screen, DT_SINGLELINE | DT_CENTER | DT_VCENTER );                    EndPaint(hwnd, &ps);                    DeleteObject( &screen );                }                else if (!Player.dead)                {                    //Draw stats                    DrawText(hdc, Phealth, -1, &pHealth, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Pmana, -1, &pMana, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Pattack, -1, &pAttack, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Plevel, -1, &pLevel, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Pxp, -1, &pXP, DT_SINGLELINE | DT_LEFT);                    //See which way Player is facing and draw it.                        switch(Player.facing)                        {                            case 1://North                            Draw("Data/Player/Stop/sN0.bmp", testX, testY, 96, 96);                            break;                            case 2://East                            Draw("Data/Player/Stop/sE0.bmp", testX, testY, 96, 96);                            break;                            case 3://South                            Draw("Data/Player/Stop/sS0.bmp", testX, testY, 96, 96);                            break;                            case 4://West                            Draw("Data/Player/Stop/sW0.bmp", testX, testY, 96, 96);                            break;                        }                    EndPaint(hwnd, &ps);                }        break;        default:                      /* for messages that we don't deal with */            return DefWindowProc (hwnd, message, wParam, lParam);    }    return 0;}void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey)  //Basic draw{    HINSTANCE hDraw = hThisInstance; //Draw instance    HDC hDCdrawOFF = CreateCompatibleDC( GetDC(hwnd) );  //Create backbuffer    CreateCompatibleBitmap( hDCdrawOFF, sizex, sizey );    HDC hDCdraw = GetDC(hwnd);  //Create backbuffer DC    hDCdraw = BeginPaint(hwnd, &ps);  //Start paint with backbuffer DC    HANDLE draw = LoadImage( hDraw, FileName, IMAGE_BITMAP, sizex, sizey, LR_LOADFROMFILE | LR_CREATEDIBSECTION );  //Load BMP    SelectObject(hDCdrawOFF, draw);  //Assign BMP to backbuffer    GetObject( draw, sizeof(BITMAP), NULL );  //Get BMP    BitBlt( GetDC(hwnd), x, y, sizex, sizey, hDCdrawOFF, 0, 0, SRCCOPY);  //Draw to window    //Cleanup    ReleaseDC( hwnd, hDCdrawOFF);    ReleaseDC( hwnd, hDCdraw );    DeleteDC( hDCdrawOFF);    DeleteDC( hDCdraw);    DeleteObject( draw );    EndPaint(hwnd, &ps);  //End paint}void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey, bool timer, int time)  //Draw with delay{    HINSTANCE hDraw = hThisInstance;    HDC hDCdraw = GetDC(hwnd);    HANDLE draw = LoadImage( hDraw, FileName, IMAGE_BITMAP, sizex, sizey, LR_LOADFROMFILE | LR_CREATEDIBSECTION );    HDC hDCdrawOFF = CreateCompatibleDC( GetDC(hwnd) );    CreateCompatibleBitmap( hDCdrawOFF, sizex, sizey );    hDCdraw = BeginPaint(hwnd, &ps);  //Start paint with backbuffer DC    SelectObject(hDCdrawOFF, draw);    GetObject( draw, sizeof(BITMAP), NULL );    if(timer)    {        double Counter = InitTimer();  //Start Timer        Counter = CurrentTime();  //Start counting time        if (Counter < time) //If time not passed by        Counter = CurrentTime();  //Update time        else            BitBlt( GetDC(hwnd), x, y, sizex, sizey, hDCdrawOFF, 0, 0, SRCCOPY);  //If time gone by, draw BMP    }    //Cleanup    ReleaseDC( hwnd, hDCdrawOFF);    ReleaseDC( hwnd, hDCdraw );    DeleteDC( hDCdrawOFF);    DeleteDC( hDCdraw);    DeleteObject( draw );    EndPaint(hwnd, &ps);  //End paint}void Init(){    //Initialize new game variable if not loaded    Player.health = 100;    Player.attack = 10;    Player.level = 1;    Player.xp = 0;    Player.mana = 20;    Player.dead = false;    InvalidateRect(hwnd,NULL,FALSE);}void eInit(int dNum)  //Create demon{    switch(dNum)    {        case 1:  //Easiet            Demon.health = 15;            Demon.attack = 5;            Demon.xp = 50;            Demon.dead = false;            break;        case 2:  //Medium            Demon.health = 45;            Demon.attack = 15;            Demon.xp = 75;            Demon.dead = false;            break;        case 3:  //Hardest            Demon.health = 80;            Demon.attack = 45;            Demon.xp = 100;            Demon.dead = false;            break;    }}void save() //Save stats{    saveL();    saveX();    saveH();    saveA();    saveM();}void load()  //Load stats{    loadL();    loadX();    loadH();    loadA();    loadM();}void saveL(){    myFile = fopen("Data/L.svg","w+b");  //Open/Create Level save    fwrite(&Player.level, sizeof(int), 1, myFile);  //Write Player Level    fclose(myFile);  //Close Level save}void loadL(){    myFile = fopen("Data/L.svg","r+b");  //Open Level save    fread(&Player.level, sizeof(int), 1, myFile);  //Read in data    fclose(myFile); //Close Level save}void saveX(){    myFile = fopen("Data/X.svg","w+b");  //XP save    fwrite(&Player.xp, sizeof(int), 1, myFile);    fclose(myFile);}void loadX(){    myFile = fopen("Data/X.svg","r+b");  //XP save    fread(&Player.xp, sizeof(int), 1, myFile);    fclose(myFile);}void saveH(){    myFile = fopen("Data/H.svg","w+b");  //Health save    fwrite(&Player.health, sizeof(int), 1, myFile);    fclose(myFile);}void loadH(){    myFile = fopen("Data/H.svg","r+b");  //Health save    fread(&Player.health, sizeof(int), 1, myFile);    fclose(myFile);}void saveA(){    myFile = fopen("Data/A.svg","w+b");  //Attack save    fwrite(&Player.attack, sizeof(int), 1, myFile);    fclose(myFile);}void loadA(){    myFile = fopen("Data/A.svg","r+b");  //Attack save    fread(&Player.attack, sizeof(int), 1, myFile);    fclose(myFile);}void saveM(){    myFile = fopen("Data/M.svg","w+b");  //Mana save    fwrite(&Player.mana, sizeof(int), 1, myFile);    fclose(myFile);}void loadM(){    myFile = fopen("Data/M.svg","r+b");  //Mana save    fread(&Player.mana, sizeof(int), 1, myFile);    fclose(myFile);}void Attack(bool player){    if (!player)  //If not attacking player        Demon.health = (Demon.health - Player.attack);  //Update Demon Health        if(Demon.health <= 0)  //If less than or equal to 0        {            Demon.health = 0;  //Health equals 0            Demon.dead = true;  //Set flag Demon Died        }    else if (player)  //If attacking player        Player.health = (Player.health - Demon.attack);  //Update Player Health    if (Player.health <= 0)    {        Player.health = 0;        Player.dead = true;    }}void AttackE()  //Attack east{    Draw( "Data/Player/Attack/aE0.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE1.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE2.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE3.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE4.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE5.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE6.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE7.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE8.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE9.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE10.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE11.bmp", testX, testY, 96, 96, true, aDelay);    Draw( "Data/Player/Attack/aE12.bmp", testX, testY, 96, 96, true, aDelay);}void LevelUp(int nLevel){    switch(nLevel)    {        case 2:        Player.health = 110;        Player.mana = 30;        Player.attack = 15;        Player.level = 2;        break;        case 3:        Player.health = 125;        Player.mana = 45;        Player.attack = 25;        Player.level = 3;        break;        case 4:        Player.health = 140;        Player.mana = 60;        Player.attack = 45;        Player.level = 4;        break;        case 5:        Player.health = 185;        Player.mana = 70;        Player.attack = 60;        Player.level = 5;        break;        case 6:        Player.health = 200;        Player.mana = 85;        Player.attack = 70;        Player.level = 6;        break;    }}double InitTimer()  //Start Timer{  __int64 time;  QueryPerformanceFrequency((LARGE_INTEGER*)&TimeFrequency);  QueryPerformanceCounter((LARGE_INTEGER*)&time);  TimeBegin = (double)time / TimeFrequency;  return TimeBegin;}double CurrentTime()  //Get time{  __int64 time;  QueryPerformanceCounter((LARGE_INTEGER*)&time);  return ((double)time / TimeFrequency) - TimeBegin;}


And here is my heade file

Main.h
#include <windows.h>#include <time.h>#include <fstream>#include "resource.h"bool moving = false;bool attack = false;COLORREF BG = RGB(106, 76, 48);  //BrownCOLORREF Black = RGB(0, 0, 0);  //BlackCOLORREF TXT = RGB(0, 255, 0);  //Neon green__int64 TimeFrequency;double TimeBegin;int testX = 100;  //Player Xint testY = 0;  //Player Yint testS = 96;  //Player sizeint speed = 2;int delay = 500;int aDelay = 1000;HINSTANCE hThisInstance;HDC         hdc;PAINTSTRUCT ps;RECT        screen;RECT        stats;RECT        pHealth;RECT        pMana;RECT        pAttack;RECT        pLevel;RECT        pXP;TCHAR Phealth[64];TCHAR Pmana[64];TCHAR Pattack[64];TCHAR Plevel[64];TCHAR Pxp[64];FILE* myFile;HWND hwnd;void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey);void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey, bool timer, int time);void Init();void eInit(int dNum);void save();void load();void saveL();void loadL();void saveX();void loadX();void saveH();void loadH();void saveN();void loadN();void saveA();void loadA();void saveM();void loadM();void Attack(bool player = false);void AttackE();  //Attack Eastvoid LevelUp(int nLevel);double InitTimer();double CurrentTime();typedef struct sPlayer {                int mana;                int health;                int attack;                int xp;                int level;                bool dead;                int facing;                //1 for up, 2 for right, 3 for down, 4 for left                };typedef struct sEnemy {                int health;  //HP                int attack;  //Attack power                bool dead;  //Dead flag                int xp;  //XP given                };


I would appreciate any comments. About the code, new code, or anything else. Thanks everyone.

Please help me. GDI is hard, but a good learing experience.
shanelaffond13
I recommend that you dont use QueryPerformanceCounter(). If I understand it correctly, this will cause strange results on both laptops and multiprocessor/multicore systems. Each processor or core might have a different counter frequency and on laptops this frequency might change with power consumption. If you want to get a higher resolution than WM_TIMER try using timeGetTime().

Also, in your switch, rather than 0x41 you can just use the character literal 'A'. The character literal has a numeric value of 0x41 and makes your code much easier to understand.

Further, do not use BeginPaint() and EndPaint() outside of WM_PAINT or more than once inside WM_PAINT. For your Draw() function, just pass in the HDC returned by BeginPaint() rather than calling BeginPaint() yourself inside that function.

Finally, when using SelectObject() remember to save the return value in some other variable. Before you destroy a DC you must select the original objects back into the DC. SelectObject() returns the object that is being pushed out of the DC. In Draw() you select the "draw" bitmap into hDCdrawOFF but never select the original bitmap back in. This might be part of your leak.

Another part is probably in this line:
HDC hDCdrawOFF = CreateCompatibleDC( GetDC(hwnd) );

You're never releasing the DC associated with that GetDC() call. Yes, I know that you call ReleaseDC() on hDCdrawOFF but since hDCdrawOFF did not come from GetDC() this call to ReleaseDC() is incorrect. Get rid of that call to ReleaseDC() and change that line to

HDC hDCdrawOFF = CreateCompatibleDC( hDCdraw );

Another part is due to the fact that you have these lines as well
HDC hDCdraw = GetDC(hwnd); //Create backbuffer DC
hDCdraw = BeginPaint(hwnd, &ps); //Start paint with backbuffer DC

Ignoring the fact that this is the second call to BeginPaint(), you are losing the handle to the call to GetDC() since you are overwriting it with the return value to BeginPaint(). This is another DC that is leaked. Rather than do either of these, make hDCdraw a parameter to the function and pass in the DC you get from BeginPaint() from WM_PAINT.

Another DC leak comes from this line:
BitBlt( GetDC(hwnd), x, y, sizex, sizey, hDCdrawOFF, 0, 0, SRCCOPY);

Again, you are losing the handle to the DC that you got from GetDC(). Use hDCdraw here instead.

That's all I could see for now.
YES!!! This worked. Now I have smooth animation(Except for the first step). I also have no more drawing memory leak. I have a leak when I post a message box, but thats it.

There's only two problems now.

1. When I take my first step, I stop, but then continue. I can't figure out how to flag if I'm moving without having that stop. Please help! I'm pulling my hair out!!!

2. I can't set the boundries so the player doesn't go out of sight. I know. A noob question. But I am a noob. Please help.

Here is my code.

main.h
#include <windows.h>#include <time.h>#include <fstream>#include "resource.h"bool moving = false;bool attack = false;COLORREF BG = RGB(106, 76, 48);  //BrownCOLORREF Black = RGB(0, 0, 0);  //BlackCOLORREF TXT = RGB(0, 255, 0);  //Neon green__int64 TimeFrequency;  //For Timer functionsdouble TimeBegin;int testX = 100;  //Player Xint testY = 0;  //Player Yint mX;int mY;int testS = 96;  //Player sizeint speed = 4;int delay = 35;int aDelay = 0;HINSTANCE hThisInstance;HDC         hdc;PAINTSTRUCT ps;RECT        screen;RECT        stats;RECT        pHealth;RECT        pMana;RECT        pAttack;RECT        pLevel;RECT        pXP;TCHAR Dhealth[64];TCHAR Phealth[64];TCHAR Pmana[64];TCHAR Pattack[64];TCHAR Plevel[64];TCHAR Pxp[64];FILE* myFile;  //For loading & savingHWND hwnd;void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey);void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey, bool timer, int time);void DrawTxt(TCHAR Text[64]);void Init();  //Init Playervoid eInit(int dNum);  //Init Demonvoid save();void load();void saveL();void loadL();void saveX();void loadX();void saveH();void loadH();void saveN();void loadN();void saveA();void loadA();void saveM();void loadM();void Attack(bool player = false);void AttackE();  //Attack Eastvoid WalkE(); //Walk Eastvoid WalkN();void WalkS();void WalkW();void LevelUp(int nLevel);double InitTimer();double CurrentTime();typedef struct sPlayer {                int mana;                int health;                int attack;                int xp;                int level;                bool dead;                int facing;                //1 for up, 2 for right, 3 for down, 4 for left                };typedef struct sEnemy {                int health;  //HP                int attack;  //Attack power                bool dead;  //Dead flag                int xp;  //XP given                };


And

main.cpp
#include "main.h"/*  Declare Windows procedure  */LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);/*  Make the class name into a global variable  */char szClassName[ ] = "GOH";sPlayer Player;sEnemy Demon;int WINAPI WinMain (HINSTANCE hThisInstance,                     HINSTANCE hPrevInstance,                     LPSTR lpszArgument,                     int nFunsterStil)             /* This is the handle for our window */{    MSG messages;            /* Here messages to the application are saved */    WNDCLASSEX wincl;        /* Data structure for the windowclass */    /* The Window structure */    wincl.hInstance = hThisInstance;    wincl.lpszClassName = szClassName;    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */    wincl.style = 0;                 /* Catch double-clicks */    wincl.cbSize = sizeof (WNDCLASSEX);    /* Use default icon and mouse-pointer */    wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(GOH_ICON));    wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(GOH_ICON));    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);    wincl.lpszMenuName = NULL;                 /* No menu */    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */    wincl.cbWndExtra = 0;                      /* structure or the window instance */    /* Use Windows's default color as the background of the window */    wincl.hbrBackground = CreateSolidBrush(BG);;    /* Register the window class, and if it fails quit the program */    if (!RegisterClassEx (&wincl))        return 0;    /* The class is registered, let's create the program*/    hwnd = CreateWindowEx (           0,                   /* Extended possibilites for variation */           szClassName,         /* Classname */           "Gates of Heaven",       /* Title Text */           WS_MINIMIZEBOX | WS_SYSMENU, /* default window */           CW_USEDEFAULT,       /* Windows decides the position */           CW_USEDEFAULT,       /* where the window ends up on the screen */           900,                 /* The programs width */           600,                 /* and height in pixels */           HWND_DESKTOP,        /* The window is a child-window to desktop */           NULL,                /* No menu */           hThisInstance,       /* Program Instance handler */           NULL                /* No Window Creation data */           );    /* Make the window visible on the screen */    ShowWindow (hwnd, nFunsterStil);    /* Run the message loop. It will run until GetMessage() returns 0 */    while (GetMessage (&messages, NULL, 0, 0))    {        /* Translate virtual-key messages into character messages */        TranslateMessage(&messages);        /* Send message to WindowProcedure */        DispatchMessage(&messages);    }    /* The program return-value is 0 - The value that PostQuitMessage() gave */    return messages.wParam;}/*  This function is called by the Windows function DispatchMessage()  */LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    switch (message)                  /* handle the messages */    {        case WM_CLOSE:            if(MessageBox( hwnd, "Do you want to save your current progress before you exit?", "Save Current Progress?", MB_YESNO | MB_ICONQUESTION) == IDYES)            save();        case WM_DESTROY:            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */        break;        case WM_CREATE:            if(MessageBox( hwnd, "Do you want to load your saved game?", "Load Save?", MB_YESNO | MB_ICONQUESTION) == IDYES)            load();            else            Init();            SetRect( &pHealth, 0, 0, 100, 20 );            SetRect( &pMana, 0, 30, 100, 50 );            SetRect( &pAttack, 0, 60, 100, 80);            SetRect( &pLevel, 0, 90, 100, 120);            SetRect( &pXP, 0, 120, 100, 160);            Player.facing = 2;  //Facing east        break;        case WM_MOUSEMOVE:            break;        case WM_KEYUP:        switch(wParam)        {            case VK_F1:                if(MessageBox( hwnd, "Are you sure that you want to save your current progress?", "Save Game?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    save();                }                else                return (1);                break;            case 0x41:  //A                while (!Demon.dead)                {                    attack = true;                    AttackE();                    Attack(false);                    Attack(true);                }                if(Demon.dead)                {                    if(attack)                    {                    Player.xp = Player.xp + Demon.xp;                    InvalidateRect(hwnd,NULL,TRUE);                    }                    attack = false;                    eInit(1);                }                if(Player.xp == 1000)                {                LevelUp(2);                InvalidateRect(hwnd,NULL,TRUE);                }                else if(Player.xp == 2000)                {                LevelUp(3);                InvalidateRect(hwnd,NULL,TRUE);                }                else if(Player.xp == 3000)                {                LevelUp(4);                InvalidateRect(hwnd,NULL,TRUE);                }                else if(Player.xp == 4000)                {                LevelUp(5);                InvalidateRect(hwnd,NULL,TRUE);                }                else if(Player.xp == 5000)                {                LevelUp(6);                InvalidateRect(hwnd,NULL,TRUE);                }                break;            case 0x48:                MessageBox(hwnd, "TEST", "TEST", MB_OK);                break;            case 0x4E: //N            if(MessageBox( hwnd, "Are you sure that you want to start a new game and lose your current progress?", "New Game?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    Init();                    InvalidateRect(hwnd,NULL,TRUE);                }                else                return (1);                break;            case 0x4C: //L                if(MessageBox( hwnd, "Are you sure that you want to load and lose your current progress?", "Load?", MB_YESNO | MB_ICONQUESTION) == IDYES)                {                    load();                    InvalidateRect(hwnd,NULL,TRUE);                }                else                return (1);                break;            case VK_ESCAPE:                if(MessageBox( hwnd, "Do you want to save your current progress before you exit?", "Save Current Progress?", MB_YESNO | MB_ICONQUESTION) == IDYES)                save();                ReleaseDC(hwnd, hdc);                DeleteDC(hdc);                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */                break;            case VK_UP:                moving = false;                break;            case VK_DOWN:                moving = false;                break;            case VK_LEFT:                moving = false;                break;            case VK_RIGHT:                moving = false;                break;        }        break;        case WM_KEYDOWN:        switch(wParam)        {            case VK_UP:                moving = true;                Player.facing = 1;                InvalidateRect(hwnd,NULL,FALSE);                break;            case VK_DOWN:                moving = true;                Player.facing = 3;                InvalidateRect(hwnd,NULL,FALSE);                break;            case VK_LEFT:                    moving = true;                    Player.facing = 4;  //Move left                    InvalidateRect(hwnd,NULL,FALSE);            break;            case VK_RIGHT:                Player.facing = 2;                moving = true;                InvalidateRect(hwnd,NULL,FALSE);                break;        }        break;        case WM_PAINT:                wsprintf(Phealth,"Health: %d", Player.health);                wsprintf(Pmana,"Mana: %d", Player.mana);                wsprintf(Pattack, "Attack: %d", Player.attack);                wsprintf(Plevel,"Level: %d", Player.level);                wsprintf(Pxp, "XP: %d", Player.xp);                hdc = BeginPaint(hwnd, &ps);                SetBkMode(hdc, TRANSPARENT);                SetTextColor( hdc, TXT );                if(Player.dead)                {                    GetClientRect (hwnd, &screen);                    FillRect(hdc, &screen, CreateSolidBrush(BG));                    DrawText( hdc, "YOU DIED!!!", -1, &screen, DT_SINGLELINE | DT_CENTER | DT_VCENTER );                    EndPaint(hwnd, &ps);                    DeleteObject( &screen );                }                else if (!Player.dead)                {                    //Draw stats                    DrawText(hdc, Phealth, -1, &pHealth, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Pmana, -1, &pMana, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Pattack, -1, &pAttack, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Plevel, -1, &pLevel, DT_SINGLELINE | DT_LEFT);                    DrawText(hdc, Pxp, -1, &pXP, DT_SINGLELINE | DT_LEFT);                    //See which way Player is facing and draw it.                    if(!moving)                    {                        switch(Player.facing)                        {                            case 1://North                            Draw("Data/Player/Stop/sN0.bmp", testX, testY, 96, 96);                            break;                            case 2://East                            Draw("Data/Player/Stop/sE0.bmp", testX, testY, 96, 96);                            break;                            case 3://South                            Draw("Data/Player/Stop/sS0.bmp", testX, testY, 96, 96);                            break;                            case 4://West                            Draw("Data/Player/Stop/sW0.bmp", testX, testY, 96, 96);                            break;                        }                    }                    if(moving)                    {                        switch(Player.facing)                        {                            case 1://North                            WalkN();                            break;                            case 2://East                            WalkE();                            break;                            case 3://South                            WalkS();                            break;                            case 4://West                            if(testX != (900 - 96))  //If not leaving screen                            WalkW();                            break;                        }                    }                    EndPaint(hwnd, &ps);                    DeleteObject(Phealth);                    DeleteObject(Pmana);                    DeleteObject(Pattack);                    DeleteObject(Plevel);                    DeleteObject(Pxp);                    ReleaseDC(hwnd,hdc);                    DeleteDC(hdc);                }        break;        default:                      /* for messages that we don't deal with */            return DefWindowProc (hwnd, message, wParam, lParam);    }    return 0;}void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey)  //Basic draw{    HINSTANCE hDraw = hThisInstance; //Draw instance    HDC hDCdraw = GetDC(hwnd);  //Create backbuffer DC    HDC hDCdrawOFF = CreateCompatibleDC( hDCdraw );  //Create backbuffer    HANDLE draw = LoadImage( hDraw, FileName, IMAGE_BITMAP, sizex, sizey, LR_LOADFROMFILE | LR_CREATEDIBSECTION );  //Load BMP    SelectObject(hDCdrawOFF, draw);  //Assign BMP to backbuffer    GetObject( draw, sizeof(BITMAP), NULL );  //Get BMP    BitBlt( hDCdraw, x, y, sizex, sizey, hDCdrawOFF, 0, 0, SRCCOPY);  //Draw to window    //Cleanup    ReleaseDC( hwnd, hDCdrawOFF);    ReleaseDC( hwnd, hDCdraw );    DeleteDC( hDCdrawOFF);    DeleteDC( hDCdraw);    DeleteObject( draw );    DeleteObject( hDraw );    DeleteObject( hDCdraw );    DeleteObject( hDCdrawOFF );}void Draw(LPCTSTR FileName, int x, int y, int sizex, int sizey, bool timer, int time)  //Draw with delay{    HINSTANCE hDraw = hThisInstance;    HDC hDCdraw = GetDC(hwnd);    HANDLE draw = LoadImage( hDraw, FileName, IMAGE_BITMAP, sizex, sizey, LR_LOADFROMFILE | LR_CREATEDIBSECTION );    HDC hDCdrawOFF = CreateCompatibleDC( hDCdraw );    SelectObject(hDCdrawOFF, draw);    GetObject( draw, sizeof(BITMAP), NULL );    if(timer)    {        double Counter = timeGetTime();  //Start Timer        if (Counter < time) //If time not passed by        Counter = timeGetTime();  //Update time        else            BitBlt( hDCdraw, x, y, sizex, sizey, hDCdrawOFF, 0, 0, SRCCOPY);  //If time gone by, draw BMP    }    //Cleanup    ReleaseDC( hwnd, hDCdrawOFF);    ReleaseDC( hwnd, hDCdraw );    DeleteDC( hDCdrawOFF);    DeleteDC( hDCdraw);    DeleteObject( draw );    DeleteObject( hDraw );}void Init(){    //Initialize new game variable if not loaded    Player.health = 100;    Player.attack = 10;    Player.level = 1;    Player.xp = 0;    Player.mana = 20;    Player.dead = false;    InvalidateRect(hwnd,NULL,FALSE);}void eInit(int dNum)  //Create demon{    switch(dNum)    {        case 1:  //Easiet            Demon.health = 15;            Demon.attack = 5;            Demon.xp = 25;            Demon.dead = false;            break;        case 2:  //Medium            Demon.health = 45;            Demon.attack = 15;            Demon.xp = 50;            Demon.dead = false;            break;        case 3:  //Hardest            Demon.health = 80;            Demon.attack = 45;            Demon.xp = 100;            Demon.dead = false;            break;    }}void save() //Save stats{    saveL();    saveX();    saveH();    saveA();    saveM();}void load()  //Load stats{    loadL();    loadX();    loadH();    loadA();    loadM();}void saveL(){    myFile = fopen("Data/L.svg","w+b");  //Open/Create Level save    fwrite(&Player.level, sizeof(int), 1, myFile);  //Write Player Level    fclose(myFile);  //Close Level save    DeleteObject( myFile );}void loadL(){    myFile = fopen("Data/L.svg","r+b");  //Open Level save    fread(&Player.level, sizeof(int), 1, myFile);  //Read in data    fclose(myFile); //Close Level save    DeleteObject( myFile );}void saveX(){    myFile = fopen("Data/X.svg","w+b");  //XP save    fwrite(&Player.xp, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void loadX(){    myFile = fopen("Data/X.svg","r+b");  //XP save    fread(&Player.xp, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void saveH(){    myFile = fopen("Data/H.svg","w+b");  //Health save    fwrite(&Player.health, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void loadH(){    myFile = fopen("Data/H.svg","r+b");  //Health save    fread(&Player.health, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void saveA(){    myFile = fopen("Data/A.svg","w+b");  //Attack save    fwrite(&Player.attack, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void loadA(){    myFile = fopen("Data/A.svg","r+b");  //Attack save    fread(&Player.attack, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void saveM(){    myFile = fopen("Data/M.svg","w+b");  //Mana save    fwrite(&Player.mana, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void loadM(){    myFile = fopen("Data/M.svg","r+b");  //Mana save    fread(&Player.mana, sizeof(int), 1, myFile);    fclose(myFile);    DeleteObject( myFile );}void Attack(bool player){    if (!player)  //If not attacking player        Demon.health = (Demon.health - Player.attack);  //Update Demon Health        if(Demon.health <= 0)  //If less than or equal to 0        {            Demon.health = 0;  //Health equals 0            Demon.dead = true;  //Set flag Demon Died        }    else if (player)  //If attacking player        Player.health = (Player.health - Demon.attack);  //Update Player Health    if (Player.health <= 0)    {        Player.health = 0;        Player.dead = true;    }}void AttackE()  //Attack east{    Sleep(delay);    Draw( "Data/Player/Attack/aE0.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE1.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE2.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE3.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE4.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE5.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE6.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE7.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE8.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE9.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE10.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE11.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    Draw( "Data/Player/Attack/aE12.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);}void WalkE(){    Draw( "Data/Player/Walk/wE0.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE1.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE2.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE3.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE4.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE5.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE6.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    Draw( "Data/Player/Walk/wE7.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testX = (testX + speed);    moving = false;}void WalkN(){    moving = false;    Draw( "Data/Player/Walk/wN0.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN1.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN2.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN3.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN4.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN5.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN6.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    Draw( "Data/Player/Walk/wN7.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY - speed);    moving = false;}void WalkS(){    moving = false;    Draw( "Data/Player/Walk/wS0.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS1.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS2.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS3.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS4.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS5.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS6.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    Draw( "Data/Player/Walk/wS7.bmp", testX, testY, 96, 96, true, aDelay);    Sleep(delay);    testY = (testY + speed);    moving = false;}void WalkW(){    moving = false;            testX = (testX - speed);            Draw( "Data/Player/Walk/wW0.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW1.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW2.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW3.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW4.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW5.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW6.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);            testX = (testX - speed);            Draw( "Data/Player/Walk/wW7.bmp", testX, testY, 96, 96, true, aDelay);            Sleep(delay);}void LevelUp(int nLevel){    switch(nLevel)    {        case 2:        Player.health = 110;        Player.mana = 30;        Player.attack = 15;        Player.level = 2;        break;        case 3:        Player.health = 125;        Player.mana = 45;        Player.attack = 25;        Player.level = 3;        break;        case 4:        Player.health = 140;        Player.mana = 60;        Player.attack = 45;        Player.level = 4;        break;        case 5:        Player.health = 185;        Player.mana = 70;        Player.attack = 60;        Player.level = 5;        break;        case 6:        Player.health = 200;        Player.mana = 85;        Player.attack = 70;        Player.level = 6;        break;    }}void DrawTxt(TCHAR Text[64]){    RECT test;    SetRect( &test, 200, 0, 300, 30 );    DrawText(hdc, Text, -1, &test, DT_SINGLELINE | DT_LEFT);}

Also, how would I draw text above the Player at any time with DrawTxt?

Thanks for your help. Peace



shanelaffond13
You are still leaking

For example, you are leaking a brush with this line:
FillRect(hdc, &screen, CreateSolidBrush(BG));

You should do something like this

HBRUSH hBrush = CreateSolidBrush(BG);
FillRect(hdc, &screen, hBrush);
DeleteObject(hBrush);

It's also incorrect to call DeleteObject() on a RECT as you do in this line:
DeleteObject( &screen );

If you want to know when and how to release objects you should check the documentation for these objects on the MSDN. Check the documentation for the functions you use to create the objects and the MSDN will tell you how to properly destroy them. In general, however, if you get the object from a GDI function beginning with "Create" then you destroy the object using a function beginning with "Delete". If you get it from a function beginning with "Get" then you release it with a function beginning with "Release". If the type begins with an H then it is a handle and probably needs to be released. Types which dont begin with H usually dont need to be released. This includes TCHAR (which I see you calling DeleteObject() on as well). You also try to do this with a FILE. The proper way to close a file is with the function fclose(), which you do use. Only use DeleteObject() with types that require you to.

In Draw() you are still inproperly cleaning up. You need to remember the original bitmap that was in hDCdrawOFF. Change this line
SelectObject(hDCdrawOFF, draw);

To something like this

HBITMAP hOldBmp = (HBITMAP)SelectObject(hDCdrawOFF, draw);
... rest of your code ...
SelectObject(hDCdrawOFF, hOldBmp);
ReleaseDC( hwnd, hDCdraw );
DeleteDC( hDCdrawOFF);
DeleteObject( draw );

Before you delete a DC always return it to its original state. Also note that in your above code I removed the call to ReleaseDC() for hDCdrawOFF and the call to DeleteDC() for hDCdraw. hDCdrawOFF was created using CreateCompatibleDC() and so must be destroyed using DeleteDC() and hDCdraw was created using GetDC() and so must be destroyed using ReleaseDC().

That's all I could see for now.

1) When you take your first step you stop because the keyboard has a delay before it starts to send repeat WM_KEYDOWN messages. It might be better for you to create a timer and whenever that timer fires call your walk functions (see 2 for a suggestion on their improvement). When you get the appropriate WM_KEYUP message kill the timer. Look into the functions SetTimer() and KillTimer().

2) If you want to prevent the player from going out of site check his position before you update where he is. If his new position will be valid (that is, within the viewing area) then update his current position, otherwise do nothing. You can handle this in your walk functions.

Note, your walk functions are all very similar. I suggest finding a way to combine them into a single function. You might want to try something like
Walk(int how_far_horizontal, int how_far_vertical)

3) If you want to draw text above your player you need to know your text's height. To do that you can either use GetTextMetrics() or GetTextExtentPoint32(). I would probably choose GetTextMetrics().

This topic is closed to new replies.

Advertisement