BlitzPlus Rotation Shooter (Help needed)

BlitzPlus Forums/BlitzPlus Beginners Area/BlitzPlus Rotation Shooter (Help needed)

CrazyTech13(Posted 2014) [#1]
I am pretty new to the language of Blitz. I am 13 years old, so I don't really understand trigonometry or anything higher.

What I need help with in my game is how to shoot lasers in the corresponding rotation position. as of right now, it just shoots up.


Graphics 1024, 768

Const keyA = 30
Const keyD = 32
Const keySpace = 57

Type ship
	Field x, y
	Field fireArm ; Weapons (not implemented yet)
	Field shield ; Shield (not implemented yet)
	Field alive ; Will be used when I add enemies
	Field rotation
End Type

; Fire Arms:
; ----------
; Laser = 1
; Shotgun = 2

Type fireArms ; The laser's properties
	Field x, y
	Field exist
End Type

shipP = LoadImage("Player Ship.bmp")
MaskImage shipP, 255, 255, 255

laserI = LoadImage("Player Laser.bmp")
MaskImage laserI, 255, 255, 255

PlayerShip.ship = New ship
PlayerShip\x = 512
PlayerShip\y = 384
PlayerShip\fireArm = 1
PlayerShip\rotation = 0

Const iNumRotations = 36

Dim imgShipFrames(iNumRotations)

MidHandle shipP

MidHandle laserI

For iLoop = 0 To iNumRotations - 1
	
	imgShipFrames(iLoop) = CopyImage(shipP)
	
	RotateImage imgShipFrames(iLoop), iLoop * 360/iNumRotations
	
Next

ClsColor 210, 140, 255

While Not KeyDown(1)
	
	Cls
	
	DrawImage imgShipFrames(PlayerShip\rotation), PlayerShip\x, PlayerShip\y
	
	If KeyDown(keyA)
		PlayerShip\rotation = PlayerShip\rotation - 1
	EndIf
	
	If KeyDown(keyD)
		PlayerShip\rotation = PlayerShip\rotation + 1
	EndIf
	
	If PlayerShip\rotation > iNumRotations - 1
		PlayerShip\rotation = 0
	EndIf
	
	If PlayerShip\rotation < 0
		PlayerShip\rotation = iNumRotations - 1
	EndIf
	
	If KeyDown(203) And PlayerShip\x > 41
		PlayerShip\x = PlayerShip\x - 5
	EndIf
	
	If KeyDown(205) And PlayerShip\x < 983
		PlayerShip\x = PlayerShip\x + 5
	EndIf
	
	If KeyDown(208) And PlayerShip\y < 738
		PlayerShip\y = PlayerShip\y + 5
	EndIf
	
	If KeyDown(200) And PlayerShip\y > 34
		PlayerShip\y = PlayerShip\y - 5
	EndIf
	
	If KeyDown(keySpace)
		
		If PlayerShip\fireArm = 1
			
			laser.fireArms = New fireArms
			laser\x = PlayerShip\x
			laser\y = PlayerShip\y - 50
			laser\exist = 1
			
		EndIf
		
	EndIf
	
	For laser.fireArms = Each fireArms
		
		DrawImage laserI, laser\x, laser\y
		
		laser\y = laser\y - 5 ; This is the area that may need the help of all you pros!
		
		If laser\y < 0
			laser\exist = 0
		EndIf
		
		If laser\exist = 0
			Delete laser
		EndIf
		
	Next
	
	Flip
	
Wend

End




Matty(Posted 2014) [#2]
Hello,

Yep - the bit you've marked in the comments "This is the area that may need help" is where you need to make an adjustment.

There are a number of ways of doing it.

One is using trigonometry with sin/cosine functions. They are not too difficult to understand and I'll go through that below. The other way is using vectors which are not as complicated as the name sounds.

Ultimately what you want is for the position of the laser to chance by a certain amount in the x direction and a certain amount in the y direction depending on the angle of firing.

Really basic explanation of trigonometric functions sin and cos -

sin(angle) takes the angle and returns a result equal to the length of the component in the y direction.

cos(angle) takes the angle and returns a result equal to the length of the component in the x direction.

The angle is measure counterclockwise starting at 0 degrees which is to the right of screen.

So - if the angle is zero, then cos(0) would be equal to 1.0
and if the angle is 90 degrees then cos(90) would be equal to 0.0

Sine is slightly different - at angle zero, sin(0) equals 0.0
and at angle 90 sin(90) equals 1.0.

Think of it as if you have a clock. Let's say an angle of zero is 3 o'clock. Then the length of the hour hand in the x direction would be at its longest at 3 o'clock. And at 12 o'clock and 6 o'clock the length of the hour hand in the x direction would be zero. Furthermore - at 9 o'clock teh length of the hour hand would be negative in the x direction, -1.0.


Now sine is similar except that at 3 o'clock it would be zero and at at 12 o'clock it would be 1.0.


Now with all that preliminary stuff out of the way....

to work out your laser position do this:

Laser\x = Laser\x + LaserSpeed# * Cos(angle);
Laser\y = Lasyer\y + LaserSpeed# * Sin(angle);






-----------------------------

Now the other way using vectors and avoiding sine and cosine is like this:

Take your target position for the bullet and your initial position for the bullet and get the difference:

dx# = targetx# - startx#;
dy# = targety# - startY#;


Then we need to work out the distance from target to start:

dist# = sqrt(dx * dx + dy * dy)
; a bit of pythagoras which you would have done by now I'd imagine.


then divide the dx, dy by the total distance to get what is called a unit vector (it simply means the direction)

if(dist>0) ;don't want a divide by zero error)
   udx# = dx / dist
   udy# = dy / dist
else
     udx#=0;
     udy#=0;
endif


Now - if we want to work out how to move our laser we do like this:

laser\x = laser\x + LaserSpeed#*udx
laser\y = laser\y + LaserSpeed#*udy



CrazyTech13(Posted 2014) [#3]
I'm really sorry Matt, but I still don't quite get cosine and sine, nor do I understand the vectors very well.

Until I do, may I ask that you provide a sample code for me, or modify my existing code? If you do modify my code, all I ask is the positioning of the lasers + I will give that credit to you :)

Thanks for trying atleast :)


Matty(Posted 2014) [#4]
I haven't tested it but this should work. Have a close look through it and see how you go...simply replace the parts I've got below....

Type fireArms ; The laser's properties
	;added rotation parameter
	Field rotation
	Field x, y
	Field exist
End Type




	If KeyDown(keySpace)
		
		If PlayerShip\fireArm = 1
			
			laser.fireArms = New fireArms
			laser\x = PlayerShip\x + 50.0 * Cos(PlayerShip\rotation * 360 / iNumRotations) 
			laser\y = PlayerShip\y - 50.0 * Sin(PlayerShip\rotation * 360 / iNumRotations) 
			laser\rotation = PlayerShip\rotation * 360 / iNumRotations
			laser\exist = 1
			
		EndIf
		
	EndIf
	
	For laser.fireArms = Each fireArms
		
		DrawImage laserI, laser\x, laser\y
		
		;laser\y = laser\y - 5 ; This is the area that may need the help of all you pros!
		laser\x = laser\x + 5.0 * Cos(laser\rotation)
		laser\y = laser\y - 5.0 * Sin(laser\rotation)		

		if(laser\x < 0 or laser\y < 0 or laser\x > 1024 or laser\y > 768)
			laser\exist = 0
		endif 

		
		If laser\exist = 0
			Delete laser
		EndIf
		
	Next



CrazyTech13(Posted 2014) [#5]
Well the modification of my code didn't work, and if you try it out yourself you'd see what I mean.

But I tried studying one of the games that came with the BlitzPlus package before I posted this, and I saw that they had put a negative in front of the Sin(PlayerShip\rotation * 360 / iNumRotations).

So I tried this, and the angle was almost correct, but it was 90 degrees off to the right. Now unless you want to check over the code again, (you don't need to), I could rotate my image in paint to make it work.

Once again, thanks :)


*(Posted 2014) [#6]
Why not deduct 90 from the angle?


CrazyTech13(Posted 2014) [#7]
Hah, I didn't think of that :3 Thanks!


mv333(Posted 2014) [#8]
Take a look at this :

360° shooter game example code (by WolRon)