Simple Rocket or Bullet Code?

BlitzMax Forums/BlitzMax Beginners Area/Simple Rocket or Bullet Code?

I've been looking all over the code archives, but I can't find anything like what I'm looking for. I'm trying to grasp how to make multiple objects spawn and have the same rules.

Does anyone have some really simple, working, code that does something like fire multiple rockets or bullets that blow up at a certain time? Anything that has to do with creating more than one object, and having the same rules for each created object.

Scouse was kind enough to give me something near to what I want, but it included some hard function (that I don't know yet) and doesn't run.

I'm not going to use the code for one of my games. I need it for learning purposes.

If anyone can help with this, thanks!

Go through this tutorial Learning 2D Game Programming With BlitzMax. Specifically look at Part 5:Adding Missiles

Strict

Graphics 640,480,0,60

Type TBullet
	Global BulletList:TList
	Field X:Float
	Field Y:Float
	Field Life:Int
	Field XOffset:Float
	Field YOffset:Float
	
	Method Update()
		X:+ XOffset
		Y:+ YOffset
		
		If (X < -16) Or (X > GraphicsWidth()+16) Then
			XOffset = -XOffset
		EndIf
		
		If (Y < -16) Or (Y > GraphicsHeight()+16) Then
			YOffset = -YOffset
		EndIf
		
		If (Xoffset<1 And XOffset>-1) And (YOffset<1 And YOffset>-1) Then
			free(Self)
		EndIf
		
		If life<= 0 Then free(Self)
		life = life - 1
	End Method
	
	Method Draw()
		SetColor 0,0,255
		DrawOval(x-4,y-4,8,8)
	End Method
	
	Function Handle()
		If BulletList <> Null Then
			For Local bullet:TBullet = EachIn BulletList
				bullet.Update()
				bullet.Draw()								
			Next
			SetColor 255,255,255
			DrawText(CountList(BulletList), 10,10)
		EndIf
	End Function
	
	Function Free(bullet:TBullet)
		BulletList.Remove(bullet)
		bullet = Null
	End Function
	
	Function Create:TBullet(X:Float,Y:Float,Xoffset:Float, YOffset:Float)
		If BulletList = Null Then BulletList = New TList
		Local tempBullet:TBullet = New TBullet
			tempBullet.X = X
			tempBullet.Y = Y
			tempBullet.XOffset = XOffset
			tempBullet.YOffset = YOffset
			tempBullet.Life=Rand(40,140)
			BulletList.AddLast(tempBullet)
		Return tempBullet
	End Function
End Type


Type TPlayer
	Field X:Float
	Field Y:Float
	
	Method Limit(val:Float Var, MinVal:Float, MaxVal:Float)
		If val < MinVal Then val = MinVal
		If val > MaxVal Then val = MaxVal
	End Method
	
	
	Method Fire()
		Local XOffset:Float
		Local YOffset:Float
		
		XOffset = (MouseX()-X)/2
		YOffset = (MouseY()-Y)/2
		Limit(Xoffset, -20,20)
		Limit(YOffset, -20,20)
					
		Local tempBullet:TBullet = TBullet.Create(X,Y,XOffset, YOffset)

	End Method
	
	
	Method Update()
	
		If KeyDown(KEY_W) Then ' up
			Y :- 5
		EndIf	
		
		If KeyDown(KEY_S) Then ' down
			Y :+ 5
		EndIf	
		
		If KeyDown(KEY_A) Then ' left
			X:-5
		EndIf	
		
		If KeyDown(KEY_D) Then ' right
			X:+5
		EndIf

		Limit(Y, 16, GraphicsHeight()-16)
		Limit(X, 16, GraphicsWidth()-16)
		
		
		
		If MouseDown(1) Then
			fire()
		EndIf
		'FlushKeys()'using flushkeys to simulate effect of auto-flush, remove to see difference
	End Method
	
	
	Method Draw()
		SetColor 255,0,0
		DrawRect(X-16, y-16, 32, 32)
	End Method


	Function Create:TPlayer(X:Float, Y:Float)
		Local tempPlayer:TPlayer = New TPlayer
			tempPlayer.X = X
			tempPlayer.Y = Y
		Return tempPlayer
	End Function

End Type

SeedRnd MilliSecs()

Global Player1:TPlayer = TPlayer.Create(320,240)

While Not KeyDown(KEY_ESCAPE)
Cls

	Player1.Update()
	Player1.Draw()
	TBullet.Handle()
Flip
Wend
End


Whoops, thanks assari.

Thanks also Perturbatio, but that's a little too complex for a Max begginner like me.

Hope you can use this, commented every line. Sorry about the comments looking a mess, it's bound to happen with this forum :)

'fire multiple rockets that blow up at a certain time
Graphics 800,600,0						'init gfx window

Global rocketlist:TList = CreateList()				'make a list for active rockets
Global gravity# = -0.07						'gravity
SeedRnd(MilliSecs())						'make a quick "random" seed
HideMouse

Repeat								'mainloop, runs until escape pressed
	If MouseHit(1) Then trocket.fire(5)			'fire 5 rockets on LMB click, change to mousedown for autofire
	DrawRect MouseX(),580,10,40
	For Local rocket:trocket = EachIn rocketlist	'run thru rocketlist
		rocket.drawandmove()				'draw a rocket
	Next							'move to next object in rocketlist
	GCCollect()							'collect garbage
	Flip ; Cls						'flip backbuffer and clear it
Until KeyHit(key_escape)

Type trocket										
	Field x#,y#						'position of the rocket
	Field xvel#=Rand(-2,2),yvel#=Rand(5,8)			'velocity of the rocket
	Field timetolive = 0, timetodie = 100			'a crude timer deciding when rocket dies
	Function fire(number)					'the "fire x number of rockets function"
		For Local i=1 To number				'simply creates x number of trockets and adds them to list
			Local newrocket:trocket = New trocket
			newrocket.x = MouseX()+5 ; newrocket.y = 580	'set coordinates to mouse
			rocketlist.addlast(newrocket)
		Next
	EndFunction
	Method drawandmove()				'move and draw a rocket
		x:+xvel ; y:-yvel					'add the veloceties
		yvel:+gravity								'add the gravity to the y velocity
		DrawOval x,y,1,1							'draw the rocket itself
		timetolive:+1								'add to the timetolive counter
		If timetolive >= timetodie Then die()		'counter check
	EndMethod
	Method die()									'death method
		DrawText "BOOM",x-20,y						' :)
		Local rocket:trocket = Self					
		rocketlist.remove(rocket)					'remove rocket from list
		rocket = Null								'die.
	EndMethod
EndType


Wow! Thanks so much, kronholm! Just what I was looking for :D

Only thing I don't understand is "Methods" and "Lists", but I should go somewhere else for that I suppose.

There's nothing to understand almost :)

A list is like a giant shopping bag where you can put all your rockets. Then you can sort through the list one rocket at a time.

When you run through a list, you assign in the for/each loop, the object to a local variable. In this case, rocket will always refer to the current rocket that's in the list.

And here's where a method comes in, because if you then say rocket.drawandmove(), inside the for/each loop of the list, on the current rocket object, it will run that method on that specific rocket. This means that within the method, you don't have to refer directly to a certain instance of the type (e.g. rocket number 523), but can instead just type x = 15. This is the same as rocket523.x = 15.

Does that make any sense?

IKG, suggests you go through the tutorials, the answers to your questions on lists (Part 4) and methods (Part 1) are all there :)

Thanks so much, guys. This really cleared up a lot of things for me :D

I'm sorry, quick question:

How does the current rocket in the list not get pushed down when the next one is created? In other words, how does a "Method" repeat the same rules to a single rocket and keep track of it, if a new one is created right after it? Do those functions in the main loop repeat the rules for the entire list?

I hope this made sense...

Well because the instances are usually stored in a list the list is looped through and all instances are updated.
Each object is responsabe for itself , values and all.

@kron : a good example of the power of bmax.

Thank you plotter, I was trying to demonstrate how easy it could be. I've added it to the misc codearchives.