Archived

This topic is now archived and is closed to further replies.

help the newbie, help the newbie

This topic is 5112 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ive tried to do bullets again and again. where you have a gun on screen, press spacebar and woah! its a shot, unfortunately if you press it again it delets the shot you just fired and refires it. if you wait until the shot is out of the screen, same thing. does anyone know how to make it so that if you press it, it fires and then if you press it again, hey!, it fires a new shot. and so on and so forth, but every time the shot you fired goes out of the screen it deletes itself. its like a....machine gun (so to speak). please, im trying to make a 2D shooter, where you walk around and shoot people but i need this gun thing working. please, any advice would be greatly apreciated. Thanks in advance

Share this post


Link to post
Share on other sites
You just have to create an array of bullets and keep track of each''s state, and when you shoot, set the bullets state on. Like this (C/C++?):

const int MAX_BULLETS_ON_SCREEN = 50;
const int BULLET_STATE_ON = 1;
const int BULLET_STATE_OFF = 0;

struct BULLETS
{
int state;
int x, y;
// All the other stuff
}bullets[MAX_BULLETS_ON_SCREEN];

// Some code..

// Now its time to shoot
for(int i = 0; i < MAX_BULLETS_ON_SCREEN; i++)
{
if(bullets.state == BULLET_STATE_OFF)
{
// You can shoot this one
Shoot(&bullets[i]);
bullets[i].state = BULLET_STATE_ON;
}
}


Maybe that isn''t the fastest way to do it, but it works.

Hope that helps.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
[removed and regular posting account noted]

[edited by - michalson on December 18, 2003 7:59:52 PM]

Share this post


Link to post
Share on other sites
k i will post my code soon enough and here it is:
#include <windows.h>
#include <vector>

#define WIN_WID 640
#define WIN_HGT 480

#define IMG_WID 128 // Width of our image
#define IMG_HGT 128 // Height of our image

#define class_name "GameTutorials_DoubleBuffer"
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

#define THE_COLOR RGB(255,0,255)

#define DOUBLE_BUFFER 1 // Change this to zero to view the app without double buffering

// This is the struct that will hold all of our double buffering info
struct SDBuffer
{
HWND win_hwnd; // A copy of the window handle

HDC win_dc; // This is the window''s HDC
HDC back_dc; // This is the HDC to the back buffer we''re gonna make

RECT rect; // This will hold the client RECT of our window

HBITMAP back_bmp; // This is the HBITMAP that we''ll fill with an exact copy of
// our window''s HBITMAP (pixels)

HBITMAP old_bmp; // We need this guy around so we can totally free up memory when it''s
// all said and done
};

struct Bullet
{
int x;
int state;
int y;
bool destroyed;
};

struct Ship
{
int x;
int y;
};
// Globals ***

int xPos = 0; // This will hold the upper left hand x-coord of the mouse
int yPos = 0; // This will hold the upper left hand y-ccord of the mouse

