How do I make Random Objects Appear at Random?

Blitz3D Forums/Blitz3D Programming/How do I make Random Objects Appear at Random?

En929(Posted 2012) [#1]
Last time I got help with making one object appear at Random. Now, I'm trying to figure out how to make it so that one of these three objects appear at Random in a continuous manner (like rain) and fall out the sky like rain too. Thanks again.


Graphics 1280, 800, 32 
SetBuffer BackBuffer() 
GameTimer=CreateTimer(20) 




Global RedBall = LoadImage ("RedBall.png")
Global OrangeBall = LoadImage ("OrangeBall.png")
Global GreenBall = LoadImage ("GreenBall.png")



Type Ball1
 
 Field x,y
 Field image 

End Type



Type Ball2
 
 Field x,y
 Field image 

End Type



Type Ball3
 
 Field x,y
 Field image 

End Type


B1.Ball1 = New Ball1
b1\x = 100
b1\y = 0
b1\image = RedBall

B2.Ball2 = New Ball2
b2\x = 150
b2\y = 0
b2\image = OrangeBall

B3.Ball3 = New Ball3
b3\x = 200
b3\y = 0
b3\image = GreenBall



While Not KeyDown(1)

Cls


DrawImage b1\image, b1\x, b1\y

DrawImage b2\image, b2\x, b2\y

DrawImage b3\image, b3\x, b3\y





Flip
Wend 





P.S. I tried posting this in the 2D forum but got no response.


RemiD(Posted 2012) [#2]
I would do it with one of these 2 methods :

1)Track the time and create a new object each X milliseconds.
See my example here :
http://blitzbasic.com/Community/posts.php?topic=97515#1133418

2)Create a new object when an event happens.
For example, when an entity reaches the middle of the screen, the entity drops one ball and then the entity leaves the screen.
You can use the X,Y coordinates to check when this event happens. Also you want to use a EntityState% variable in order to make it drop only one ball.
In this example, the EntityState% variable will be equal to 0 until the entity reaches the middle of the screen, then the EntityState% variable will be equal to 1 while the ball is created, then the EntityState% variable will be equal to 2 until the entity reaches the outside of the screen, then the EntityState% will be equal to 0 again and the cycle continue if you want it to.

Last edited 2012


