• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
v0rtexza

Limiting Bullets and stopping spamming - DirectX

8 posts in this topic

Hey all, I am making a simple sidescroller space shooter and have encountered a problem. I do not know how to limit the amount of bullets adequately or control the difference between input times.

Here is the relevant code that I know is the problem.

I create space in memory for my bullet sprites and I set their default properties (according to my own class):

[source lang="cpp"]//bullet sprites
const int MAX_BULLETS = 20;
SPRITE bullets [MAX_BULLETS];

//set default properties
for (int j = 0; j < MAX_BULLETS;j++)
{
bullets[j].alive = false;
bullets[j].startframe = 0;
bullets[j].endframe = 1;
bullets[j].delay = 10;
bullets[j].x = 0;
bullets[j].y = 0;
bullets[j].height = 55;
bullets[j].width = 16;
bullets[j].columns = 1;
bullets[j].vely = 6.0f;
}
imgBullet = LoadTexture("purplefire.tga");
if (!imgBullet) return false;
player_shoot_timer = 0;[/source]

I then go onto set bullets to alive when I click space bar like so:

[source lang="cpp"]if (Key_Down(DIK_SPACE)) {
//limit firing rate
if ((int)timeGetTime() < player_shoot_timer + 100) return;
player_shoot_timer = timeGetTime();

if (CurrentBullet >= MAX_BULLETS) CurrentBullet = 0;
CurrentBullet++;
bullets[CurrentBullet].alive = true;
bullets[CurrentBullet].x = player.x + (player.width/2);
bullets[CurrentBullet].y = player.y;
}[/source]
But the above code is not adequately stopping me from shooting if I hold down for example space bar, any ideas on that?

Finally in my actual game loop, I render the bullets that are deemed "alive" or have been shot already:

[source lang="cpp"]for (int k = 0;k < MAX_BULLETS;k++)
{

if (bullets[k].isAlive() == true)
{

bullets[k].y -= bullets[k].vely;
// Sprite_Animate(bullets[k].frame,bullets[k].startframe,bullets[k].endframe,1,bullets[k].starttime,bullets[k].delay);
Sprite_Draw_Frame(imgBullet,bullets[k].x,bullets[k].y,bullets[k].frame,bullets[k].width,bullets[k].height,bullets[k].columns);

}
}[/source]

However the problem is that I can hold down spacebar and it will just keep rendering the bullets to that spot and once I finish the program/close it, I get the following error:

Unhandled exception at 0x61a659da (msvcr100d.dll) in Tile_Dynamic_Scroll.exe: 0xC0000005: Access violation reading location 0x4424aac2.

I am guessing this is because I am not resetting the bullets adequately but I can't figure out:

a) how to create a time between each fired bullet so that the user cannot spam spacebar, my current implementation does not work
b) Limit the amount of bullets fired and reset them accordingly.

(if any more code is needed, I will supply upon request as the entire project is largeish)

I do not want the complete answer but merely a nudge in the right direction, any help is appreciated.

Thanks, v0rtex
0

Share this post


Link to post
Share on other sites
In the second code snippet you are always creating a bullet every 100ms even if MAX_BULLETS are already alive, that means the bullet are constantly being reset to the player's position.
As for the exception: Have you tried running the program in debug mode and pause when the exception happens?
1

Share this post


Link to post
Share on other sites
In addition to Madhed's suggestion, your access violation is a buffer overrun:

[code]
if (CurrentBullet >= MAX_BULLETS) CurrentBullet = 0;
CurrentBullet++;
[/code]

Recall that an array of N elements is named from 0 to N-1. If [tt]CurrentBullet == MAX_BULLETS-1[/tt], then the tested condition is false in the first line of this snippet. After executing the next line, [tt]CurrentBullet == MAX_BULLETS[/tt], which is an invalid index in the array [tt]bullets[/tt].
2

Share this post


Link to post
Share on other sites
(Can't edit my post?!)

Any attempt to write to past the end of [tt]bullets[/tt] will either cause your program to crash (best case), an unrelated bug to appear elsewhere (unfavorable), or behave exactly as expected (worst case).

Addendum to Madhed's suggestion:
You may want to consider searching for a dead bullet to create your new bullet as you may overwrite an existing living bullet.

Another consideration:
You might want to consider using [url=http://www.cplusplus.com/reference/stl/vector/]std::vector[/tt], which is a dynamically resizing array with additional safety checks in your debug build.
1

Share this post


Link to post
Share on other sites
Wow lol, was focusing so much on the graphics and DirectX that I forgot something as simple as that. Thanks! My only last problem is that I do not know how to space input, so that for example when you click space. Only 1 shot is registered, at the moment whenever space is held down, my variable CurrentBullet (as seen in the listing above) continually increases as much as I click instead of only registering one click. Any ideas?
0

Share this post


Link to post
Share on other sites
You'll need to move from this sort of logic:
[code]
if ( isKeyPressed( KEY_SPACE ) ) {
// ...
}
[/code]

To this (quickfix):
[code]
// Assume: bool keySpaceIsHeld = false;
if ( isKeyPressed( KEY_SPACE ) ) {
if ( !keySpaceIsHeld ) {
keySpaceIsHeld = true;
// ...
}
} else
keySpaceIsHeld = false;
[/code]

However, this approach is tedious and the OS already provides this functionality. Since you're using win32, you can handle the [url=http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280%28v=vs.85%29.aspx][tt]WM_KEYDOWN[/tt][/url] message in your event loop and signal the object responsible for firing the bullet:

[code]
LRESULT CALLBACK wndproc( HWND h, INT msg, WPARAM wParam, LPARAM lParam ) { // (Guessing this declaration here)
switch ( msg ) {
case WM_KEYDOWN: {
switch ( wParam ) {
case VK_SPACE:
player->fireBullet();
break;
// etc...
}
} break;

// etc...
}

return DefWndProc( h, msg, wParam, lParam ); //
}
[/code]
1

Share this post


Link to post
Share on other sites
Thanks fastcall22, I tried your first solution:

[source lang="cpp"] if (Key_Down(DIK_SPACE))
{
//limit firing rate
// if (GetTickCount() - player_shoot_timer > 100) return;
//player_shoot_timer = GetTickCount();
if (!keySpaceIsHeld)
keySpaceIsHeld = true;
if (keySpaceIsHeld)
{
if (CurrentBullet == MAX_BULLETS -1) return; //CurrentBullet = Max Ammo, So Exit
if (CurrentBullet < MAX_BULLETS) //If there are bullets available
{
bullets[CurrentBullet].alive = true;
bullets[CurrentBullet].x = player.x + (player.width/2);
bullets[CurrentBullet].y = player.y;
}
}

}
[/source]

But It still does what it did and increases CurrentBullet a lot instead of by 1 upon each keypress. Editing my windows code to work with my main code sounds like a massive hassle as I would have to rewrite ALOT of my code... Sorry to bother man, you've been a lot of help!
0

Share this post


Link to post
Share on other sites
Sorry as an addendum to my last post (as I can't edit!?)
After the second last bracket, I had:
[source lang="cpp"]}
}
else
keySpaceIsHeld = false;
}[/source]
0

Share this post


Link to post
Share on other sites
Nevermind, got it working with the following:

I set a long variable to 0 that would hold the last time the player shot and then I did the following

[source lang="cpp"] if ((int)timeGetTime() < lastShot + 100) return;
else
{
//shoot bullet
}[/source]
Thanks everyone, for all your help!
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0