A roulette wheel

BlitzMax Forums/BlitzMax Programming/A roulette wheel

siread(Posted 2007) [#1]
Hello everyone. I'm creating a roulette game and I'm trying to find the best way of simulating a ball being launched into, riding around the outer rim for a while before drifting in and bouncing off the pocket seperators (frets) and finally settling in a pocket.

Displaying the wheel and spinning it is fairly easy. It's the ball physics that seem difficult. I'm not interested in a perfect simulation. For instance, rather having the ball bounce off of each fret realistically I'm happy to say,

"If wheel speed > 10 then deflect ball at random angle"

I guess it's similar to an object getting sucked into a vortex or black hole, then being repelled as it gets too deep. Any pointers would be welcome. Thanks.


ImaginaryHuman(Posted 2007) [#2]
Looks like you need to use physics.


Czar Flavius(Posted 2007) [#3]
You could try working out which pocket the ball lands in before hand (just a simple random number?) and then having a "fake" simulation just for appearance's sake? (Like gambling machines probably already know which fruit is going to come up before the wheels even start spinning?) Or is the intention of the program to actually simulate the physics? If it's a game I would just use my idea. The player doesn't need to know ;)


siread(Posted 2007) [#4]
Well, I managed to fake it well enough for my needs. Here's the code for anyone that's interested. It needs some proper timing code, or you can try flip 0 if it runs too slowly. The pockets souldn't be sequencial either but you could set up an array so Pocket[1] = 32, Pocket[2] = 15 and so on, then just use Pocket[ball.fPocket] to find the actual result. :)

SuperStrict

Graphics 800, 600
SeedRnd MilliSecs()

Const CNOOF_POCKETS:Float = 37		' EU wheel has 37 pockets/US has 38 
Const CPOCKET_ANGLE:Float = 9.729	' 360/37

Global wheel:TRouletteWheel = New TRouletteWheel
Global ball:TRouletteBall = New TRouletteBall
wheel.Reset()
ball.Reset(wheel)

Repeat
	If KeyHit(KEY_ESCAPE) Then End
	
	If KeyHit(KEY_SPACE) 
		wheel.Reset()
		ball.Reset(wheel)
	End If
	
	wheel.Update()
	wheel.Draw()
	ball.Update(wheel)
	ball.Draw(wheel)
	
	' Display variables
	DrawText("Wheel Speed:"+wheel.fSpeed,10,10)
	DrawText("Ball ZVel:"+ball.fVel,10,30)
	
	DrawText("Wheel Rotation:"+wheel.fRot,10,70)
	DrawText(" Ball Rotation:"+ball.fLineRot,10,90)
	
	DrawText("Ball Pocket:"+String(Int(ball.fPocket)),10,130)
	
	DrawText("Controls: SpaceBar To Spin",10,550)
	
	Flip
	Cls
Forever

Type TRouletteWheel
	' Inner and outer limits of the gulley
	Field iWheelSize:Int = 200
	Field iRimSize:Int = 300
	
	' Place the wheel in centre of screen
	Field fX:Float = 400
	Field fY:Float = 300
	
	' Rotation and speed of the wheel
	Field fRot:Float = 0
	Field fSpeed:Float
	
	Method Reset()
		' Start wheel spinning
		fSpeed = 1.5
	End Method
	
	Method Update()
		' Spin da wheel
		fRot:+fSpeed
		
		If fSpeed <= 0 
			fSpeed = 0
		Else
			fSpeed :- 0.001
		End If
		
		' Bounds check
		If fRot > 360 Then fRot = 1
	End Method
	
	Method Draw()
		' Draw outer rim
		SetColor 100,0,0
		DrawOval fX-(iRimSize/2), fY-(iRimSize/2), iRimSize, iRimSize
		
		' Draw wheel
		SetColor 255,0,0
		DrawOval fX-((iWheelSize*0.9)/2), fY-((iWheelSize*0.9)/2), iWheelSize*0.9, iWheelSize*0.9
		
		' Draw pockets
		SetColor 255,255,255
		Local count:Int = 0
		
		For Local pocket:Float = 1 To 360 Step CPOCKET_ANGLE
			' Draw pocket segments
			SetRotation pocket+fRot
			DrawLine fX,fY,fX+iWheelSize/2,fY
		
			' Draw numbers
			Local numX:Float = wheel.fX + Cos(pocket+fRot) * iWheelSize/2
			Local numY:Float = wheel.fY + Sin(pocket+fRot) * iWheelSize/2
			DrawText(count, numX, numY)
			count:+1
		Next
	End Method
End Type

Type TRouletteBall
	' Gravity needed to make ball descend
	' at a reasonable speed
	Global fGrav:Float = 0.025
	
	' Ball size
	Global iSize:Int = 10
	
	' The ball position is actually calculated using 
	' a line that extends from the center of wheel. 
	' An oval is simply drawn at the end of the line.
	
	' Angle of line
	Field fLineRot:Float
	
	' Ball speed
	Field fSpeed:Float
	
	' Distance from the center of the wheel
	Field fDist:Float
	
	' Velocity that ball descends towards wheel
	Field fVel:Float
	
	' Balls actual position
	Field fX:Float
	Field fY:Float
	
	' Pocket where ball sits
	Field fPocket:Float = 0
	
	Method Reset(wheel:TRouletteWheel)
		' Start ball moving
		fSpeed = -1.5
		fDist = wheel.iRimSize/2
		fVel = -0.1
	End Method
	
	Method Update(wheel:TRouletteWheel)
		SetRotation 0		
		
		' Ball rolls around wheel (in opposition direction)
		fLineRot:+fSpeed
		If fLineRot > 360 Then fLineRot:-360
		If fLineRot < 1 Then fLineRot:+360
		
		' Calculate current pocket it is over
		fPocket = (fLineRot/CPOCKET_ANGLE) - (wheel.fRot/CPOCKET_ANGLE)
		If fPocket < 0 Then fPocket:+CNOOF_POCKETS
		
		' Drop ball into gulley after wheels slows down a bit
		If wheel.fSpeed < 1.3
			' Increase velocity of fall
			fVel:-fGrav
			
			' Adjust distance of ball from center (length of line)
			fDist:+fVel
		
			' If ball hits wheel
			If fDist <= wheel.iWheelSize/2
			
				' Reset ball to inner boundary
				fDist = wheel.iWheelSize/2
				
				' Reverse ball velocity to bounce it
				fVel = -(fVel*0.8)	
				
				' Set random deflection of ball
				' Ball is more likely to get hit in the direction
				' of the wheel so give it a positive bias
				fSpeed = Rnd(-0.1, 1.0)

			
				' If bouncing has decreased enough then stay in current pocket
				If fVel > -0.4 And fVel < 0.4
				
					' Move ball around at same speed as wheel
					fSpeed = wheel.fSpeed
					
					' Settle in center of pocket
					If fPocket > Float(Int(fPocket))+0.5
						fLineRot :-0.1
					Else
						fLineRot :+0.1
					EndIf
				EndIf
			EndIf
		EndIf
	
		' Calculate actual ball position
		fX = wheel.fX + Cos(fLineRot) * fDist
		fY = wheel.fY + Sin(fLineRot) * fDist
	End Method

	Method Draw(wheel:TRouletteWheel)
		' Draw ball 
		SetColor 255,255,255
		DrawOval(fX-(iSize/2), fY-(iSize/2), iSize, iSize)
		
		' Uncomment to see ball line
		'DrawLine(wheel.fX, wheel.fY, ballX, ballY)	
		
	End Method
End Type



Fry Crayola(Posted 2007) [#5]
Ah, once again my unholy gambling addiction shall thwart my once burgeoning career.


Czar Flavius(Posted 2007) [#6]
LOL

The ball landed then suddenly zoomed to the other side of the wheel.

Nice try, but perhaps more realistic faking? ;)


siread(Posted 2007) [#7]
Never seen that myself. Though I have updated it since posting.