Kryzon(Posted 2012) [#3]
I have a bit of time today.

Take a look (the following is -untested-):
Graphics 1280, 800, 32 
SetBuffer BackBuffer() 
SeedRnd Millisecs()


Type Balls
	Field X#,Y#
	Field class% ;0 -> red.  1 -> orange.  2 -> green.
	;Field yVel#
End Type


Global FPSTimer% = CreateTimer(30) 

Dim BallSprites%(2) ;Use an array to spare using IFs or a SELECT later on when drawing.
BallSprites(0) = LoadImage("RedBall.png")
BallSprites(1) = LoadImage("OrangeBall.png")
BallSprites(2) = LoadImage("GreenBall.png")

Const MIN_DELAY% = 100
Const MAX_DELAY% = 1500
Const BALL_Y_VEL# = 5.0
Global BallTimer% = Millisecs()
Global BallDelay% = GetRandDelay()


While Not KeyHit(1)
	WaitTimer(FPSTimer)
	Cls

	UpdateBalls()
	RenderBalls()

	Flip
Wend


Function GetRandDelay()
	Return Rand(MIN_DELAY, MAX_DELAY)
End Function

Function UpdateBalls()
	;A single FOR...NEXT loop that handles all kinds of ball, much better
	;than one for each.
	For B.Balls = Each Balls

		;If you wish so, each ball can have a random vertical speed
		;as it's suggested by the commented-out 'yVel' field.
		;Here I'm using the same falling\vertical speed for all balls.
		B\Y = B\Y + BALL_Y_VEL 

		If B\Y > GraphicsHeight() Then Delete B
	Next


	;Ball creation code, probably the bit you're curious about:

	;If the current time has passed the amount of (last sampled time + random delay)...
	If Millisecs() > (BallTimer + BallDelay)

		;...then create a new ball.
		B.Ball = New Ball
		B\class = Rand(0, 2) ;Assign a random class\color\kind.	
	
		;Assign a random horizontal position.
		;ImageWidth() is used here so the ball isn't accidentally
		;created exactly at the right side of the screen, where it would
		;remain unseen.
		B\X = Rand( 0, GraphicsWidth() - ImageWidth(BallSprites(0)) )
		
		;The assigned starting vertical position is constant for all 
		;balls: it's completely above the screen's top ('zero' minus 
		;the ball's height).
		B\Y = 0 - ImageHeight(BallSprites(0))

		;You can assign other properties here such as that random 
		;yVel for each ball, a horizontal speed to make them look
		;like they're under wind etc. 

		;VERY IMPORTANT! renew time values for the creation of other
		;balls. If this bit is accidentally skipped, the program will 
		;create infinite balls (because the condition to create them 
		;will always be true). Never leave it out.
		BallTimer = Millisecs() ;Sample the current time.
		BallDelay = GetRandDelay() ;Create a new random delay.
	EndIf
End Function

Function RenderBalls()
	For B.Balls = Each Balls
		;Look how the 'class' field is used to avoid a trio of 
                ;IFs or a SELECT block.

		DrawImage BallSprites(B\class), B\X, B\Y
	Next
End Function
Updated.

Last edited 2012


Polygon(Posted 2012) [#4]
I added a background!
And a random speed thingy (The thing you semicoloned out)

ps I wish I knew how to put coding in the black boxes, could you tell me?

EDIT: Not much of a change...

''''''''''''''''''''''''''''''''''''''''''''
Graphics 1280, 800, 0 ,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()


Type Balls
Field X#,Y#
Field class% ;0 -> red. 1 -> orange. 2 -> green.
Field Y_Vel
End Type


Global FPSTimer% = CreateTimer(30)

Dim BallSprites%(3) ;Use an array to spare using IFs or a SELECT later on when drawing.
BallSprites(0) = LoadImage("C:\Users\Caleb user\angbrd.png")
BallSprites(1) = LoadImage("C:\Users\Caleb user\angbrd2.png")
BallSprites(2) = LoadImage("C:\Users\Caleb user\pig.png")
BallSprites(3) = LoadImage("C:\Users\Caleb user\pop.png") ; If you can, Maybe add a pointer, and it pops the balls!
Background = LoadImage("C:\Users\Caleb user\Desktop\New folder\Blitz3D Demo\New folder\irrlicht-1.7.3\media\wall.bmp")

Const MIN_DELAY% = 100
Const MAX_DELAY% = 1500
Const BALL_Y_VEL# = 5.0
Global BallTimer% = MilliSecs()
Global BallDelay% = GetRandDelay()
Global ballscollected

While Not KeyHit(1)
WaitTimer(FPSTimer)
Cls

TileImage Background,backx,backy : backx=backx+1 : backy=Sin(backx)*backx ;produces a cool effect! Try Cos!

Text 0,0,ballscollected

UpdateBalls()
RenderBalls()

Flip
Wend


Function GetRandDelay()
Return Rand(MIN_DELAY, MAX_DELAY)
End Function

Function UpdateBalls()
;A single FOR...NEXT loop that handles all kinds of ball, much better
;than one for each.
For B.Balls = Each Balls

;If you wish so, each ball can have a random vertical speed
;as it's suggested by the commented-out 'yVel' field.
;Here I'm using the same falling\vertical speed for all balls.
B\Y = B\Y + B\Y_VEL

If B\Y > GraphicsHeight() Then Delete B
Next

;Ball creation code, probably the bit you're curious about:

;If the current time has passed the amount of (last sampled time + random delay)...
If MilliSecs() > (BallTimer + BallDelay)



;...then create a new ball.
B.Balls = New Balls
B\class = Rand(0, 2) ;Assign a random class\color\kind.

;Assign a random horizontal position.
;ImageWidth() is used here so the ball isn't accidentally
;created exactly at the right side of the screen, where it would
;remain unseen.
B\X = Rand( 0, GraphicsWidth() - ImageWidth(BallSprites(0)) )

;The assigned starting vertical position is constant for all
;balls: it's completely above the screen's top ('zero' minus
;the ball's height).
B\Y = 0 - ImageHeight(BallSprites(0))
B\Y_VEL=Rnd(3,16)
;You can assign other properties here such as that random
;yVel for each ball, a horizontal speed to make them look
;like they're under wind etc.

;VERY IMPORTANT! renew time values for the creation of other
;balls. If this bit is accidentally skipped, the program will
;create infinite balls (because the condition to create them
;will always be true). Never leave it out.
BallTimer = MilliSecs() ;Sample the current time.
BallDelay = GetRandDelay() ;Create a new random delay.
EndIf
End Function

Function RenderBalls()
For B.Balls = Each Balls
;Look how the 'class' field is used to avoid a trio of
;IFs or a SELECT block.

DrawImage BallSprites(B\class), B\X, B\Y
Next
End Function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Last edited 2012


Kryzon(Posted 2012) [#5]
Hi Polygon,
you can see the forum tags (special words used to format posts) at this page: http://blitzbasic.com/faq/faq_entry.php?id=2

Use [/code] for small programs (like the above).

If you have a lot of code, use [/codebox] instead - it's a fixed size box but has scroll-bars when the code size exceeds it, like a window to a bigger text area.
Better used for libraries and bigger programs.

Both keep "tab" spaces, so they're well suited for representing indentation (unlike the [quote] tags).


En929(Posted 2012) [#6]
Thanks for the codes Kryzon and Polygon. They worked. That was pretty cool how the background moved in different directions at various speeds and thanks for the advice Remcoder.

Last edited 2012