Microsoft Small Basic

Program Listing: MDJ923
'Paddle game extended a bit with fireworks for winners

' set GraphicsWindow window size
gh=600
gw=800
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh

'Paddle width, length and ball size (diameter)
padsize = 12
padlength = 120
ballsize = 32
'Number of ball hits for a win
winscore = 5

' Restart game
Restart:

'Set main game window properties and paddles/ball
GraphicsWindow.Clear()
GraphicsWindow.PenColor = "Black"
GraphicsWindow.BackgroundColor = "lightblue"
GraphicsWindow.BrushColor = "darkblue"
paddle1 = Shapes.AddRectangle(padlength, padsize)
paddle2 = Shapes.AddRectangle(padlength, padsize)
paddle3 = Shapes.AddRectangle(padsize, padlength)
paddle4 = Shapes.AddRectangle(padsize, padlength)
GraphicsWindow.BrushColor = "red"
ball = Shapes.AddEllipse(ballsize,ballsize)

'Allow mouse event to redraw paddles
GraphicsWindow.MouseMove = OnMouseMove

'Initialise random ball position and velocity (deltaX,deltaY)
x = gw/4+Math.GetRandomNumber(gw/2)
y = gh/4+Math.GetRandomNumber(gh/2)
deltaX = (Math.GetRandomNumber(11)-6)/5
deltaY = (Math.GetRandomNumber(11)-6)/5
'We want a non-zero initial velocity in x and y directions to get it going
If (deltaX > -0.5 And deltaX < 0.5) then
deltaX = 0.5
endif
If (deltaY > -0.5 And deltaY < 0.5) then
deltaY = 0.5
endif
'Set some gravity and speedup with each bounce
gravity = math.GetRandomNumber(10)/1000
bounce = 1+math.GetRandomNumber(10)/100
'Initialise score and pause flag to not-paused (left mouse click)
score = 0
pause = 0

'Update ball loop
RunLoop:

'New ball position
x = x + deltaX
y = y + deltaY

'Assume mouse position is at paddle centres
padX = GraphicsWindow.MouseX-padlength/2
padY = GraphicsWindow.MouseY-padlength/2

'Top paddle
If (y <= padsize + ballsize/2 and x >= padX and x <= padX + padlength) Then
deltaY = -deltaY*bounce
y = padsize + ballsize/2 'Since y is not integer, make sure we start on paddle when bouncing away - prevents double hits
Sound.PlayClick()
score = score+1
EndIf
'Bottom paddle
If (y >= gh - padsize - ballsize/2 and x >= padX and x <= padX + padlength) Then
deltaY = -deltaY*bounce
y = gh - padsize - ballsize/2
Sound.PlayClick()
score = score+1
EndIf
'Left paddle
If (x <= padsize + ballsize/2 and y >= padY and y <= padY + padlength) Then
deltaX = -deltaX*bounce
x = padsize + ballsize/2
Sound.PlayClick()
score = score+1
EndIf
'Right paddle
If (x >= gw - padsize - ballsize/2 and y >= padY and y <= padY + padlength) Then
deltaX = -deltaX*bounce
x = gw - padsize - ballsize/2
Sound.PlayClick()
score = score+1
EndIf

'Crude pause toggle option on left mouse click - e.g. allows window repositioning - resizing causes all sorts of obvious problems
'Can be used as a cheat since the paddles move when paused
wait:
If (Mouse.IsLeftButtonDown) then
pause = 1-pause
Program.Delay(250)
endif
If (pause = 1) then
Goto wait
endif

'Redraw ball - since coords for drawing are top left, remove radius (ballsize/2) to keep centred on x,y
Shapes.Move(ball, x-ballsize/2, y-ballsize/2)

'Delay to suit game
Program.Delay(5)

'If inside window add gravity to y(downwards) velocity and do next ball position update
If (x > 0 And x < gw and y > 0 And y < gh) Then
deltaY = deltaY + gravity
Goto RunLoop
EndIf

'The ball has left the window - winscore or more hits is a win
If (score >= winscore) then
Goto Win
endif

'less than winscore hits is a loose - restart game
GraphicsWindow.ShowMessage("You Lose", "Paddle")
Goto Restart

'If we win then fireworks display, with a bell ring to start
Win:

Sound.PlayBellRingAndWait()

'Start fireworks display
start:

'Initialise graphics dispay, firework count and max number of fireworks
GraphicsWindow.Clear()
GraphicsWindow.BackgroundColor = "Black"
count = 0
maxcount = 10

