C++ DirectX9!! BULLET PROBLEMS! HAVE BEEN SOLVED!!!

Started by
4 comments, last by Steve8x 15 years, 10 months ago
Hello, I am creating a remake of the ol 'Astrosmash' game for intellevision ;) I've drawn the background, the ship, and started putting in the soundFX, hyperspace, then when it came to bullets is where I got stuck... I'd like to fix whats wrong with my bullets, though I can't seem to figure it out so I thought Id ask for some help! I create an array of D3DXVECTOR3's (to hold the bullet positions) with a size of 10 I will eventually make it only let you shoot 2 bullets,(since thats how the original was) but for a cheat mode or something I want it to be able to shoot more.. the problem is when I shoot bullets/lasers whatever you want to call em; As soon as one bullet leaves the screen all bullets disappear!! Heres my code, I'll explain what im doing currently... heres what I have at the top:

IDirect3D9* d3d = 0;
IDirect3DDevice9* d3dDevice = 0;
D3DPRESENT_PARAMETERS d3dpp; 

ID3DXSprite* pSprite; // my sprite rendering object
IDirect3DTexture9* pBGTex; // textures for background, ship, and bullet
IDirect3DTexture9* pShipTex;
IDirect3DTexture9* pBulletTex;

D3DXVECTOR3 LaserPos[10]; // array of LaserPositions(x, y, z)[but z is made null]
D3DXVECTOR3 ShipPos, BGPos; // Ship And Background coordinates
float MoveSpeed = 5.8f; // Ship Move Speed
int LID = 0;		// Laser ID
Ok now after I Initialize the window, Direct3D, and the textures, and sprite... Heres my render function which gets called every frame from WinMain

void Render()
{
	d3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
	d3dDevice->BeginScene();

	pSprite->Begin(D3DXSPRITE_ALPHABLEND); // transparency enabled
	pSprite->Draw(pBGTex, 0, 0, &BGPos, 0xFFFFFFFF); // draw BG
	pSprite->Draw(pShipTex, 0, 0, &ShipPos, 0xFFFFFFFF); // draw Ship
	
	if(LID > 0) // if at least 1 laser has been shot
	{
		for(int x = 0; x < LID; x++) // iterate through laser's coordinates
		{
			if(LaserPos[x].x != 0 && LaserPos[x].y != 0)
			{
                                //Draw laser if x+y != 0
				pSprite->Draw(pBulletTex, 0, 0, &LaserPos[x], 0xFFFFFFFF);
			}
			else if(LaserPos[x].x == 0 && LaserPos[x].y == 0)
			{
                              // not sure if I need something here
			}
		}
		
	}

	pSprite->End();
	d3dDevice->EndScene();
	d3dDevice->Present(0, 0, 0, 0);
}

LID (laser ID) gets increased upon pressing one of the shoot buttons In WinMain I create a thread called 'HotkeyHandler' Which handles most keypresses

