Microsoft Small Basic

Program Listing: TZT450
init()
While "true"
title()
start()
gameloop()
gameover()
EndWhile

' 初期設定
Sub init
GraphicsWindow.Width = 640
GraphicsWindow.Height = 480
' ウィンドウのサイズ変更を不可とする
GraphicsWindow.CanResize = "false"
' 実行中のプログラムのディレクトリを取得する
dir = Program.Directory + "\"
' 背景
Shapes.AddImage(dir+"p_bg.jpg")
' 隕石
enemy_img = ImageList.LoadImage(dir+"p_meteor.png")
For i=0 To 9
enemy[i] = Shapes.AddImage(enemy_img)
Shapes.HideShape(enemy[i])
EndFor
radius = 130/2 ' 隕石の半径
' 自機(プレイヤー)
pw = 41
ph = 51
player = Shapes.AddImage(dir+"p_player.png")
Shapes.HideShape(player)
' 爆発
exp = Shapes.AddImage(dir+"p_explosion.png")
Shapes.HideShape(exp) ' 隠す
Shapes.SetOpacity(exp,90) ' 半透明
' ゲームオーバー
gover = Shapes.AddImage(dir+"p_gameover.png")
Shapes.HideShape(gover)
Shapes.Move(gover,110,170)
' メッセージ
msg = Shapes.AddImage(dir+"p_msg.png")
Shapes.HideShape(msg)
Shapes.Move(msg,160,330)
' タイトル
title_p = Shapes.AddImage(dir+"p_title.png")
Shapes.HideShape(title_p)
Shapes.Move(title_p,60,130)

GraphicsWindow.MouseMove = OnMouseMove
EndSub

Sub title
state = "title"
Shapes.ShowShape(title_p)
mcnt = 0
While state = "title"
mcnt = mcnt +1
If mcnt > 60 Then
' メッセージを点滅させる
If Math.Remainder(mcnt,60) < 40 Then
Shapes.ShowShape(msg)
Else
Shapes.HideShape(msg)
EndIf
' クリックされたらタイトルから抜ける
If Mouse.IsLeftButtonDown = "true" Then
state = "start"
EndIf
EndIf
Program.Delay(1000/30)
EndWhile
Shapes.HideShape(title_p)
Shapes.HideShape(msg)
EndSub

' プレイ直前の準備
Sub start
score = 0
' 自機の初期配置
px = 300
py = 400
Shapes.Move(player,px,py)
' 隕石の初期配置
For i=0 To 9
eX[i] = Math.GetRandomNumber(640) -50
eY[i] = -Math.GetRandomNumber(1000) -200
Shapes.ShowShape(enemy[i])
Shapes.Move(enemy[i],eX[i],eY[i])
' 先に描画される隕石をゆっくり、徐々に速くする
eSpd[i] = 6 +(i/2)
' 先に描画される隕石を小さく、徐々に大きくする
scaleSet()
EndFor
Shapes.ShowShape(player)
state = "play"
EndSub

Sub scaleSet
' 隕石の大きさを score に合わせて大きくする
scale = (i+5+(score/3000))/12
Shapes.Zoom(enemy[i],scale,scale)
' 拡縮後の半径を算出
eSize[i] = radius*scale
EndSub

Sub gameloop
While state = "play"
' 自機の中心座標を算出
pcx = px + (pw/2)
pcy = py + (ph/2)
hit = 0 ' 0:はずれ 1:あたり

For i=0 To 9
' 隕石の移動
eY[i] = eY[i] + eSpd[i]
Shapes.Move(enemy[i],eX[i],eY[i])
' 隕石が画面の外へ出たら再配置
If GraphicsWindow.Height < eY[i] Then
eX[i] = Math.GetRandomNumber(640) -50
eY[i] = -Math.GetRandomNumber(300) -130
scaleSet()
EndIf
' 隕石の中心座標を算出
ecx = eX[i] + radius
ecy = eY[i] + radius
' 自機と隕石の距離を算出(結果は2乗のまま)
dis = (ecx - pcx)*(ecx - pcx)+(ecy - pcy)*(ecy - pcy)
If (hit = 0) and (dis < (eSize[i]*eSize[i])) Then
hit = 1
state = "gameover"
EndIf
EndFor
score = score +10
GraphicsWindow.Title = "SCORE:"+score

' 30 fps で動かす
Program.Delay(1000/30)
EndWhile
EndSub

Sub OnMouseMove
If state <> "play" Then
Goto endOnMouse
EndIf
px = GraphicsWindow.MouseX
'py = GraphicsWindow.MouseY
' 自機が右端に隠れないようにする
If (GraphicsWindow.Width -pw) < px Then
px = GraphicsWindow.Width -pw
EndIf
Shapes.Move(player,px,py)
endOnMouse:
EndSub

Sub gameover
Shapes.ShowShape(exp)
zcnt = 0 ' 拡縮用
zoom = 0.2
mcnt = 0 ' メッセージ用
While state = "gameover"
' 爆発の拡縮と表示位置を決める
Shapes.Zoom(exp,zoom,zoom)
If zcnt = 0 Then
rx = px + Math.GetRandomNumber(30) -45
ry = py + Math.GetRandomNumber(30) -20
Shapes.Move(exp,rx,ry)
EndIf
zcnt = zcnt +1
If zcnt > 7 Then
zcnt = 0
EndIf
zoom = 0.2 + (zcnt/10)
mcnt = mcnt +1
If mcnt = 60 Then
Shapes.ShowShape(gover)
EndIf
If mcnt > 120 Then
' メッセージを点滅させる
If Math.Remainder(mcnt,60) < 40 Then
Shapes.ShowShape(msg)
Else
Shapes.HideShape(msg)
EndIf
' クリックされたら gameover から抜ける
If Mouse.IsLeftButtonDown = "true" Then
state = "title"
EndIf
EndIf

' 30 fps で動かす
Program.Delay(1000/30)
EndWhile
' 表示したメッセージと爆発を隠す
Shapes.HideShape(gover)
Shapes.HideShape(msg)
Shapes.HideShape(exp)
Shapes.HideShape(player)
EndSub