'Set a random set of stars, the randon RGB are designed to be dimish 'off white'
For i = 1 To gh
x=math.GetRandomNumber(gw)
y=math.GetRandomNumber(gh)
size=math.GetRandomNumber(8)
R=100+math.GetRandomNumber(55)
G=100+math.GetRandomNumber(55)
B=100+math.GetRandomNumber(55)
GraphicsWindow.BrushColor=GraphicsWindow.GetColorFromRGB(R,G,B)
GraphicsWindow.FillEllipse(x,y,size,size)
EndFor

'loop for each firework
next:

'Update firework count
count = count+1

'Set a random start and end for rocket
startx=math.GetRandomNumber(gw)
starty=gh
endx=50+math.GetRandomNumber(gw-100)
endy=20+math.GetRandomNumber(gh/2)

'Use a random number to set the colour - these are designed to be bright near primary
'Red, Green, Blue, Cyan, Yellow, Magenta
rand = math.GetRandomNumber(6)
If (rand=1) Then
R=254
G=math.GetRandomNumber(100)
B=0
EndIf
If (rand=2) Then
G=254
B=math.GetRandomNumber(100)
R=0
EndIf
If (rand=3) Then
B=254
R=math.GetRandomNumber(100)
G=0
EndIf
If (rand=4) Then
R=254
G=254
B=math.GetRandomNumber(100)
EndIf
If (rand=5) Then
G=254
B=254
R=math.GetRandomNumber(100)
EndIf
If (rand=6) Then
B=254
R=254
G=math.GetRandomNumber(100)
EndIf

'Set our firework color and create a rocket (ball)
GraphicsWindow.PenColor = GraphicsWindow.GetColorFromRGB(R,G,B)
GraphicsWindow.BrushColor = GraphicsWindow.GetColorFromRGB(R,G,B)
ball = Shapes.AddEllipse(15,15)

'Draw the rocket trail from start to end
For i = 1 To 100
x=startx+i/100*(endx-startx)
y=starty+i/100*(endy-starty)
Program.Delay(5)
Shapes.Move(ball, x, y)
endfor
Shapes.Remove(ball)

'Draw the firework burst
'nlayer is the number of concentric layers
'nangle is the number of angular segments to the burst
nlayer = 50
nangle = 20
'Random gravity for burst
grav = Math.GetRandomNumber(5)/nlayer

'Draw with the firework colour(k=1), then overdraw in black (k=2) - this leaves a trace outline which may be an artifact, but looks ok
For k = 1 To 2
If (k = 2) then
'Overdraw in black - also do a bang
GraphicsWindow.PenColor = "Black"
GraphicsWindow.BrushColor = "Black"
'Add you own bang!
' Sound.PlayAndWait("C:\Users\Public\Documents\SmallBasic\bang_2.wav")
' Sound.Stop("C:\Users\Public\Documents\SmallBasic\bang_2.wav")
EndIf
'A little text to show score above firework
GraphicsWindow.DrawText(endx-50,endy-100,"Well Done! " + score + " Hits")
'Loop over concentric layers
For i = 1 To nlayer
'Add a delay and set the radius(dist) and size of the burst points
'These scalings are an attempt to make it OK with different nlayer - not guaranteed!
Program.Delay(500/nlayer)
dist = 200/nlayer*i
size = 1+0.2*nlayer/math.SquareRoot(i)
' Loop over angle segments
For j = 1 To nangle
'Calculate coordinates of burst point, including the gravity term
x=endx+dist*math.Cos(j/nangle*2*3.14)
y=endy+dist*math.Sin(j/nangle*2*3.14)+grav*i*i
'Draw burst point
GraphicsWindow.FillEllipse(x,y,size,size)
EndFor
'Fireworks fade a little more slowly
If (k = 2) Then
Program.Delay(10)
EndIf
EndFor
'Short delay between draw and black overdraw (erase)
Program.Delay(300)
EndFor

'Limit the maximum number of fireworks
If (count = score Or count = maxcount) Then
Goto end
EndIf

'Next firework
Goto next

end:

'Restart game
Goto Restart

'Position the paddles accoring to mouse position - remember keep mouse within game window!
Sub OnMouseMove
paddleX = GraphicsWindow.MouseX
Shapes.Move(paddle1, paddleX - padlength/2, 0)
Shapes.Move(paddle2, paddleX - padlength/2, gh - padsize)
paddleY = GraphicsWindow.MouseY
Shapes.Move(paddle3, 0, paddleY - padlength/2)
Shapes.Move(paddle4, gw - padsize, paddleY - padlength/2)
EndSub