void HotkeyHandler()
{
	int count = 0;

	for(;; Sleep(10))
	{
		if(paused == 0)
		{
			if(GetAsyncKeyState(VK_LEFT))
			{
				ShipPos.x -= MoveSpeed;
			}
			if(GetAsyncKeyState(VK_RIGHT))
			{
				ShipPos.x += MoveSpeed;
			}
			if(GetAsyncKeyState(VK_DOWN))
			{
				HyperSpace();//generates random x coord and goes
			}
		
			if(GetAsyncKeyState(VK_SPACE) || GetAsyncKeyState(VK_CONTROL) || GetAsyncKeyState(VK_UP))
			{
				if(LID < 10 && count == 0)
				{	
					LaserPos[LID] = D3DXVECTOR3((ShipPos.x + 25), (ShipPos.y - 5), 0.0f);
					LID++;
					
					count = 8;
					result = systemx->playSound(FMOD_CHANNEL_FREE, Shootsound, false, &channel);
				}		
			}

			// Wall Boundries
			if(ShipPos.x < -25.0f)
				ShipPos.x = -25.0f;

			if(ShipPos.x > 988.0f)
				ShipPos.x = 988.0f;

			if(count > 0)
				count--;
		}
	}
}
this line: LaserPos[LID] = D3DXVECTOR3((ShipPos.x + 25), (ShipPos.y - 5), 0.0f); places the start coordinates of the current laser into the array... LID++; tells the render loop to start drawing... count makes sure you have to wait a little before being able to fire again I have another created thread which moves all lasers up the screen, and also I think where it should remove a laser from the game once it goes off the top of the screen! void LaserThread() { for(;; Sleep(10)) { for(int c = 0; c < LID; c++) // ;) { // move lasers up the screen if(LaserPos[c].y > -57.0f) { LaserPos[c].y -= 10.0f; } else if(LaserPos[c].y < -57.0f) // laser is off the top { LaserPos[c].x = 0; // tried this but LaserPos[c].y = 0;// seems to not have any effect LID--; // draw 1 less laser } } } } So what is my problem? I have also commented that LID--; and made a hotkey to decrease it, and my results where that it was closer to what I want but, backwards pretty much the last bullet you shot once subtracting 1 from LID is the one that gets removed from play, instead I want the one offscreen to be removed from play, and the other ones NOT to be removed until they go offscreen! I know someone out there has done this before! thanks to anyone that makes a post! :) [Edited by - Steve8x on May 28, 2008 12:58:57 AM]
Advertisement
This sounds more like a game logic problem than a DirectX problem. If you log the calls to ID3DXSprite::Draw(), is it actually drawing any bullets?
I concur with Steve - does this actually have anything to do with the Direct3D technology? Sounds to me like you need to get friendly with your debugger and look at the intermediary states and actual flow of execution - I suspect your logic doesn't actually do what you think it does.

Unless you can confirm this is a D3D-related issue then I'll move this to 'Game Programming'.


Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Oh I'm sorry you misunderstand, I never wanted to mean its a problem with directx!!! I just signed up here so I'm new, I thought "Gamedev.net" is all game programming pretty much... I just clicked directx because I thought in here people are working with directx, so they'd be able to help.. I guess you can move it into game programming if thats where you think it should go... thanks

Its a problem with my coding for sure! There is a right way to do bullets with directx9 I'm just not seeing it... Im also thinking im going to have similar problems with the asteriods later

I also forgot to mention im using microsoft visual c++ 2008

I am pretty new to directx and making games just for fun...

Ok now I've really sat down and thought about my logic, and you're right jolly I have something wrong...

it works like this, after 1 bullet is shot, that bullet's starting xy coordinates are stored in the array in the first position [0] then LID gets 1 added to it, since LID is greater than 0 it now draws as many bullets as LID is equal (in this case the first bullet)

It works the same for the rest of the bullets, for bullet 2 for example, the starting xy is stored in the array at [1] then LID equals 2, so now the render loop draws two bullets at whatever coordinates they currently have in the array, the y coordinates for bullets are updated every 10 milliseconds, in the LaserThread they go up the screen...


OK so i thought that when a bullet goes off screen I can just decrease LID and that bullet wont be drawn anymore...

Well it does stop drawing a bullet, but not the right one! it stops drawing the LAST Bullet shot instead of the one that has went offscreen!

How can I fix this, so that bullets wont disappear until they go off screen?

Im thinking I need an offset of somekind but not sure where to implement it!

A picture of what it looks like currently:
http://i136.photobucket.com/albums/q183/djphisic/new/Astro.png

as soon as the first one leaves the screen, any other bullets shot after will disappear!
The simplest way to keep a nicely packed array is to move the last entry into the deleted slot, then decrease your count.

Imagine I have an array of A, B, C, D.

I want to delete index 1 (B), so I:
array[1] = array[3];
entryCount--;

Or to generalize:
array[idxToDelete] = array[entryCount-1];
entryCount--;

Leaving you with A, D, C.
Thank you very much "Namethatnobodyelsetook"!!!

Your method works great! I learned something new!

I no longer have any problems whatsoever with my bullets and they shoot fine and never disappear until they leave the top of the screen!!

Problem Solved!


BulletPos[c] = BulletPos[LID-1];


;)

some times all it takes is one line of code to make it all work right!

This topic is closed to new replies.

Advertisement