cpu4ghz
asked on
Direct Draw, Movement problem.
Hi i'm currently programming a small game (similar to radian 2). and have come across a small problem with moving the ship.
1. I can't move the ship North-west while shooting.
2. I can't move the ship south-west while shooting.
The keys i have used for moving are:
Forward - W
backward - S
Left - A
Right - D
Shoot - Space.
I can move forward,backward,left,righ t,north-ea st & south east without any problems.
I have tried other keys for shoot, e.g. i tried F1 for shoot and the ship moves in all directions with no problems.
Can someone please tell me why i'm having this problem.
Note: If you see any problems with my code, e.g. style or bad programming practises please let me know =)
Also the way i've gotten the ship to shoot is probably pretty crude :) (didn't put much thought into it, Just wanted to check ways in which i could get the ship to shoot).
#include<stdlib.h>
#include<windows.h>
#include<ddraw.h>
#include<stdio.h>
#include<conio.h>
#define WIN32_LEAN_AND_MEAN
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define BPP 16 //bits per pixel
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code ) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code ) & 0x8000) ? 0 : 1)
#define DDRAW_INIT_STRUCT(ddstruct ) {memset(&ddstruct,0,sizeof (ddstruct) ); ddstruct.dwSize = sizeof(ddstruct);}
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
#define MAX_BULLET 15
#define LEFT 0x41
#define RIGHT 0x44
#define UP 0x57
#define DOWN 0x53
#define SHOOT 0x20
HWND Global_hWnd;
LPDIRECTDRAW Lpdd = NULL;
LPDIRECTDRAW7 Lpdd7 = NULL;
PALETTEENTRY Palette[256];
LPDIRECTDRAWPALETTE LpddPalette;
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE7 LpddsPrimary;
LPDIRECTDRAWSURFACE7 LpddsBack;
DDPIXELFORMAT ddpixel;
void ShootLeftBullet(int,int,in t);
void ShootRightBullet(int,int,i nt);
void ShootMiddleBullet(int,int, int);
int Window_Closed = 0;
RECT rMovement;
RECT rLeftBullet[16];
RECT rRightBullet[16];
RECT rMiddleBullet[16];
int MovementXposition = 310;
int MovementYposition = 420;
int BulletVelocity = 5;
int RateOfFire;
int BulletNumber;
LRESULT CALLBACK WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT pS;
HDC hDc;
switch(Msg)
{
case WM_CREATE:
break;
case WM_PAINT:
hDc = BeginPaint(hWnd,&pS);
EndPaint(hWnd,&pS);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,Msg,wPa ram,lParam );
}
int Game_Main(void *parms = NULL, int num_parms = 0)
{
DDBLTFX ddbltfx; //Used for the bliter
if(Window_Closed)
return(0);
if(KEYDOWN(VK_ESCAPE))
{
PostMessage(Global_hWnd,WM _CLOSE,0,0 );
Window_Closed = 1;
}
//Lock the back buffer Note: this is done so you can write to the back buffer.
LpddsBack->Lock(NULL,&ddsd ,DDLOCK_SU RFACEMEMOR YPTR | DDLOCK_WAIT, NULL);
UCHAR *Buffer = (UCHAR*)ddsd.lpSurface;
DDRAW_INIT_STRUCT(ddbltfx) ;
if(ddsd.lPitch == WINDOW_WIDTH)
{
memset(Buffer,0,640*2*480) ;
}
else
{
UCHAR* Buffer2 = Buffer;
for(int Count = 0; Count<WINDOW_HEIGHT;Count+ +)
{
memset(Buffer2,0,WINDOW_WI DTH*2);
Buffer2+=ddsd.lPitch;
}
}
LpddsBack->Unlock(NULL);
rMovement.left = MovementXposition;
rMovement.right = MovementXposition+20;
rMovement.top = MovementYposition;
rMovement.bottom= MovementYposition+50;
ddbltfx.dwFillColor = _RGB16BIT565(255,255,255);
LpddsBack->Blt(&rMovement,
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
ddbltfx.dwFillColor = _RGB16BIT565(255,0,0);
for(int count = 0; count<MAX_BULLET;count++)
{
LpddsBack->Blt(&rLeftBulle t[count],
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
LpddsBack->Blt(&rRightBull et[count],
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
LpddsBack->Blt(&rMiddleBul let[count] ,
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
}
LpddsPrimary->Flip(NULL,DD FLIP_WAIT) ;
if(KEYDOWN(LEFT))
{
if(MovementXposition>4)
{
MovementXposition-=4;
}
}
if(KEYDOWN(RIGHT))
{
if(MovementXposition<615)
{
MovementXposition+=4;
}
}
if(KEYDOWN(UP))
{
if(MovementYposition>2)
{
MovementYposition-=4;
}
}
if(KEYDOWN(DOWN))
{
if(MovementYposition<425)
{
MovementYposition+=4;
}
}
if(RateOfFire>=10)
{
if(KEYDOWN(SHOOT))
{
ShootLeftBullet(MovementXp osition,Mo vementYpos ition,Bull etNumber);
ShootRightBullet(MovementX position,M ovementYpo sition,Bul letNumber) ;
ShootMiddleBullet(Movement Xposition, MovementYp osition,Bu lletNumber );
RateOfFire=0;
if(BulletNumber<MAX_BULLET )
{
BulletNumber++;
}
else
{
BulletNumber=0;
}
}
}
for(int Count1=0;Count1<MAX_BULLET ;Count1++)
{
if(rLeftBullet[Count1].top >0)
{
rLeftBullet[Count1].top-=8 ;
rLeftBullet[Count1].bottom -=8;
rRightBullet[Count1].top-= 8;
rRightBullet[Count1].botto m-=8;
rMiddleBullet[Count1].top- =8;
rMiddleBullet[Count1].bott om-=8;
}
else
{
rLeftBullet[Count1].top = 0;
rLeftBullet[Count1].bottom = 0;
rRightBullet[Count1].top = 0;
rRightBullet[Count1].botto m = 0;
rMiddleBullet[Count1].top = 0;
rMiddleBullet[Count1].bott om = 0;
}
}
RateOfFire++;
Sleep(10);
return(1);
}
void ShootLeftBullet(int Xpos,int Ypos,int BulletNumber)
{
rLeftBullet[BulletNumber]. left = Xpos;
rLeftBullet[BulletNumber]. right = Xpos+1;
rLeftBullet[BulletNumber]. top = Ypos;
rLeftBullet[BulletNumber]. bottom = Ypos+10;
}
void ShootRightBullet(int Xpos,int Ypos,int BulletNumber)
{
rRightBullet[BulletNumber] .left = Xpos+19;
rRightBullet[BulletNumber] .right = Xpos+20;
rRightBullet[BulletNumber] .top = Ypos;
rRightBullet[BulletNumber] .bottom = Ypos+10;
}
void ShootMiddleBullet(int Xpos,int Ypos,int BulletNumber)
{
rMiddleBullet[BulletNumber ].left = Xpos+9;
rMiddleBullet[BulletNumber ].right = Xpos+11;
rMiddleBullet[BulletNumber ].top = Ypos;
rMiddleBullet[BulletNumber ].bottom = Ypos+10;
}
int Game_Init(void *parms = NULL, int num_parms = 0)
{
srand(GetTickCount());
ShowCursor(false);
if(FAILED(DirectDrawCreate (NULL,&Lpd d,NULL)))
{
return(0);
}
if(FAILED(Lpdd->QueryInter face(IID_I DirectDraw 7,(LPVOID* )&Lpdd7)))
{
return(0);
}
Lpdd->Release();
Lpdd = NULL;
if(FAILED(Lpdd7->SetCooper ativeLevel (Global_hW nd,
DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE |
DDSCL_ALLOWREBOOT|
DDSCL_ALLOWMODEX)))/*Note: i don't think that it is required
to addd DDSCL_ALLOWMODEX, as this only allows
you to use 320*240, & no one uses this....*/
{
return(0);
}
Lpdd7->SetDisplayMode(WIND OW_WIDTH,W INDOW_HEIG HT,BPP,0,0 );
DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |DDSCAPS_COMPLEX;
if(FAILED(Lpdd7->CreateSur face(&ddsd ,&LpddsPri mary,NULL) ))
{
return(0);
}
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
LpddsPrimary->GetAttachedS urface(&dd sd.ddsCaps ,&LpddsBac k);
return(1);
}
int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
if(LpddsPrimary)
{
LpddsPrimary->Release();
LpddsPrimary = NULL;
}
if(LpddPalette)
{
LpddPalette->Release();
LpddPalette = NULL;
}
if(Lpdd7)
{
Lpdd7->Release();
Lpdd7 = NULL;
}
return(1);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX WndClass;
HWND hWnd;
MSG Msg;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLA CK_BRUSH);
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW) ;
WndClass.hIcon = LoadIcon(NULL,IDI_ERROR);
WndClass.hIconSm = LoadIcon(NULL,IDI_ERROR);
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = "Class1";
WndClass.lpfnWndProc = WinProc;
WndClass.style = CS_DBLCLKS | CS_VREDRAW |
CS_HREDRAW | CS_OWNDC;
if(!RegisterClassEx(&WndCl ass))
{
MessageBox(NULL,"Could not Register Class.","Error",MB_OK |MB_ICONERROR);
return(-1);
}
/*This will create the window, and defines window properties*/
if(!(hWnd = CreateWindowEx(NULL,
"Class1",
"Practise Window",
WS_POPUP | WS_VISIBLE,
350,
150,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL,
NULL,
hInstance,
NULL)))
{
MessageBox(NULL,"Could not Create Window.","Error",MB_OK|MB_ ICONERROR) ;
}
Global_hWnd = hWnd;
Game_Init();
while(1)
{
if(PeekMessage(&Msg,NULL,0 ,0,PM_REMO VE))
{
if(Msg.message==WM_QUIT)
{
break;
}
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
Game_Main();
}
Game_Shutdown();
return Msg.wParam;
}
1. I can't move the ship North-west while shooting.
2. I can't move the ship south-west while shooting.
The keys i have used for moving are:
Forward - W
backward - S
Left - A
Right - D
Shoot - Space.
I can move forward,backward,left,righ
I have tried other keys for shoot, e.g. i tried F1 for shoot and the ship moves in all directions with no problems.
Can someone please tell me why i'm having this problem.
Note: If you see any problems with my code, e.g. style or bad programming practises please let me know =)
Also the way i've gotten the ship to shoot is probably pretty crude :) (didn't put much thought into it, Just wanted to check ways in which i could get the ship to shoot).
#include<stdlib.h>
#include<windows.h>
#include<ddraw.h>
#include<stdio.h>
#include<conio.h>
#define WIN32_LEAN_AND_MEAN
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define BPP 16 //bits per pixel
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code
#define DDRAW_INIT_STRUCT(ddstruct
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
#define MAX_BULLET 15
#define LEFT 0x41
#define RIGHT 0x44
#define UP 0x57
#define DOWN 0x53
#define SHOOT 0x20
HWND Global_hWnd;
LPDIRECTDRAW Lpdd = NULL;
LPDIRECTDRAW7 Lpdd7 = NULL;
PALETTEENTRY Palette[256];
LPDIRECTDRAWPALETTE LpddPalette;
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE7 LpddsPrimary;
LPDIRECTDRAWSURFACE7 LpddsBack;
DDPIXELFORMAT ddpixel;
void ShootLeftBullet(int,int,in
void ShootRightBullet(int,int,i
void ShootMiddleBullet(int,int,
int Window_Closed = 0;
RECT rMovement;
RECT rLeftBullet[16];
RECT rRightBullet[16];
RECT rMiddleBullet[16];
int MovementXposition = 310;
int MovementYposition = 420;
int BulletVelocity = 5;
int RateOfFire;
int BulletNumber;
LRESULT CALLBACK WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT pS;
HDC hDc;
switch(Msg)
{
case WM_CREATE:
break;
case WM_PAINT:
hDc = BeginPaint(hWnd,&pS);
EndPaint(hWnd,&pS);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,Msg,wPa
}
int Game_Main(void *parms = NULL, int num_parms = 0)
{
DDBLTFX ddbltfx; //Used for the bliter
if(Window_Closed)
return(0);
if(KEYDOWN(VK_ESCAPE))
{
PostMessage(Global_hWnd,WM
Window_Closed = 1;
}
//Lock the back buffer Note: this is done so you can write to the back buffer.
LpddsBack->Lock(NULL,&ddsd
UCHAR *Buffer = (UCHAR*)ddsd.lpSurface;
DDRAW_INIT_STRUCT(ddbltfx)
if(ddsd.lPitch == WINDOW_WIDTH)
{
memset(Buffer,0,640*2*480)
}
else
{
UCHAR* Buffer2 = Buffer;
for(int Count = 0; Count<WINDOW_HEIGHT;Count+
{
memset(Buffer2,0,WINDOW_WI
Buffer2+=ddsd.lPitch;
}
}
LpddsBack->Unlock(NULL);
rMovement.left = MovementXposition;
rMovement.right = MovementXposition+20;
rMovement.top = MovementYposition;
rMovement.bottom= MovementYposition+50;
ddbltfx.dwFillColor = _RGB16BIT565(255,255,255);
LpddsBack->Blt(&rMovement,
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
ddbltfx.dwFillColor = _RGB16BIT565(255,0,0);
for(int count = 0; count<MAX_BULLET;count++)
{
LpddsBack->Blt(&rLeftBulle
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
LpddsBack->Blt(&rRightBull
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
LpddsBack->Blt(&rMiddleBul
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
}
LpddsPrimary->Flip(NULL,DD
if(KEYDOWN(LEFT))
{
if(MovementXposition>4)
{
MovementXposition-=4;
}
}
if(KEYDOWN(RIGHT))
{
if(MovementXposition<615)
{
MovementXposition+=4;
}
}
if(KEYDOWN(UP))
{
if(MovementYposition>2)
{
MovementYposition-=4;
}
}
if(KEYDOWN(DOWN))
{
if(MovementYposition<425)
{
MovementYposition+=4;
}
}
if(RateOfFire>=10)
{
if(KEYDOWN(SHOOT))
{
ShootLeftBullet(MovementXp
ShootRightBullet(MovementX
ShootMiddleBullet(Movement
RateOfFire=0;
if(BulletNumber<MAX_BULLET
{
BulletNumber++;
}
else
{
BulletNumber=0;
}
}
}
for(int Count1=0;Count1<MAX_BULLET
{
if(rLeftBullet[Count1].top
{
rLeftBullet[Count1].top-=8
rLeftBullet[Count1].bottom
rRightBullet[Count1].top-=
rRightBullet[Count1].botto
rMiddleBullet[Count1].top-
rMiddleBullet[Count1].bott
}
else
{
rLeftBullet[Count1].top = 0;
rLeftBullet[Count1].bottom
rRightBullet[Count1].top = 0;
rRightBullet[Count1].botto
rMiddleBullet[Count1].top = 0;
rMiddleBullet[Count1].bott
}
}
RateOfFire++;
Sleep(10);
return(1);
}
void ShootLeftBullet(int Xpos,int Ypos,int BulletNumber)
{
rLeftBullet[BulletNumber].
rLeftBullet[BulletNumber].
rLeftBullet[BulletNumber].
rLeftBullet[BulletNumber].
}
void ShootRightBullet(int Xpos,int Ypos,int BulletNumber)
{
rRightBullet[BulletNumber]
rRightBullet[BulletNumber]
rRightBullet[BulletNumber]
rRightBullet[BulletNumber]
}
void ShootMiddleBullet(int Xpos,int Ypos,int BulletNumber)
{
rMiddleBullet[BulletNumber
rMiddleBullet[BulletNumber
rMiddleBullet[BulletNumber
rMiddleBullet[BulletNumber
}
int Game_Init(void *parms = NULL, int num_parms = 0)
{
srand(GetTickCount());
ShowCursor(false);
if(FAILED(DirectDrawCreate
{
return(0);
}
if(FAILED(Lpdd->QueryInter
{
return(0);
}
Lpdd->Release();
Lpdd = NULL;
if(FAILED(Lpdd7->SetCooper
DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE |
DDSCL_ALLOWREBOOT|
DDSCL_ALLOWMODEX)))/*Note:
to addd DDSCL_ALLOWMODEX, as this only allows
you to use 320*240, & no one uses this....*/
{
return(0);
}
Lpdd7->SetDisplayMode(WIND
DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |DDSCAPS_COMPLEX;
if(FAILED(Lpdd7->CreateSur
{
return(0);
}
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
LpddsPrimary->GetAttachedS
return(1);
}
int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
if(LpddsPrimary)
{
LpddsPrimary->Release();
LpddsPrimary = NULL;
}
if(LpddPalette)
{
LpddPalette->Release();
LpddPalette = NULL;
}
if(Lpdd7)
{
Lpdd7->Release();
Lpdd7 = NULL;
}
return(1);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX WndClass;
HWND hWnd;
MSG Msg;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLA
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW)
WndClass.hIcon = LoadIcon(NULL,IDI_ERROR);
WndClass.hIconSm = LoadIcon(NULL,IDI_ERROR);
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = "Class1";
WndClass.lpfnWndProc = WinProc;
WndClass.style = CS_DBLCLKS | CS_VREDRAW |
CS_HREDRAW | CS_OWNDC;
if(!RegisterClassEx(&WndCl
{
MessageBox(NULL,"Could not Register Class.","Error",MB_OK |MB_ICONERROR);
return(-1);
}
/*This will create the window, and defines window properties*/
if(!(hWnd = CreateWindowEx(NULL,
"Class1",
"Practise Window",
WS_POPUP | WS_VISIBLE,
350,
150,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL,
NULL,
hInstance,
NULL)))
{
MessageBox(NULL,"Could not Create Window.","Error",MB_OK|MB_
}
Global_hWnd = hWnd;
Game_Init();
while(1)
{
if(PeekMessage(&Msg,NULL,0
{
if(Msg.message==WM_QUIT)
{
break;
}
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
Game_Main();
}
Game_Shutdown();
return Msg.wParam;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.