Bullet direction
Blitz3D Forums/Blitz3D Programming/Bullet direction
| ||
I am making a 2d birds eye view cam shooting game. I already made the character, bullet, and reciticle, there is only one problem. How do i make the bullets shoot towards the reciticle? I have tried a number of things that havent seemed to work, so if someone could give me a little help that would really be great. :) The game is a 2d game also, so obviously no 3d commands will work. And the reciticle is attached to the mouse, so where that moves, the reciticle moves. Thank you everyone for your help! - Kevin |
| ||
Here ya go. Just plug in your own bullet and gun graphics. This is from a LONG time ago and it's got some unnecessary stuff in there but it'll work. :)Graphics 800,600,32,0 Global ShotList:TList = New TList SetBlend ALPHABLEND Local bow:TImage =LoadImage("gun.png") MidHandleImage(bow) Global arr:TImage = LoadImage("bullet.bmp") MidHandleImage arr While Not KeyHit(KEY_ESCAPE) Cls Local MX:Int = MouseX() Local MY:Int = MouseY() Local LMH:Int = MouseHit(1) Local LMD:Int = MouseDown(1) Local RMH:Int = MouseHit(2) Local RMD:Int = MouseDown(2) a:Int = MouseX() - 400 b:Int = 300 - MouseY() r:Float = ATan2(a,b) SetRotation r SetScale .5,.5 DrawImage bow,400,300 SetScale .75,1.5 If LMH TShot.Create(400,300,r,.25) Local s:TShot For s = EachIn ShotList s.Update() Next Flip 0 Wend End Type TShot Field img:TImage Field x:Float,y:Float,r:Float Field spd:Float Function Create:TShot(x:Float,y:Float,r:Float,spd:Float) Local s:TShot = New TShot s.img = arr MidHandleImage s.img s.x = x s.y = y s.r = r s.spd = spd ShotList.AddLast s End Function Method Update() SetRotation self.r self.x = self.x + (Sin(self.r) * self.spd) self.y = self.y - (Cos(self.r) * self.spd) DrawImage self.img,self.x,self.y If self.x < 0 kil = 1 If self.x >800 kil = 1 If self.y < 0 kil = 1 If self.y > 600 kil = 1 If kil = 1 ShotList.Remove(Self) End Method End Type |
| ||
Thanks alot man! :D Ill test this out, and post back if there seems to be any error. |
| ||
Np at all, if you do have a problem I can strip it down to the bare necessities if needed. Eh, I just realized I posted BMax code in the B3D forum. It should be somewhat easy to convert I think. |
| ||
ya thanks again. Havent had much time to try it out yet though. I got back from my soccer game at about 9:30(we tied), was tired, didnt do much coding and just went to sleep, and now am in my computer class. But when i get home ill try it. If i need help, ill just email you for the bare code. :) |
| ||
Well there seems to be one error. In the beginning of the loop. Where it says "Local MX:Int = MouseX()", it highlights " Int = MouseX()" and says Expecting 'Wend'. If you dont have a solution for this, then the bare code may work better. |
| ||
. |
| ||
The problem is, that that function is written with BMax. It is not compatible with Blitz3D. Basically, the idea is to use Atan2 to determine the angle between the ship and the aiming point: angle# = atan2((aim_y - ship_y), (aim_x - ship_x)) and then use Cos and Sin to move the bullet: bullet_x# = ship_x bullet_y# = ship_y Repeat bullet_x# = bullet_x# + Cos(angle#) bullet_y# = bullet_y# + Sin(angle#) Forever |
| ||
Yeah. You'll probably also want to multiply the cos/sin values by speed though, or they'll be mighty slow bullets. :) |
| ||
ok that really seems to help, but there seems to be one problem. I believe i did it right, but obviously i didnt, because everytime i try to test launch the game, the window opens, stays black, my mouse disapears, and then it times out. I dont know if any of you would have a solution for this, but if you do, i would really like to hear it. here is the code for the program if that helps at all. ;Freeroamer ;Created by Mintybreath Graphics 800,600,16,2 SetBuffer BackBuffer() ;Constants Const upkey = 200 ;move the player up Const downkey = 208 ;move the player down Const leftkey = 203 ;move the player left Const rightkey = 205;move the player right Const humanspeed = 3 ;the speed of the human Const bulletspeed = 2 ;Loaded Images Global playerimage=LoadImage("player smallest.png") Global aimimage=LoadImage("reciticle.png") Global bulletimage=LoadImage("bullet.png") Global backimage=LoadImage("Full Ground.png") AutoMidHandle bulletimage AutoMidHandle playerimage MaskImage playerimage,0,255,255 AutoMidHandle aimimage MaskImage aimimage,0,255,255 Type player Field x,y End Type Type bullet Field x,y End Type Type back Field x,y End Type Type aim Field x,y End Type Function initializelevel() player\y = 250 player\x = 250 End Function ;update the bullets Function updatebullet() ;for each bullet, move it up 5 pixels ;if it goes off screen delete it For bullet.bullet = Each bullet bullet\y = bullet\y - 5 ;if bullet moves offscreen, delete it, otherwise draw it onscreen If bullet\y<0 Delete bullet Else DrawImage bulletimage,bullet\x,bullet\y ;draw the image EndIf Next End Function ;Controls Function Controls() DrawImage (backimage,back\x,back\y) DrawImage (playerimage,player\x,player\y) DrawImage aimimage,aim\x,aim\y HidePointer ;point and shoot angle#=ATan2((aim\y - player\y), (aim\x - player\x)) Repeat bullet\x=bullet\x + Cos(angle#) bullet\y=bullet\y + Sin(angle#) Forever If KeyDown(rightkey) back\x = back\x - humanspeed playerimage=LoadImage("player Right.png") MaskImage playerimage,0,255,255 EndIf If KeyDown(leftkey) back\x = back\x + humanspeed playerimage=LoadImage("player left.png") MaskImage playerimage,0,255,255 EndIf If KeyDown(downkey) back\y = back\y - humanspeed playerimage=LoadImage("player down.png") MaskImage playerimage,0,255,255 EndIf If KeyDown(upkey) back\y = back\y + humanspeed playerimage=LoadImage("player smallest.png") MaskImage playerimage,0,255,255 EndIf End Function Global aim.aim = New aim Global back.back = New back Global player.player = New player Global bullet.bullet = New bullet initializelevel() ;________________________________________________________ ;______________________Main Loop_________________________ ;________________________________________________________ While Not KeyDown(1) Cls aim\y=MouseY() aim\x=MouseX() If MouseHit(1) Then bullet.bullet=New bullet bullet\x = player\x bullet\y = player\y EndIf ;Functions Controls() updatebullet() If KeyHit(30) EndIf Flip Wend End |
| ||
First of all, remove the Repeat..Forever commands around the bullet's movement. Then, change all the fields in the types to floats, by adding "#": Field x#, y#Then, the code for the bullet movement should go in place where it now says: bullet\y = bullet\y - 5 Finally, the angle# should be calculated for each bullet, when the "New bullet" is created. So the bullet type needs a new field, that is angle#, and that angle should be used when the bullet is moved. |
| ||
Thanks for all your help, that worked really good. One other thing if you dont mind and have the time. How do i make the bullets faster? i tried putting a 2 in front of cos and sin to multiply them by 2. That made the bullet faster, but it kept the bullet moving the the bottom right corner only. If you have any advice on this i would really like to hear it. And sorry about asking for so much help. I just cant see how to do it. :) -Kevin |
| ||
It should work as long as you multiply sin and cos by the same amount. Post the code as you have it so far. |
| ||
Here it is:;Freeroamer ;Created by Mintybreath Graphics 800,600,16,2 SetBuffer BackBuffer() ;Constants Const upkey = 200 ;move the player up Const downkey = 208 ;move the player down Const leftkey = 203 ;move the player left Const rightkey = 205;move the player right Const humanspeed = 3 ;the speed of the human Const bulletspeed = 2 ;Loaded Images Global playerimage=LoadImage("player smallest.png") Global aimimage=LoadImage("reciticle.png") Global bulletimage=LoadImage("bullet.png") Global back=LoadImage("Ground.png") AutoMidHandle bulletimage AutoMidHandle playerimage MaskImage playerimage,0,255,255 AutoMidHandle aimimage MaskImage aimimage,0,255,255 Type player Field x,y End Type Type bullet Field x#,y# Field angle# End Type Type aim Field x,y End Type Function initializelevel() player\y=300 player\x=300 End Function ;update the bullets Function updatebullet() ;for each bullet, move it up 5 pixels ;if it goes off screen delete it For bullet.bullet = Each bullet bullet\x# = bullet\x# + 2Cos(angle#) bullet\y# = bullet\y# + 2Sin(angle#) angle#= ATan2((aim\y - player\y), (aim\x - player\x)) ;if bullet moves offscreen, delete it, otherwise draw it onscreen If bullet\y#<0 Delete bullet Else DrawImage bulletimage,bullet\x#,bullet\y# ;draw the image EndIf Next End Function ;Controls Function Controls() camerax=player\x -(800/2) cameray=player\y -(600/2) DrawImage (playerimage,player\x,player\y) DrawImage aimimage,aim\x,aim\y HidePointer If KeyDown(rightkey) player\x = player\x + humanspeed playerimage=LoadImage("player Right.png") MaskImage playerimage,0,255,255 EndIf If KeyDown(leftkey) player\x = player\x - humanspeed playerimage=LoadImage("player left.png") MaskImage playerimage,0,255,255 EndIf If KeyDown(downkey) player\y = player\y + humanspeed playerimage=LoadImage("player down.png") MaskImage playerimage,0,255,255 EndIf If KeyDown(upkey) player\y = player\y - humanspeed playerimage=LoadImage("player smallest.png") MaskImage playerimage,0,255,255 EndIf End Function Global aim.aim = New aim Global player.player = New player initializelevel() ;________________________________________________________ ;______________________Main Loop_________________________ ;________________________________________________________ While Not KeyDown(1) Cls DrawImage back,0,0 aim\x=MouseX() aim\y=MouseY() If MouseHit(1) Then bullet.bullet=New bullet bullet\x# = player\x bullet\y# = player\y EndIf ;Functions Controls() updatebullet() If KeyHit(30) EndIf Flip Wend End |
| ||
bullet\x# = bullet\x# + 2Cos(angle#) bullet\y# = bullet\y# + 2Sin(angle#) What's that?! Does that even compile? it should be: bullet\x# = bullet\x# + (Cos(angle#) * 2) bullet\y# = bullet\y# + (Sin(angle#) * 2) |
| ||
ooohhh i see. ill try that. I guess i figured that it would see it as 2*cos, or basically 2cos. thanks alot :) EDIT: Ya that worked great. thanks everyone for all your help. Edit: I really feel wierd asking more help of all of you, but there is one minor problem i am still not sure about. When the bullets are shot out, they continue to follow the aimer, giving the user controll over the bullets while they are in flight, which i dont really like the idea of. If anyone has any idea how to fix that it would really help me. Once i get the weapons system down and camera system down, i know pretty much how to do the rest. Thanks alot everyone! -Kevin |
| ||
What I do to fix this is something like this: if mousehit(1) then bullets.bullet=new bullet bullets\destx=mousex() bullets\desty=mousey() endif for bullets.bullet=each bullet angle#=atan2((bullets\desty-player\y),(bullets\x-player\x)) bullets\x=bullets\x+(cos(angle#)*2) bullets\y=bullets\y+(sin(angle#)*2) next That might fix it. |
| ||
p.s. Loading and masking an image each time you press a key is slow. Load & mask them outwith the main loop and simply display the one you need. |
| ||
Ill try that code out. Thanks everyone! Edit: Worked great! thanks alot! |