HBITMAP three_bmp = (HBITMAP)LoadImage(NULL,"laser_blast.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
HBITMAP back_bmp = (HBITMAP)LoadImage(NULL,"background.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
HBITMAP ship_bmp = (HBITMAP)LoadImage(NULL,"ship.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

const int MAX_BULLETS = 100;
const int BULLET_STATE_ON = 1;
const int BULLET_STATE_OFF = 0;
Ship player;
Bullet bullets[MAX_BULLETS];
#define STATE_ONE 1
#define STATE_TWO 2
#define STATE_THREE 3
int x = 0;
int x_vel = 10;
int y = 0;
#define TIME_OF_DELAY 10;
bool animate(int bullet_per_second);
int wait = 0;
HDC wonder = NULL;
int state = STATE_ONE;
SDBuffer doubleBuff = {0}; // This is our "double buffer" struct

// *** End of Globals
void key();
// This will set up our double buffering. We return true on success, false on failure
bool InitDoubleBuffer(SDBuffer &doubleBuff);

// This funciton will free up all the memory associated with our double buffer
void FreeDoubleBuffer(SDBuffer &doubleBuff);

// Locks the frame rate at the passed in frame rate (60 FPS by default)
bool LockFrameRate(int frame_rate = 60);
void check_bullets();
void game_init();
// Standard callback function
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclassex = {0};


// Fill the fields we care about
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WinProc;
wndclassex.hInstance = hinstance;
wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclassex.lpszClassName = class_name;

RegisterClassEx(&wndclassex); // Register the window

hwnd = CreateWindowEx(NULL, // No extra window attributes
class_name,
"www.GameTutorials.com -- Double Buffering",
WS_POPUP,
0, // Window will receive a default x pos on screen
0, // Window will receive a default y pos on screen
WIN_WID,
WIN_HGT,
NULL,
NULL,
hinstance,
NULL);

// Error check
if(!hwnd)
{
UnregisterClass(class_name,hinstance);
return EXIT_FAILURE; // Something really bad happened!
}

doubleBuff.win_hwnd = hwnd; // Set the HWND of our double buffer struct

// Attempt to initialize our double buffering
if(!InitDoubleBuffer(doubleBuff))
{
UnregisterClass(class_name,hinstance);
return EXIT_FAILURE; // Couldn''t set up double buffering
}

// Here we''ll load up our bitmap
HBITMAP img_bmp = (HBITMAP)LoadImage(hinstance,"background.bmp",IMAGE_BITMAP,
0,0,LR_LOADFROMFILE);

// Error Check
if(!img_bmp)
{
UnregisterClass(class_name,hinstance);
return EXIT_FAILURE; // Couldn''t load our image
}

game_init();
// Change To FullScreen

// Create a compatible HDC so that we can draw our "img_bmp"
HDC img_dc = CreateCompatibleDC(doubleBuff.win_dc);
wonder = img_dc;
if(!img_dc)
{
UnregisterClass(class_name,hinstance);
return EXIT_FAILURE;
}

// Select our "img_bmp" into the "img_dc"
HBITMAP old_bmp = (HBITMAP)SelectObject(img_dc,img_bmp);

ShowWindow(hwnd, ishow);
UpdateWindow(hwnd);

while(1)
{
// Check message(s) if there are any
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(LockFrameRate())
{
check_bullets();
key();
#if DOUBLE_BUFFER // If we are using double buffering

// First we fill our back buffer to solid white (the same color as the
// background color of our window)
FillRect(doubleBuff.back_dc,&doubleBuff.rect,(HBRUSH)GetStockObject(WHITE_BRUSH));

// Next we''ll draw the bitmap to our back buffer

old_bmp = (HBITMAP)SelectObject(img_dc,ship_bmp);

BitBlt(doubleBuff.back_dc,player.x,player.y,250,350,img_dc,0,0,SRCCOPY);

for(int i = 0; i < MAX_BULLETS; i++)
{
old_bmp = (HBITMAP)SelectObject(img_dc,three_bmp);

BitBlt(doubleBuff.back_dc,bullets.x,bullets[i].y,27,50,img_dc,
0,0,SRCCOPY);
}

// Then we draw the back buffer to the front buffer (our window)
BitBlt(doubleBuff.win_dc,0,0,doubleBuff.rect.right,
doubleBuff.rect.bottom,doubleBuff.back_dc,0,0,SRCCOPY);

#else // No double buffering in use

// We fill our window with solid white so we can clear away the "old"
// position of the image
FillRect(doubleBuff.win_dc,&doubleBuff.rect,(HBRUSH)GetStockObject(WHITE_BRUSH));

// Blit the image to the window

// **NOTE** Do not be mislead by the use of the "doubleBuff" variable.
// We are ONLY using this to access the window''s HDC. Absolutely
// no double buffering goes on in the between the #else and the
// #endif. Be sure to look at how worse it looks without double
// buffering.

#endif
}

}

// Free up our image memory
SelectObject(img_dc,old_bmp);
DeleteDC(img_dc);

// Free up all the memory associated with our back buffer
FreeDoubleBuffer(doubleBuff);

UnregisterClass(class_name,hinstance); // Free up WNDCLASSEX
return msg.wParam;
}

// The WinProc
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps;

// Depending on the message -- we''ll do different stuff
switch(message)
{
case WM_PAINT:

BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return 0;

// Message we get when the mouse moves
case WM_MOUSEMOVE:

xPos = LOWORD(lparam); // X position of cursor
yPos = HIWORD(lparam); // Y position of cursor
return 0;

case WM_DESTROY:
case WM_CLOSE:

PostQuitMessage(0);
return 0;

} // end of switch(message)

return DefWindowProc(hwnd, message, wparam, lparam);
}

// Here will create/initialize our double buffer
// Return true on success, false on failure
bool InitDoubleBuffer(SDBuffer &doubleBuff)
{
// Error Check
if(!doubleBuff.win_hwnd)
return false; // Not a valid window HWND

// First and foremost we are going to get and store off the CLIENT RECT of our
// window. The client area (client rect) is the portion of a window where the
// application displays output, such as text, graphics, etc, etc
GetClientRect(doubleBuff.win_hwnd,&doubleBuff.rect); // Get the client RECT

// The next thing we are going to do is store off the window''s
// HDC. Remember you can think of the HDC as a way to "talk to" all of the
// pixels that make up the window.
doubleBuff.win_dc = GetDC(doubleBuff.win_hwnd); // Get the window''s HDC

// Error Check
if(doubleBuff.win_dc == NULL)
return false;

// Okay we have the window''s HDC. What we want to do is create a replicable
// in memory of the window''s pixels that we are able to draw to. So that
// means we''ll need a HDC that can interface (is compatible to) the window''s
// HDC. Thus we create a compatible HDC
doubleBuff.back_dc = CreateCompatibleDC(doubleBuff.win_dc);

// Error Check
if(doubleBuff.back_dc == NULL)
return false;

// So now we have a means to talk to our back buffer, but we DO NOT have
// the buffer (the set aside memory that will hold the pixel information).
// No worries, we''ll just create a compatible bitmap the SAME size as
// our window''s client area
doubleBuff.back_bmp = CreateCompatibleBitmap(doubleBuff.win_dc,
doubleBuff.rect.right,
doubleBuff.rect.bottom);

// Error Check
if(doubleBuff.back_bmp == NULL)
return false;

// If we get here that means we were successful in creating a "buffer" that
// mimics the windows front buffer. But before we can draw to our newly
// created buffer, we have to tell the "back buffer''s HDC" that it is
// associated with (or in charge of) the "back buffer''s HBITMAP -- Thus we
// select the created back buffer into our back buffer''s device context
doubleBuff.old_bmp = (HBITMAP)SelectObject(doubleBuff.back_dc,doubleBuff.back_bmp);

// **NOTE** remember we save off the return from SelectObject() so we can FULLY
// free up memory before we close the application

return true; // We be buff
}

// This function will free up all the memory we allocated
void FreeDoubleBuffer(SDBuffer &doubleBuff)
{
// Error Check
if(!doubleBuff.win_hwnd)
return;

if(doubleBuff.old_bmp) // If we have a double buffer
{
// Select back the original "bitmap"
SelectObject(doubleBuff.back_dc,doubleBuff.old_bmp);

// Free up memory
DeleteObject(doubleBuff.back_bmp);
DeleteDC(doubleBuff.back_dc);
}

if(doubleBuff.win_dc) // If we have the window''s device context
{
// Relese the device context
ReleaseDC(doubleBuff.win_hwnd,doubleBuff.win_dc);
}

// Set everything to zero
memset(&doubleBuff,0,sizeof(SDBuffer));
}

// Locks the frame rate at "frame_rate"
// Returns true when it''s okay to draw, false otherwise
bool LockFrameRate(int frame_rate)
{
static float lastTime = 0.0f;

// Get current time in seconds (milliseconds * .001 = seconds)
float currentTime = GetTickCount() * 0.001f;

// Get the elapsed time by subtracting the current time from the last time
// If the desired frame rate amount of seconds has passed -- return true (ie Blit())
if((currentTime - lastTime) > (1.0f / frame_rate))
{
// Reset the last time
lastTime = currentTime;
return true;
}

return false;
}

void key()
{
if(KEYDOWN(VK_ESCAPE))
{
PostQuitMessage(0);
}
}

void check_bullets()
{
if(KEYDOWN(VK_SPACE))
{
if(animate(2) == TRUE)
{
for(int i = 0; i < MAX_BULLETS; i++)
{
if(bullets[i].state == BULLET_STATE_OFF)
{
// You can shoot this one
bullets[i].state = BULLET_STATE_ON;
break;
}
}
}
}

for(int fire = 0; fire < MAX_BULLETS; fire++)
{
if(bullets[fire].state == BULLET_STATE_ON)
{
bullets[fire].y -= 5;
}

if(bullets[fire].y <= 0)
{
bullets[fire].y = WIN_HGT;
bullets[fire].state = BULLET_STATE_OFF;
}
}
}

void game_init()
{
for(int i = 0; i < MAX_BULLETS; i++)
{
bullets[i].x = 200;
bullets[i].y = WIN_HGT;
}
}

bool animate(int bullet_per_second)
{
static float lastTime = 0.0f;
float elapsedTime = 0.0;

// Get current time in seconds (milliseconds * .001 = seconds)
float currentTime = timeGetTime() * 0.001f;

// Get the elapsed time by subtracting the current time from the last time
elapsedTime = currentTime - lastTime;

// Check if the time since we last checked is over (1 second / framesPerSecond)
if( elapsedTime > (1.0f / bullet_per_second) )
{
// Reset the last time
lastTime = currentTime;

// Return TRUE, to animate the next frame of animation
return TRUE;
}

// We don''t animate right now.
return FALSE;
}

k, tell me what im doing wrong (if anything).
o and if i change the function BitBlt(); to TransparentBlt(); you can shoot about 3 times before the whole program screws up. o and Anonymous Poster FSCK YOU, stop posting S*IT. A**H*LE.

Share this post


Link to post
Share on other sites
Shouldn''t you test if the bullet is flying before you draw it?You should also keep old_bmp = ... outside that for loop.
Do it like this instead:

old_bmp = (HBITMAP)SelectObject(img_dc,three_bmp);

for(int i = 0; i < MAX_BULLETS; i++)
{
if(bullets.state == BULLET_STATE_ON)
{
BitBlt(doubleBuff.back_dc,bullets[i].x,bullets[i].y,27,50,img_dc,
0,0,SRCCOPY);
}
}


That is the only bad thing I found in your code, so if TransparentBlit doesn''t work, I have no idea what could cause crashing.

Share this post


Link to post
Share on other sites
the only thing that would make it crash is microsofts post that the transparentblt(); function leaks memory in Win98 and NT so....if you have any solutions to this one..hehe...please tell me...of course if your solution is to use BitBlt();...i already thought of that but i want it transparent......so....what to do????? and what do you mean what the bloody hell happened???

Share this post


Link to post
Share on other sites