Can someone help me with my Code
Hi
I am just learning DirectX 7 at the moment and i am trying to do so animation with my character. I am using the Microsoft Visual C++ 6.0 Compiler the Standard Edition. I know DirectX 7 is an older version than the recent one but this is the one i am using for now. I have managed to display the Bitmaps to the screen but i would like them to flick through nicely. here is my code.
First is the DirectX.h file
// DEFINES //////////////////////////////////////////////////////
//main application handle
HINSTANCE Main_Instance =NULL;
//handle to our main window
HWND Main_Window =NULL;
#define MAX_PLAYER_FRAMES 2
/////////////////////////////////////////////////////////////////
// MACROS ///////////////////////////////////////////////////////
#define SAFERELEASE(x) { if (x) { x->Release(); x = NULL; } }
/////////////////////////////////////////////////////////////////
// INCLUDES /////////////////////////////////////////////////////
#include <ddraw.h>
/////////////////////////////////////////////////////////////////
// GLOBALS //////////////////////////////////////////////////////
// DIRECTDRAW GLOBALS
// The DirectDraw object, used to access the DirectDraw functions.
LPDIRECTDRAW7 lpDD = NULL;
// The primary DDraw surface, this represents the screen.
LPDIRECTDRAWSURFACE7 lpDDSPrimary = NULL;
// The back buffer, things are blitted onto this then flipped to
// the Primary surface.
LPDIRECTDRAWSURFACE7 lpDDSBack = NULL;
// A surface description structure, used to describe the
// different surfaces you make.
DDSURFACEDESC2 ddsd;
// A surface capabilities structure, used to tell
// CreateSurface() what kind of surface to create.
DDSCAPS2 ddscaps;
// This our bitmap create surface function
LPDIRECTDRAWSURFACE7 bitmap_surface(LPCTSTR file_name);
//This is the image we are going to load up..
LPDIRECTDRAWSURFACE7 My_Character[2] = { NULL, NULL };
int Frame_no = 1;
/////////////////////////////////////////////////////////////////
// PROTOTYPES ///////////////////////////////////////////////////
bool DD_INIT();
bool DD_SHUT_DOWN();
bool DD_LOAD_BITMAPS();
bool DD_Draw_Bitmap();
/////////////////////////////////////////////////////////////////
bool DD_INIT()
{
HRESULT ddrval;
ddrval = DirectDrawCreateEx(NULL, (LPVOID*)&lpDD,
IID_IDirectDraw7, NULL);
if (ddrval != DD_OK)
{
return FALSE;
}
// Set our cooperative level
ddrval = lpDD->SetCooperativeLevel(Main_Window, DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
if (ddrval != DD_OK)
{
return FALSE;
}
// Set our display mode
ddrval = lpDD->SetDisplayMode( 640, 480, 16, 0, 0 );
if (ddrval != DD_OK)
{
return FALSE;
}
// Create our primary surface
// Create the primary surface with 1 back buffer. Make it
// the height and width of the screen.
// First, zero the memory used by the ddsd structure.
// If you don''t do this, it may have some random data
// that might mess up CreateSurface().
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
// DDSD_CAPS makes CreateSurface() check the
// ddsd.ddsCaps.dwCaps value. DDS_BACKBUFFERCOUNT makes
// it check the ddsd.dwBackBufferCount value.
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
// Make it the primary surface that can be flipped.
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP | DDSCAPS_COMPLEX;
// Give it one back buffer.
ddsd.dwBackBufferCount = 1;
ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if (ddrval != DD_OK)
{
return FALSE;
}
// CREATE BACK BUFFER
ZeroMemory(&ddscaps, sizeof(ddscaps));
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface( &ddscaps, &lpDDSBack );
if (ddrval != DD_OK)
{
return FALSE;
}
return (true);
} // end of DD_Init
bool DD_SHUT_DOWN()
{
// When you have finished with DirectX you shoul always
// Release the interfaces that you have created there
// two important things to remember when doing this
// and they are
// 1. You must release the interfaces in reverse order
// in which they were created
// 2. attempting to release an interface that was never
// created will cause a program fault
SAFERELEASE(lpDDSBack);
SAFERELEASE(lpDDSPrimary);
SAFERELEASE(lpDD);
return (true);
} // end of DD_Shut_Down
// This is the bitmap surface creator function
LPDIRECTDRAWSURFACE7 bitmap_surface(LPCTSTR file_name)
{
HDC hdc;
HBITMAP bit;
BITMAP bitmap;
HRESULT ddrval;
LPDIRECTDRAWSURFACE7 surf;
// load the interface bitmap
bit = (HBITMAP) LoadImage(NULL, file_name, IMAGE_BITMAP, 0, 0,
LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (!bit)
// failed to load, return failure to caller
return NULL;
// get bitmap dimensions
GetObject( bit,sizeof(BITMAP), &bitmap ); // get the object as a bitmap
int surf_width = bitmap.bmWidth; // gather the properties
int surf_height = bitmap.bmHeight;
// Create Surface. When creating a new surface we use a
//SurfaceDescriptor to tell it what properties we want..
ZeroMemory( &ddsd, sizeof( ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = surf_width;
ddsd.dwHeight = surf_height;
// Attempt to create surface
// Using the properties we have set, create a new surface..
ddrval = lpDD->CreateSurface( &ddsd, &surf, NULL);
if (ddrval != DD_OK)
{
// release the bitmap and return failure to caller
DeleteObject(bit);
return NULL;
}
else
{
// Get a DC for the surface
surf->GetDC(&hdc);
// Generate a Compatible DC
HDC bit_dc = CreateCompatibleDC(hdc);
// blit the interface to the surface
SelectObject(bit_dc, bit);
BitBlt(hdc, 0, 0, surf_width, surf_height, bit_dc, 0, 0, SRCCOPY);
// Release the DCs
surf->ReleaseDC(hdc);
DeleteDC(bit_dc);
// Clear bitmap
DeleteObject(bit);
}
//WE succeeded, return the loaded directdraw surface..!
return (surf);
} // End of LPDIRECTDRAWSURFACE7 bitmap_surface(LPCTSTR file_name)
bool DD_LOAD_BITMAPS()
{
//Might for now as well load the image in here
My_Character[0] = bitmap_surface("My_Character1.bmp");
//If myImage is null, then the function didn''t work!
if(My_Character[0] == NULL)
{
//Might as well leave here, and return an error!
return(false);
}
//Might for now as well load the image in here
My_Character[1] = bitmap_surface("My_Character2.bmp");
//If myImage is null, then the function didn''t work!
if(My_Character[1] == NULL)
{
//Might as well leave here, and return an error!
return(false);
}
return (true);
} // end of DD_Load_Bitmaps()
bool DD_Draw_Bitmap()
{
//Put the image onto the backbuffer
lpDDSBack->BltFast(0,0, My_Character[Frame_no++], NULL, DDBLTFAST_WAIT);
//Now flip the backbuffer to the visible screen
lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);
if(Frame_no == MAX_PLAYER_FRAMES)
Frame_no = 0;
return (true);
}
Secondly here is my .cpp file
// DEFINES ////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to mfc
// define for windows
#define WINDOW_CLASS_NAME "WINCLASS1"
///////////////////////////////////////////////////////////////////////
// INCLUDES ///////////////////////////////////////////////////////////
// include the predefine .h files
#include <windows.h>
#include <ddraw.h>
// Include our own .h file
#include "DirectX.h"
///////////////////////////////////////////////////////////////////////
// GLOBALS ////////////////////////////////////////////////////////////
int Game_Main(void);
///////////////////////////////////////////////////////////////////////
// FUNCTIONS //////////////////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
// return success
return(0);
} break;
case WM_KEYDOWN:
{
if (wparam == VK_ESCAPE)
{
// if the escape key is pressed close window
DestroyWindow(hwnd);
DD_SHUT_DOWN();
}
} break;
case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
// you would do all your painting here
EndPaint(hwnd,&ps);
// return success
return(0);
} break;
case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
// return success
return(0);
} break;
default:break;
} // end switch
// process any messages we didn''t take care of
return(DefWindowProc(hwnd, msg, wparam, lparam));
} // end WinProc
///////////////////////////////////////////////////////////////////////
// WINMAIN ////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int nShowCmd)
{
//assign instance to global variable
Main_Instance = hinstance;
WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
// first fill in the window class structure
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = Main_Instance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"My Basic Window", // title
WS_POPUP | WS_VISIBLE,
0,0, // initial x,y
400,400, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
Main_Instance, // instance of this application
NULL))) // extra creation parms
return(0);
// Save the Main Window handle in to a GLOBAL
Main_Window = hwnd;
// Hide the mouse pointer
ShowCursor (FALSE);
// Make a call to initialize the DirectX
DD_INIT();
// Load our Character bitmap
DD_LOAD_BITMAPS();
// Enter the main event loop
while (1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Test if this is a quit message
if (msg.message == WM_QUIT)
break;
// Translate message
TranslateMessage(&msg);
// Dispatch message
DispatchMessage(&msg);
} // End if
else
{
// The Main_Game goes here
Game_Main();
} // End if
} // end while
DD_SHUT_DOWN();
// return to windows like this
return(msg.wParam);
} // end WinMain
///////////////////////////////////////////////////////////////////////
int Game_Main(void)
{
///////////////////////////////////////////////////////////////////////
// Start_Level goes here
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Game_Start Here
DD_Draw_Bitmap();
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// return success or failure
return (1);
///////////////////////////////////////////////////////////////////////
} // End of Game_Main
We Are Borg, Resistance Is Futile
We Are Borg, Resistance Is Futile
I have no idea about it, but I think you should use the
around your code.
[/source]
[edited by - germpest on January 31, 2003 5:18:11 PM]
// use [source]
[/source]
[edited by - germpest on January 31, 2003 5:18:11 PM]
And is this YOUR code not a books? (or tutorial)
A couple of things hint this...
Unless it's a tutorial!
DarkNebula
[edited by - DarkNebula on January 31, 2003 5:26:27 PM]
A couple of things hint this...
quote:
// When you have finished with DirectX you shoul always
// Release the interfaces that you have created there
// two important things to remember when doing this
// and they are
// 1. You must release the interfaces in reverse order
// in which they were created
// 2. attempting to release an interface that was never
// created will cause a program fault
Unless it's a tutorial!
DarkNebula
[edited by - DarkNebula on January 31, 2003 5:26:27 PM]
hi all
ok lets see if i can put this question in simple terms. ok first what i am trying to do is make the sprite animated. What i have done is loaded all the sprites in. Now i want them to flick through frame by frame like this.
frame1 = blit to screen then this will increment to frame2 = blit to screen then this will increment to frame3 = blit to screen then this will increment to frame4 = blit to screen then once it has reached frame four the maximum frames it will go back to frame1 and start the process all over again.
now this part works but i want to slow down the animation of this so it blits slower than it does.
We Are Borg, Resistance Is Futile
ok lets see if i can put this question in simple terms. ok first what i am trying to do is make the sprite animated. What i have done is loaded all the sprites in. Now i want them to flick through frame by frame like this.
frame1 = blit to screen then this will increment to frame2 = blit to screen then this will increment to frame3 = blit to screen then this will increment to frame4 = blit to screen then once it has reached frame four the maximum frames it will go back to frame1 and start the process all over again.
now this part works but i want to slow down the animation of this so it blits slower than it does.
We Are Borg, Resistance Is Futile
We Are Borg, Resistance Is Futile
January 31, 2003 04:47 PM
All you have to do is switch between the current cell (store it in a var) and an empty cell (contains no pixels).
Try this method: when you want it to blink, setup a flag to enable the code. Each frame, increment a variable by one, check to see if its a multiple of 2 (or whatever, the higher the number, the slower it blinks if you inc by 1), then if it is, set the animation frame to an empty cell. ELSE set the frame to the current frame buffer which you stored earlier.
You don''t have to have a animation frame buffer, but it will enable you to keep the sprites animation frames current and still blinking.
''currentframe'' can be set whenever you change the sprites main animation frame, that way, when its changed, so is the ''currentframe'' var for when it blinks.
Try this method: when you want it to blink, setup a flag to enable the code. Each frame, increment a variable by one, check to see if its a multiple of 2 (or whatever, the higher the number, the slower it blinks if you inc by 1), then if it is, set the animation frame to an empty cell. ELSE set the frame to the current frame buffer which you stored earlier.
You don''t have to have a animation frame buffer, but it will enable you to keep the sprites animation frames current and still blinking.
bool blinking; // Globalif (blinking){ var++; if (var%2) spriteframe=-1; else spriteframe=currentframe;}
''currentframe'' can be set whenever you change the sprites main animation frame, that way, when its changed, so is the ''currentframe'' var for when it blinks.
Do something like
int currenttime = timeGetTime();
if (TimeTillNextTick == 0) TimeTillNextTick = currenttime + GSpeed;
if (currenttime > TimeTillNextTick)
{
TimeTillNextTick += GSpeed;
Tick += 1;
}
You would then have your image change when the Tick variable increments. GSpeed would allow you to control the speed of the animation. I forget which header you need to #include to use timeGetTime() though.
int currenttime = timeGetTime();
if (TimeTillNextTick == 0) TimeTillNextTick = currenttime + GSpeed;
if (currenttime > TimeTillNextTick)
{
TimeTillNextTick += GSpeed;
Tick += 1;
}
You would then have your image change when the Tick variable increments. GSpeed would allow you to control the speed of the animation. I forget which header you need to #include to use timeGetTime() though.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement