Microsoft Small Basic
Program Listing:
Embed this in your website
<object id='sbapp' data='data:application/x-silverlight-2,' type='application/x-silverlight-2' width='640' height='480'> <param name='source' value='http://smallbasic.com/program/ClientBin/SBWeb.xap'/> <param name='onError' value='onSilverlightError' /> <param name='background' value='white' /> <param name='minRuntimeVersion' value='3.0.40624.0' /> <param name='autoUpgrade' value='true' /> <param name='initParams' value='programId=SPR072' /> </object>
' SBace-Invaders-25 (v2) - A space invader game in under 25 lines by Davey~Wavey, Nov.2009, for Small Basic Forum.
' ===================================================================================
'
' Alien has increasing speed as it descends to increase difficulty, but you also get more score the faster they are!
' Aliens have different personalities (!) and drop further depending on their agression (i.e. a random number)
' You are rated on your score and your hit accuracy. You have 3 lives. Use your mouse to move your rocket and left mousebutton to fire.
' When an alien gets through your defences, they kill you off, then immediately regroup for another assault.
'
' See below game code for notes. Good Luck, civilization is depending on you!!!!!
' initialise game array
gamearry
=
"1=-1;-1=1;moveables=7;lives=3;ammo=0;score=0;aspeed=2;mx1=0;my1=0;mxo1=-3;myo1=0;m1="
+
Shapes
.
AddEllipse
(
5
,
10
)
+
";mx2="
+
(
GraphicsWindow
.
MouseX
-
25
)
+
";my2="
+
(
GraphicsWindow
.
Height
-
50
)
+
";m2="
+
Shapes
.
AddImage
(
"http://www.tutorialized.com/upload/(2006.06.21-09:12:44)rocket50x50.jpg"
)
+
";mxo3=-25;myo3=-25;mx3="
+
(
(
GraphicsWindow
.
Width
/
2
)
-
160
)
+
";my3=20;md3=-1;m3="
+
shapes
.
AddImage
(
"http://www.adiumxtras.com/images/thumbs/space_invaders_1_17601_6150_thumb.png"
)
+
";mxo4=-25;myo4=-25;mx4="
+
(
(
GraphicsWindow
.
Width
/
2
)
-
80
)
+
";my4=20;md4=-1;m4="
+
shapes
.
AddImage
(
"http://www.adiumxtras.com/images/thumbs/space_invaders_1_17601_6150_thumb.png"
)
+
";mxo5=-25;myo5=-25;mx5="
+
(
GraphicsWindow
.
Width
/
2
)
+
";my5=20;md5=-1;m5="
+
shapes
.
AddImage
(
"http://www.adiumxtras.com/images/thumbs/space_invaders_1_17601_6150_thumb.png"
)
+
";mxo6=-25;myo6=-25;mx6="
+
(
(
GraphicsWindow
.
Width
/
2
)
+
80
)
+
";my6=20;md6=-1;m6="
+
shapes
.
AddImage
(
"http://www.adiumxtras.com/images/thumbs/space_invaders_1_17601_6150_thumb.png"
)
+
";mxo7=-25;myo7=-25;mx7="
+
(
(
GraphicsWindow
.
Width
/
2
)
+
160
)
+
";my7=20;md7=-1;m7="
+
shapes
.
AddImage
(
"http://www.adiumxtras.com/images/thumbs/space_invaders_1_17601_6150_thumb.png"
)
While
gamearry
[
"lives"
]
>
0
' update alien and bullet positions
gamearry
=
"1=-1;-1=1;moveables="
+
gamearry
[
"moveables"
]
+
";lives="
+
gamearry
[
"lives"
]
+
";ammo="
+
gamearry
[
"ammo"
]
+
";score="
+
gamearry
[
"score"
]
+
";aspeed="
+
gamearry
[
"aspeed"
]
+
";mx1="
+
gamearry
[
"mx1"
]
+
";my1="
+
(
gamearry
[
"my1"
]
-
gamearry
[
"aspeed"
]
)
+
";mxo1="
+
gamearry
[
"mxo1"
]
+
";myo1="
+
gamearry
[
"myo1"
]
+
";m1="
+
gamearry
[
"m1"
]
+
";mx2="
+
(
GraphicsWindow
.
MouseX
-
25
)
+
";my2="
+
(
GraphicsWindow
.
Height
-
50
)
+
";m2="
+
gamearry
[
"m2"
]
+
";mxo3="
+
gamearry
[
"mxo3"
]
+
";myo3="
+
gamearry
[
"myo3"
]
+
";mx3="
+
(
gamearry
[
"mx3"
]
+
(
gamearry
[
gamearry
[
"md3"
]
]
*
gamearry
[
"aspeed"
]
)
)
+
";my3="
+
gamearry
[
"my3"
]
+
";md3="
+
gamearry
[
"md3"
]
+
";m3="
+
gamearry
[
"m3"
]
+
";mxo4="
+
gamearry
[
"mxo4"
]
+
";myo4="
+
gamearry
[
"myo4"
]
+
";mx4="
+
(
gamearry
[
"mx4"
]
+
(
gamearry
[
gamearry
[
"md4"
]
]
*
gamearry
[
"aspeed"
]
)
)
+
";my4="
+
gamearry
[
"my4"
]
+
";md4="
+
gamearry
[
"md4"
]
+
";m4="
+
gamearry
[
"m4"
]
+
";mxo5="
+
gamearry
[
"mxo5"
]
+
";myo5="
+
gamearry
[
"myo5"
]
+
";mx5="
+
(
gamearry
[
"mx5"
]
+
(
gamearry
[
gamearry
[
"md5"
]
]
*
gamearry
[
"aspeed"
]
)
)
+
";my5="
+
gamearry
[
"my5"
]
+
";md5="
+
gamearry
[
"md5"
]
+
";m5="
+
gamearry
[
"m5"
]
+
";mxo6="
+
gamearry
[
"mxo6"
]
+
";myo6="
+
gamearry
[
"myo6"
]
+
";mx6="
+
(
gamearry
[
"mx6"
]
+
(
gamearry
[
gamearry
[
"md6"
]
]
*
gamearry
[
"aspeed"
]
)
)
+
";my6="
+
gamearry
[
"my6"
]
+
";md6="
+
gamearry
[
"md6"
]
+
";m6="
+
gamearry
[
"m6"
]
+
";mxo7="
+
gamearry
[
"mxo7"
]
+
";myo7="
+
gamearry
[
"myo7"
]
+
";mx7="
+
(
gamearry
[
"mx7"
]
+
(
gamearry
[
gamearry
[
"md7"
]
]
*
gamearry
[
"aspeed"
]
)
)
+
";my7="
+
gamearry
[
"my7"
]
+
";md7="
+
gamearry
[
"md7"
]
+
";m7="
+
gamearry
[
"m7"
]
' move the bullet (m1), gun (m2) and aliens (m3+)
For
m
=
1
To
gamearry
[
"moveables"
]
' put the shapes where they're supposed to be
Shapes
.
Move
(
gamearry
[
"m"
+
m
]
,
gamearry
[
"mx"
+
m
]
+
gamearry
[
"mxo"
+
m
]
,
gamearry
[
"my"
+
m
]
+
gamearry
[
"myo"
+
m
]
)
If
m
>
2
And
(
math
.
abs
(
math
.
Floor
(
gamearry
[
"mx1"
]
-
(
gamearry
[
"mx"
+
m
]
)
)
)
<
25
)
And
(
math
.
Abs
(
Math
.
Floor
(
gamearry
[
"my1"
]
-
gamearry
[
"my"
+
m
]
)
)
<
10
)
Then
' bullet has collided with alien - increase score and reset alien
gamearry
=
"1=-1;-1=1;moveables="
+
gamearry
[
"moveables"
]
+
";lives="
+
gamearry
[
"lives"
]
+
";ammo="
+
gamearry
[
"ammo"
]
+
";score="
+
(
gamearry
[
"score"
]
+
10
)
+
";aspeed="
+
gamearry
[
"aspeed"
]
+
";mx1="
+
gamearry
[
"mx1"
]
+
";my1=-200;mxo1="
+
gamearry
[
"mxo1"
]
+
";myo1="
+
gamearry
[
"myo1"
]
+
";m1="
+
gamearry
[
"m1"
]
+
";mx2="
+
(
GraphicsWindow
.
MouseX
-
25
)
+
";my2="
+
(
GraphicsWindow
.
Height
-
50
)
+
";m2="
+
gamearry
[
"m2"
]
+
";mxo3="
+
gamearry
[
"mxo3"
]
+
";myo3="
+
gamearry
[
"myo3"
]
+
";mx3="
+
gamearry
[
"mx3"
]
+
";my3="
+
(
gamearry
[
"my3"
]
-
(
(
(
gamearry
[
"my3"
]
+
80
)
*
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
+
10
,
3
+
10
)
*
2
)
+
1
)
)
)
)
)
+
";md3="
+
gamearry
[
"md3"
]
+
";m3="
+
gamearry
[
"m3"
]
+
";mxo4="
+
gamearry
[
"mxo4"
]
+
";myo4="
+
gamearry
[
"myo4"
]
+
";mx4="
+
gamearry
[
"mx4"
]
+
";my4="
+
(
gamearry
[
"my4"
]
-
(
(
gamearry
[
"my4"
]
+
80
)
*
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
4
)
*
2
)
+
1
)
)
)
)
+
";md4="
+
gamearry
[
"md4"
]
+
";m4="
+
gamearry
[
"m4"
]
+
";mxo5="
+
gamearry
[
"mxo5"
]
+
";myo5="
+
gamearry
[
"myo5"
]
+
";mx5="
+
gamearry
[
"mx5"
]
+
";my5="
+
(
gamearry
[
"my5"
]
-
(
(
gamearry
[
"my5"
]
+
80
)
*
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
5
)
*
2
)
+
1
)
)
)
)
+
";md5="
+
gamearry
[
"md5"
]
+
";m5="
+
gamearry
[
"m5"
]
+
";mxo6="
+
gamearry
[
"mxo6"
]
+
";myo6="
+
gamearry
[
"myo6"
]
+
";mx6="
+
gamearry
[
"mx6"
]
+
";my6="
+
(
gamearry
[
"my6"
]
-
(
(
gamearry
[
"my6"
]
+
80
)
*
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
6
)
*
2
)
+
1
)
)
)
)
+
";md6="
+
gamearry
[
"md6"
]
+
";m6="
+
gamearry
[
"m6"
]
+
";mxo7="
+
gamearry
[
"mxo7"
]
+
";myo7="
+
gamearry
[
"myo7"
]
+
";mx7="
+
gamearry
[
"mx7"
]
+
";my7="
+
(
gamearry
[
"my7"
]
-
(
(
gamearry
[
"my7"
]
+
80
)
*
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
7
)
*
2
)
+
1
)
)
)
)
+
";md7="
+
gamearry
[
"md7"
]
+
";m7="
+
gamearry
[
"m7"
]
ElseIf
m
>
2
AND
(
(
gamearry
[
"mx"
+
m
]
<
35
)
Or
(
gamearry
[
"mx"
+
m
]
>
GraphicsWindow
.
Width
-
55
)
)
Then
' alien has hit edge of screen, so bounce it and increase speed
gamearry
=
"1=-1;-1=1;moveables="
+
gamearry
[
"moveables"
]
+
";lives="
+
gamearry
[
"lives"
]
+
";ammo="
+
gamearry
[
"ammo"
]
+
";score="
+
gamearry
[
"score"
]
+
";aspeed="
+
(
gamearry
[
"aspeed"
]
+
0.01
)
+
";mx1="
+
gamearry
[
"mx1"
]
+
";my1="
+
gamearry
[
"my1"
]
+
";mxo1="
+
gamearry
[
"mxo1"
]
+
";myo1="
+
gamearry
[
"myo1"
]
+
";m1="
+
gamearry
[
"m1"
]
+
";mx2="
+
(
GraphicsWindow
.
MouseX
-
25
)
+
";my2="
+
(
GraphicsWindow
.
Height
-
50
)
+
";m2="
+
gamearry
[
"m2"
]
+
";mxo3="
+
gamearry
[
"mxo3"
]
+
";myo3="
+
gamearry
[
"myo3"
]
+
";mx3="
+
gamearry
[
"mx3"
]
+
";my3="
+
(
gamearry
[
"my3"
]
+
(
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
+
10
,
3
+
10
)
*
4
)
+
1
)
)
*
(
10
+
Math
.
GetRandomNumber
(
20
)
)
)
)
+
";md3="
+
gamearry
[
(
gamearry
[
"md3"
]
*
(
math
.
Max
(
-
1
,
0
-
(
Math
.
Remainder
(
m
+
10
,
3
+
10
)
*
4
)
+
1
)
)
)
]
+
";m3="
+
gamearry
[
"m3"
]
+
";mxo4="
+
gamearry
[
"mxo4"
]
+
";myo4="
+
gamearry
[
"myo4"
]
+
";mx4="
+
gamearry
[
"mx4"
]
+
";my4="
+
(
gamearry
[
"my4"
]
+
(
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
4
)
*
4
)
+
1
)
)
*
(
10
+
Math
.
GetRandomNumber
(
20
)
)
)
)
+
";md4="
+
gamearry
[
(
gamearry
[
"md4"
]
*
(
math
.
Max
(
-
1
,
0
-
(
Math
.
Remainder
(
m
,
4
)
*
4
)
+
1
)
)
)
]
+
";m4="
+
gamearry
[
"m4"
]
+
";mxo5="
+
gamearry
[
"mxo5"
]
+
";myo5="
+
gamearry
[
"myo5"
]
+
";mx5="
+
gamearry
[
"mx5"
]
+
";my5="
+
(
gamearry
[
"my5"
]
+
(
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
5
)
*
4
)
+
1
)
)
*
(
10
+
Math
.
GetRandomNumber
(
20
)
)
)
)
+
";md5="
+
gamearry
[
(
gamearry
[
"md5"
]
*
(
math
.
Max
(
-
1
,
0
-
(
Math
.
Remainder
(
m
,
5
)
*
4
)
+
1
)
)
)
]
+
";m5="
+
gamearry
[
"m5"
]
+
";mxo6="
+
gamearry
[
"mxo6"
]
+
";myo6="
+
gamearry
[
"myo6"
]
+
";mx6="
+
gamearry
[
"mx6"
]
+
";my6="
+
(
gamearry
[
"my6"
]
+
(
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
6
)
*
4
)
+
1
)
)
*
(
10
+
Math
.
GetRandomNumber
(
20
)
)
)
)
+
";md6="
+
gamearry
[
(
gamearry
[
"md6"
]
*
(
math
.
Max
(
-
1
,
0
-
(
Math
.
Remainder
(
m
,
6
)
*
4
)
+
1
)
)
)
]
+
";m6="
+
gamearry
[
"m6"
]
+
";mxo7="
+
gamearry
[
"mxo7"
]
+
";myo7="
+
gamearry
[
"myo7"
]
+
";mx7="
+
gamearry
[
"mx7"
]
+
";my7="
+
(
gamearry
[
"my7"
]
+
(
(
math
.
Max
(
0
,
0
-
(
Math
.
Remainder
(
m
,
7
)
*
4
)
+
1
)
)
*
(
10
+
Math
.
GetRandomNumber
(
20
)
)
)
)
+
";md7="
+
gamearry
[
(
gamearry
[
"md7"
]
*
(
math
.
Max
(
-
1
,
0
-
(
Math
.
Remainder
(
m
,
7
)
*
4
)
+
1
)
)
)
]
+
";m7="
+
gamearry
[
"m7"
]
ElseIf
(
gamearry
[
"my"
+
m
]
>=
GraphicsWindow
.
Height
-
15
)
Then
' alien has reached the bottom - decrease life and reset alien.
gamearry
=
"1=-1;-1=1;moveables="
+
gamearry
[
"moveables"
]
+
";lives="
+
(
gamearry
[
"lives"
]
-
1
)
+
";ammo="
+
gamearry
[
"ammo"
]
+
";score="
+
gamearry
[
"score"
]
+
";aspeed="
+
(
gamearry
[
"aspeed"
]
-
0.5
)
+
";mx1="
+
gamearry
[
"mx1"
]
+
";my1="
+
gamearry
[
"my1"
]
+
";mxo1="
+
gamearry
[
"mxo1"
]
+
";myo1="
+
gamearry
[
"myo1"
]
+
";m1="
+
gamearry
[
"m1"
]
+
";mx2="
+
(
GraphicsWindow
.
MouseX
-
25
)
+
";my2="
+
(
GraphicsWindow
.
Height
-
50
)
+
";m2="
+
gamearry
[
"m2"
]
+
";mxo3="
+
gamearry
[
"mxo3"
]
+
";myo3="
+
gamearry
[
"myo3"
]
+
";mx3="
+
(
(
GraphicsWindow
.
Width
/
2
)
-
160
)
+
";my3=20;md3="
+
gamearry
[
"md3"
]
+
";m3="
+
gamearry
[
"m3"
]
+
";mxo4="
+
gamearry
[
"mxo4"
]
+
";myo4="
+
gamearry
[
"myo4"
]
+
";mx4="
+
(
(
GraphicsWindow
.
Width
/
2
)
-
80
)
+
";my4=20;md4="
+
gamearry
[
"md4"
]
+
";m4="
+
gamearry
[
"m4"
]
+
";mxo5="
+
gamearry
[
"mxo5"
]
+
";myo5="
+
gamearry
[
"myo5"
]
+
";mx5="
+
(
GraphicsWindow
.
Width
/
2
)
+
";my5=20;md5="
+
gamearry
[
"md5"
]
+
";m5="
+
gamearry
[
"m5"
]
+
";mxo6="
+
gamearry
[
"mxo6"
]
+
";myo6="
+
gamearry
[
"myo6"
]
+
";mx6="
+
(
(
GraphicsWindow
.
Width
/
2
)
+
80
)
+
";my6=20;md6="
+
gamearry
[
"md6"
]
+
";m6="
+
gamearry
[
"m6"
]
+
";mxo7="
+
gamearry
[
"mxo7"
]
+
";myo7="
+
gamearry
[
"myo7"
]
+
";mx7="
+
(
(
GraphicsWindow
.
Width
/
2
)
+
160
)
+
";my7=20;md7="
+
gamearry
[
"md7"
]
+
";m7="
+
gamearry
[
"m7"
]
ElseIf
Mouse
.
IsLeftButtonDown
Then
' fire button pressed
gamearry
=
"1=-1;-1=1;moveables="
+
gamearry
[
"moveables"
]
+
";lives="
+
gamearry
[
"lives"
]
+
";ammo="
+
(
gamearry
[
"ammo"
]
+
1
)
+
";score="
+
gamearry
[
"score"
]
+
";aspeed="
+
gamearry
[
"aspeed"
]
+
";mx1="
+
(
GraphicsWindow
.
mousex
)
+
";my1="
+
(
GraphicsWindow
.
Height
-
45
)
+
";mxo1="
+
gamearry
[
"mxo1"
]
+
";myo1="
+
gamearry
[
"myo1"
]
+
";m1="
+
gamearry
[
"m1"
]
+
";mx2="
+
(
GraphicsWindow
.
MouseX
-
25
)
+
";my2="
+
(
GraphicsWindow
.
Height
-
50
)
+
";m2="
+
gamearry
[
"m2"
]
+
";mxo3="
+
gamearry
[
"mxo3"
]
+
";myo3="
+
gamearry
[
"myo3"
]
+
";mx3="
+
gamearry
[
"mx3"
]
+
";my3="
+
gamearry
[
"my3"
]
+
";md3="
+
gamearry
[
"md3"
]
+
";m3="
+
gamearry
[
"m3"
]
+
";mxo4="
+
gamearry
[
"mxo4"
]
+
";myo4="
+
gamearry
[
"myo4"
]
+
";mx4="
+
gamearry
[
"mx4"
]
+
";my4="
+
gamearry
[
"my4"
]
+
";md4="
+
gamearry
[
"md4"
]
+
";m4="
+
gamearry
[
"m4"
]
+
";mxo5="
+
gamearry
[
"mxo5"
]
+
";myo5="
+
gamearry
[
"myo5"
]
+
";mx5="
+
gamearry
[
"mx5"
]
+
";my5="
+
gamearry
[
"my5"
]
+
";md5="
+
gamearry
[
"md5"
]
+
";m5="
+
gamearry
[
"m5"
]
+
";mxo6="
+
gamearry
[
"mxo6"
]
+
";myo6="
+
gamearry
[
"myo6"
]
+
";mx6="
+
gamearry
[
"mx6"
]
+
";my6="
+
gamearry
[
"my6"
]
+
";md6="
+
gamearry
[
"md6"
]
+
";m6="
+
gamearry
[
"m6"
]
+
";mxo7="
+
gamearry
[
"mxo7"
]
+
";myo7="
+
gamearry
[
"myo7"
]
+
";mx7="
+
gamearry
[
"mx7"
]
+
";my7="
+
gamearry
[
"my7"
]
+
";md7="
+
gamearry
[
"md7"
]
+
";m7="
+
gamearry
[
"m7"
]
EndIf
EndFor
' show status in titlebar
GraphicsWindow
.
Title
=
"SBace-Invaders-25: SCORE="
+
gamearry
[
"score"
]
+
" LIVES="
+
gamearry
[
"lives"
]
EndWhile
' Game Over!
GraphicsWindow
.
ShowMessage
(
"Well Done, you scored: "
+
gamearry
[
"score"
]
+
" and your Skill = "
+
Math
.
Floor
(
(
gamearry
[
"score"
]
/
gamearry
[
"ammo"
]
)
*
100
)
+
"%"
,
"<<< G-A-M-E O-V-E-R >>> "
)
' =========================================================================================================
'
' NOTES: This looks more complex than it really is. Instead of defining any variables, I am using the array to handle everything.
' Unfortunately this means that every time I change a variable, I have to completely rebuild the array, hence the long 'gamearry' lines (yeah, they're LONG!)
' If you compare them though, you'll see that only one, or maybe two, values change each time.
' To cut down on lines, I'm also using the ElseIf's to handle the various checks, which means I only need one endif.
'
' moveables = number of sprites to be moved (processed) each mainloop cycle
' The strange '1=-1;-1=1' elements, along with 'md3,4,etc', allow me to simulate a logical 'NOT' type function when I need to bounce the alien. (i.e. md3=NOT md3)
' mxo, myo are the offsets for each object (to centre object over its x,y)
' md3,4,5,etc. are the direction of individual aliens (-1,+1)
'
' Note that the calculations for collisions with alien 1 (m3) are slightly different in the arrays, due to 3 dividing into 3 and 6 without remainders.
' If adding more aliens, the same issue will be found with alien 2 (m4) and new alien 6 (m8), etc.
'
' CALCULATION TO RESET ALIEN WHEN HIT BY BULLET = (gamearry["my3"]-(gamearry["my3"]*(math.Max(0,0-(Math.Remainder(m,3)*2)+1))))
' which 1) calculates the remainder of the alien number being checked divided by the loop number = No remainder for alien being processed!
' then 2) multiplies the remainder by 2. Alien being processed stays as zero (as zero remainder times 2 still = zero)!
' then 3) make value negative, then add one to the result. Alien being processed gets a value of 1, all others remain negative.
' then 4) gets the highest (max) value comparing zero and the above result. Negatives give us zero, while alien being processed gives us 1.
' then 5) multiply the y position of the alien by the above result. Gives us zero if this is not the alien being processed.
' then 6) subtract the result above from the alien y position. If this is the alien being processed, it gets returned to the top of the screen. Yay!
'
' (c) Dave~Wavey, 2009. Please use this code only to produce further examples for the Small Basic forum to help others learn.
Copyright (c) Microsoft Corporation. All rights reserved.