Microsoft Small Basic

Program Listing: KGC257
'parabolic shot
'jalpc december 2014
fps=50
'
GraphicsWindow.Show() ' USAR ANTES DE HIDE o no dibujara a veces
GraphicsWindow.Hide()
data_()
form_()
grid_()
cannon_()
text_()
target_()
updateText_()
updateLinXY_()
'
GraphicsWindow.KeyDown=OnKeyDown_
'
Timer.Tick=OnTick_
Timer.Interval=1000
'
moveCannon_()
GraphicsWindow.Show()
'
While ("True")
start = Clock.ElapsedMilliseconds' recoge hora entrada en loop
update_()
delay = 1000/fps - (Clock.ElapsedMilliseconds - start)' retraso
If (delay > 0) Then
Program.Delay(delay)
EndIf
EndWhile
'
Sub update_
'sucesos del juego
'--------------------
'
'tiempo agotado = perder 1 nivel
If flag_timeOff Then
GraphicsWindow.ShowMessage("Time elapsed: Level>1 = Level-1","Msg")
flag_Msg="False"
if level>1 Then
level=level-1
EndIf
Vi= VInit
angle=angleInit
updateText_()
erasePoint_()
moveTarget_()
moveCannon_()
updateLinXY_()
timePlay=lapTimePlay
flag_timeOff="False"
Goto EXIT_update
EndIf
'
'Cambio de nivel por puntos e inicio contador (no superar 999)
If numPoints=changeLevel And (totalPoints+numPoints)<999 Then
totalPoints=totalPoints+numPoints
level=level+1
numPoints=0
timePlay=lapTimePlay
updateText_()
Goto EXIT_update
EndIf
'
'colision con blanco o con el propio cañon
If flag_Collision Or flag_Disaster Then 'Si ha acertado en el blanco
boom_() 'animacion de explosion
numPoints=numPoints+1 'actualiza puntos juego
updateShot_() 'actualiza o inicia contador tiros y cambia blanco si procede
updateText_()
'
'desastre blanco en cañon (juego se reinicia)
If flag_Disaster Then
numShot=1
numPoints=0
totalPoints=0
timePlay=lapTimePlay
level=1
Vi= VInit
angle=angleInit
updateText_()
moveTarget_()
moveCannon_()
updateLinXY_()
EndIf
'
flag_Collision="False"
flag_Disaster="False"
Goto EXIT_update
EndIf
'
'Sucesos de teclado
If flagKey="Right" And angle<90 Then
angle=angle+1
moveCannon_()
updateText_()
updateLinXY_()
flagKey=""
Goto EXIT_update
EndIf
'
If flagKey="Left" And angle>0 Then
angle=angle-1
moveCannon_()
updateText_()
updateLinXY_()
flagKey=""
Goto EXIT_update
EndIf
'
If flagKey="Down" And Vi > ViMin Then
Vi=Vi-1
Shapes.SetOpacity(gunpowder,Vi)
updateText_()
updateLinXY_()
flagKey=""
Goto EXIT_update
EndIf
'
If flagKey="Up" And Vi < ViMax Then
Vi=Vi+1
Shapes.SetOpacity(gunpowder,Vi)
updateText_()
updateLinXY_()
flagKey=""
Goto EXIT_update
EndIf
'
If flagKey="Space" Then
Shapes.HideShape(gunpowder)'desaparece carga polvora
bang_() 'simula fuego boca cañon
shot_() 'disparo
Shapes.HideShape(ball) 'desaparece bala
ballInit_() 'bala a boca de cañon
Shapes.ShowShape(gunpowder)'aparece carga polvora
updateShot_() 'actualiza o inicia contador tiros y cambia blanco si procede
updateText_() 'actualiza textos
flagKey=""
Goto EXIT_update
EndIf
'
EXIT_update:
EndSub
'
Sub OnKeyDown_
flagKey=GraphicsWindow.LastKey
EndSub
'
Sub OnTick_
If flag_Msg="False" Then
timePlay=timePlay-1
Shapes.SetText(texTimePlay,Text.Append(Text.GetSubText("000",1,(3-Text.GetLength(timePlay+""))),timePlay))
If timePlay<=0 Then
timePlay=lapTimePlay
flag_timeOff="True"
flag_Msg="True"
EndIf
EndIf
EndSub
'
Sub form_
GraphicsWindow.Width = pgW-5
GraphicsWindow.Height = pgH-5
GraphicsWindow.Top=40
GraphicsWindow.Left=40
GraphicsWindow.CanResize="False"
GraphicsWindow.Title="parabolic shot (jalpc)"
EndSub
'
Sub grid_
For lin=1 to Array.GetItemCount(draw["lines"])
pm = draw["lines"][lin]
DrawGrid_()
EndFor
EndSub
'
Sub DrawGrid_
GraphicsWindow.PenColor=pm["penColor"]
GraphicsWindow.PenWidth= pm["penWidht"]
'dibuja lineas verticales y horizontales
For i = 1 To pm["stepMax"]
x1=pm["x"]+(pm["stepX"]*i)
y1=pm["y"]+(pm["stepY"]*i)
x2=x1+pm["xMax"]
y2=y1+pm["yMax"]
GraphicsWindow.DrawLine(x1,y1,x2,y2)
EndFor
EndSub
'
Sub cannon_
'Tubo de cañon
GraphicsWindow.BrushColor="Black"
GraphicsWindow.PenColor="Gray"
c_w[1]= longCanon
c_h[1] = 8
c_x[1] =ox-c_w[1]
c_y[1] =oy-c_h[1]/2
c_rx[1]=c_w[1]/2'separacion del centro de rotacion en x
c_ry[1]=0'separacion del centro de rotacion en y
cannon[1] = Shapes.AddRectangle(c_w[1],c_h[1])
Shapes.Move(cannon[1],c_x[1],c_y[1])
'
'dibujar cuerpo del cañon
GraphicsWindow.PenWidth=2
c_w[2]=20
c_h[2]=13
c_x[2]=ox-c_w[2]/2-longCanon
c_y[2]=oy-(c_h[2]/2)
c_rx[2]=longCanon 'separacion del centro de rotacion en x
c_ry[2]=0'separacion del centro de rotacion en y
cannon[2]=Shapes.AddRectangle(c_w[2],c_h[2])
Shapes.Move(cannon[2],c_x[2],c_y[2])
'
'carga de polvora cañon
GraphicsWindow.PenWidth=1
GraphicsWindow.PenColor="White"
GraphicsWindow.BrushColor="White"
c_w[3]=10
c_h[3]=4
c_x[3]=ox-c_w[3]/2-longCanon
c_y[3]=oy-(c_h[3]/2)
c_rx[3]=longCanon 'separacion del centro de rotacion en x
c_ry[3]=0'separacion del centro de rotacion en y
cannon[3]=Shapes.AddRectangle(c_w[3],c_h[3])
Shapes.SetOpacity(cannon[3],Vi)
Shapes.Move(cannon[3],c_x[3],c_y[3])
gunpowder=cannon[3]
'
'Rueda de cañon
GraphicsWindow.PenWidth=3
GraphicsWindow.PenColor="Black"
GraphicsWindow.BrushColor="Transparent"
c_w[4]=30
c_h[4]=30
c_x[4]=ox-c_w[4]/2-longCanon
c_y[4]=oy-(c_h[4]/2)
c_rx[4]=longCanon 'separacion del centro de rotacion en x
c_ry[4]=0'separacion del centro de rotacion en y
cannon[4]=Shapes.AddEllipse(c_w[4],c_h[4])
wheelCannon=cannon[4]
Shapes.Move(cannon[4],c_x[4],c_y[4])
'
'Base 1 movible del cañon
GraphicsWindow.BrushColor="Black"
GraphicsWindow.PenColor="Gray
GraphicsWindow.PenWidth=2
bc1_w=50
bc1_h=60
bc1_difx=-10
bc1_dify=20
bc1_x=Shapes.GetLeft(wheelCannon)+bc1_difx
bc1_y=Shapes.GetTop(wheelCannon)+bc1_dify
bc1=Shapes.AddRectangle(bc1_w,bc1_h)
Shapes.Move(bc1,bc1_x,bc1_y)
'
'Base 2 movible del cañon
GraphicsWindow.PenWidth=4
bc2_w=180
bc2_h=40
bc2_difx=-75
bc2_dify=40
bc2_x=Shapes.GetLeft(wheelCannon)+bc2_difx
bc2_y=oy+50
bc2=Shapes.AddEllipse(bc2_w,bc2_h)
Shapes.Move(bc2,bc2_x,bc2_y)
'
'bola de cañon
GraphicsWindow.BrushColor="Red"
GraphicsWindow.PenColor="Yellow"
GraphicsWindow.PenWidth=2
b_w=10
b_h=10
b_x=ox-b_w/2
b_y=oy-b_h/2
ball=Shapes.AddEllipse(b_w,b_h)
Shapes.HideShape(ball)
Shapes.Move(ball,b_x,b_y)
'
'linea de tiro X
GraphicsWindow.PenColor="DimGray"
GraphicsWindow.PenWidth=2
ltx_w=2
ltx_h=10
ltx=Shapes.AddRectangle(ltx_w,ltx_h)
'
'Marca si linea tiro X sobrepasa pantalla
GraphicsWindow.BrushColor="DimGray"
ltxMax=Shapes.AddText("...")
Shapes.HideShape(ltxMax)
Shapes.Move(ltxMax,pgW-15,oy)
'
'linea de tiro Y
GraphicsWindow.PenColor="DimGray"
GraphicsWindow.PenWidth=2
lty_w=10
lty_h=2
lty=Shapes.AddRectangle(lty_w,lty_h)
'
'Marca si linea tiro Y sobrepasa pantalla
GraphicsWindow.BrushColor="DimGray"
ltyMax=Shapes.AddText("...")
Shapes.HideShape(ltyMax)
Shapes.Move(ltyMax,ox+5,0)

EndSub
'
Sub text_
'texto angulo , velocidad inicial etc del cañon
GraphicsWindow.BrushColor="Black"
textAngle=Shapes.AddText("Ag: "+angle+"º")
Shapes.Move(textAngle,ox+10,oy+10)
textVi=Shapes.AddText("Vi: "+Vi)
Shapes.Move(textVi,ox-45,oy-30)
'
textYMax=Shapes.AddText("Ym: "+yMax)
Shapes.Move(textYMax,ox+100,oy+10)
textXMax=Shapes.AddText("Xm: "+xMax)
Shapes.Move(textXMax,ox+100,oy+30)
'
GraphicsWindow.BrushColor="DimGray"
GraphicsWindow.DrawBoundText(ox+200,oy+10,200,"- Change angle: Left/Right")
GraphicsWindow.DrawBoundText(ox+200,oy+30,200,"- Change Vi: Up/Down")
GraphicsWindow.DrawBoundText(ox+200,oy+50,200,"- Level > 2: Help Lines Hide ")
'
' GraphicsWindow.FontSize=10
GraphicsWindow.DrawBoundText(ox-45,10,50,"shot")
' GraphicsWindow.FontSize=20
texNumShot=Shapes.AddText(numShot)
Shapes.Move(texNumShot,ox-45,25)
'
'GraphicsWindow.FontSize=10
GraphicsWindow.DrawBoundText(ox-45,60,50,"Points")
'GraphicsWindow.FontSize=20
texNumPoints=Shapes.AddText("000")
Shapes.Move(texNumPoints,ox-45,70)
'
' GraphicsWindow.FontSize=10
GraphicsWindow.DrawBoundText(ox-45,110,50,"Level")
'GraphicsWindow.FontSize=20
texLevel=Shapes.AddText(level)
Shapes.Move(texLevel,ox-45,120)
'
'GraphicsWindow.FontSize=10
GraphicsWindow.DrawBoundText(ox-45,160,50,"Time")
'GraphicsWindow.FontSize=20
texTimePlay=Shapes.AddText("000")
Shapes.Move(texTimePlay,ox-45,170)
'
' GraphicsWindow.FontSize=10
GraphicsWindow.DrawBoundText(ox-45,210,50,"Total")
' GraphicsWindow.FontSize=20
texTotalPoints=Shapes.AddText("000")
Shapes.Move(texTotalPoints,ox-45,220)
EndSub
'
Sub target_
'explosion
GraphicsWindow.BrushColor="Yellow"
GraphicsWindow.PenColor="Red"
GraphicsWindow.PenWidth=4
bo_w=25
bo_h=25
bo_x=posTargetIniX
bo_y=posTargetIniY-bo_h
boom=Shapes.AddEllipse(bo_w,bo_h)
Shapes.HideShape(boom)
'
'blancos target
GraphicsWindow.BrushColor="Transparent"
GraphicsWindow.PenColor="Gray"
GraphicsWindow.PenWidth=4
t_w[1]=30
t_h[1]=30
t_x[1]=posTargetIniX
t_y[1]=posTargetIniY-t_h[1]
target[1]=Shapes.AddRectangle(t_w[1],t_h[1])
Shapes.Move(target[1],t_x[1],t_y[1])
'
t_w[2]=30
t_h[2]=30
t_x[2]=posTargetIniX
t_y[2]=posTargetIniY-t_h[2]
target[2]=Shapes.AddEllipse(t_w[2],t_h[2])
Shapes.HideShape(target[2])
'
t_w[3]=10
t_h[3]=60
t_x[3]=posTargetIniX
t_y[3]=posTargetIniY-t_h[3]
target[3]=Shapes.AddRectangle(t_w[3],t_h[3])
Shapes.HideShape(target[3])
'
t_w[4]=60
t_h[4]=10
t_x[4]=posTargetIniX
t_y[4]=posTargetIniY-t_h[4]
target[4]=Shapes.AddRectangle(t_w[4],t_h[4])
Shapes.HideShape(target[4])
'
t_w[5]=15
t_h[5]=15
t_x[5]=posTargetIniX
t_y[5]=posTargetIniY-t_h[5]
target[5]=Shapes.AddEllipse(t_w[5],t_h[5])
Shapes.HideShape(target[5])
EndSub
'
Sub moveCannon_
angleCannon=-angle
'mover todas las partes del cañon menos la base
For index=1 To Array.GetItemCount(cannon)
Shapes.Rotate(cannon[index],angleCannon)
rotateX=c_rx[index]
rotateY=c_ry[index]
rad = Math.GetRadians(angleCannon)
difX = rotateX*Math.Cos(rad) - rotateY*Math.Sin(rad)
difY = rotateX*Math.Sin(rad) + rotateY*Math.Cos(rad) '
x=c_x[index]+ rotateX-difX
y=c_y[index]+rotateY-difY '
Shapes.Move(cannon[index],x,y)
EndFor
'mover bases de cañon a la misma vez
bc1_x=Shapes.GetLeft(wheelCannon)+bc1_difx
bc1_y=Shapes.GetTop(wheelCannon)+bc1_dify
Shapes.Move(bc1,bc1_x,bc1_y)
bc2_x=Shapes.GetLeft(wheelCannon)+bc2_difx
Shapes.Move(bc2,bc2_x,bc2_y)
EndSub
'
Sub shot_
'color para traza de bala
GraphicsWindow.BrushColor="Gray"
GraphicsWindow.PenColor="Gray"
GraphicsWindow.PenWidth=1
'
alpha = Math.GetRadians(angle)
xpos = ox
ypos = oy
lap= 0.15
time=0
lapDraw=0
stepDraw=2
While xpos <= pgW And ypos <= oy
lapDraw=lapDraw+1
time=time+lap
X=Vi*time * Math.Cos(alpha)
Y=Vi*time * Math.Sin(alpha) - gravity/2 * time*time
xpos = ox+X
ypos = oy-Y
'
Shapes.Move(ball,xpos-b_w/2,ypos-b_h/2)
'
If Math.Remainder(lapDraw,stepDraw)=0 Then
itemPoint=Array.GetItemCount(point)+1
Shapes.HideShape(point[itemPoint])
point[itemPoint]=Shapes.AddEllipse(3,3)
Shapes.Move(point[itemPoint],xpos-1,ypos-1)
Shapes.ShowShape(point[itemPoint])
EndIf
'
collision_()
If flag_Collision Then
Goto EXIT_shot
EndIf
'
Program.Delay(20)
EndWhile
EXIT_shot:
if angle=90 Then
flag_Disaster="True"
EndIf
updateText_()
EndSub
'
Sub updateText_
alpha = Math.GetRadians(angle)
xMax=((Vi*Vi)/gravity)*(Math.Sin(alpha*2))
yMax=(Vi*Vi*Math.Sin(alpha)*Math.Sin(alpha))/(gravity*2)
Shapes.SetText(textXMax,"Xm: "+0.01*(Math.Round(100*xMax)))
Shapes.SetText(textYMax,"Ym: "+0.01*(Math.Round(100*yMax)))
Shapes.SetText(textAngle,"Ag: "+angle+"º")
Shapes.SetText(textVi,"Vi: "+Vi)
Shapes.SetText(texNumShot,numShot+"/3")
'
Shapes.SetText(texNumPoints,Text.Append(Text.GetSubText("000",1,(3-Text.GetLength(numPoints+""))),numPoints))
'
Shapes.SetText(texLevel,level)
Shapes.SetText(texTotalPoints,Text.Append(Text.GetSubText("000",1,(3-Text.GetLength(totalPoints+""))),totalPoints))
EndSub
'
Sub collision_
'posicion centro bola
posBallX=Shapes.GetLeft(ball)+b_w/2
posBallY=Shapes.GetTop(ball)+b_h/2
'posicion del blanco
posTargetX=Shapes.GetLeft(target[numTarget])
posTargetY=Shapes.GetTop(target[numTarget])
'comprobar colision
flag_Collision="False"
'colision con target activo
If posBallX>=posTargetX And posBallX<=(posTargetX+t_w[numTarget]) Then
If posBallY>=posTargetY And posBallY<=(posTargetY+t_h[numTarget]) Then
flag_Collision="True"
EndIf
EndIf
EndSub
'
Sub boom_
Shapes.Move(boom,posBallX-bo_w/2,posBallY-bo_h/2)
Shapes.ShowShape(boom)
Shapes.HideShape(target[numTarget])
For i=10 To 40
If flag_Disaster Then
Shapes.Zoom(boom,1/(i/40),1/(i/80))
Else
Shapes.Zoom(boom,1/(i/40),1/(i/15))
EndIf
Shapes.SetOpacity(boom,110-i)
Program.Delay(25)
EndFor
Shapes.Zoom(boom,1,1)
Shapes.HideShape(boom)
EndSub
'
Sub bang_
Shapes.ShowShape(ball)'se visualiza bala roja
For i=1 To 5
Shapes.Zoom(ball,1/(i/5),1/(i/5))
Program.Delay(25)
EndFor
Shapes.Zoom(ball,1,1)
EndSub
'
Sub moveTarget_
'Elegir modelos de target aleatoriamente
numTargetOld=numTarget
numTarget=Math.GetRandomNumber(Array.GetItemCount(target))
Shapes.HideShape(target[numTargetOld])
Shapes.ShowShape(target[numTarget])
'
'Mover aleatoriamente de forma horizontal
min=ox+50
max=pgW-50
interval=50
randX = min + (Math.GetRandomNumber(1+(max-min)/interval)-1)*interval
randY=oy
'
'mover aleatoriamnete de forma vertical
If level > 1 Then
min=50
max=oy
interval=50
randY = min + (Math.GetRandomNumber(1+(max-min)/interval)-1)*interval
EndIf
Shapes.Move(target[numTarget],randX,randY-t_h[numTarget])
Shapes.ShowShape(target[numTarget])
EndSub
'
Sub ballInit_
Shapes.Move(ball,ox-b_w/2,oy-b_h/2)
EndSub
'
Sub erasePoint_
For p=1 To Array.GetItemCount(point)
Shapes.Remove(point[p])
EndFor
EndSub
'
Sub updateShot_
numShot=numShot+1 'aumenta el num disparo
If numShot>numShotMax Or flag_Collision Or flag_Disaster Then
numShot=1 'repone a 1 contador
erasePoint_() 'borrar rastro de puntos de parabolas
moveTarget_() 'cambia blanco de posicion
EndIf
updateText_()
EndSub
'
Sub updateLinXY_
'actualizar posicion marcas de max altura y distancia
Shapes.Move(ltx,ox+xMax-ltx_w/2,oy-ltx_h/2)'marca xMax en eje X
Shapes.Move(lty,ox-lty_w/2,oy-yMax-lty_h/2)'marca yMax en eje y
If ox+xMax > pgW Then
Shapes.ShowShape(ltxMax)
Else
Shapes.HideShape(ltxMax)
EndIf
If oy-yMax <= 0 Then
Shapes.ShowShape(ltyMax)
Else
Shapes.HideShape(ltyMax)
EndIf
'Ocultar ayuda si nivel es mayor que 3
If level >= 3 Then
Shapes.HideShape(ltx)
Shapes.HideShape(lty)
Shapes.HideShape(ltxMax)
Shapes.HideShape(ltyMax)
Else
Shapes.ShowShape(ltx)
Shapes.ShowShape(lty)
EndIf
EndSub
'
Sub data_
pgW = 598 'ancho pantalla
pgH = 428 'alto pantalla
ox=50 'origen x coordenada
oy=350 'origen y coordenada
longCanon=36 'radio de giro = largo tubo cañon
angleInit=45 'angulo inicial de la bala
angle=angleInit 'angulo variable de la bala
angleCannon=-45 'angulo variable del cañon
VInit=70 'velocidad inicial bala
Vi=VInit 'velocidad variable de la bala
ViMax=100 'velocidad inicial maxima permitida
ViMin=40 'velocidad inicial minima permitida
gravity = 9.81 'fuerza gravitatopria
flag_Collision="False" ' badera de acierto en blanco
posTargetIniX=ox+450 'posicion X inicial del blanco
posTargetIniY=oy+0 'posicion Y inicial del blanco
numShot=1 'num disparo de 1 a 3
numShotMax=3 'num disparo maximo por tanda
numPoints=0 'puntos de la tanda
totalPoints=0 'total de puntos
changeLevel=5 'cambio de nivel cada 5 puntos
numTarget=1 'num blanco inicial
level=1 'num nivel inicial
lapTimePlay=60 'tiempo por tanda
timePlay=lapTimePlay ' tiempo transcurrido en tanda
flag_Help="True" 'ayuda de lineas que marcan xMax y yMax
flag_Msg="False"
'
'draws Grid
'cuadriculas
draw["lines"][1]="penColor=LightGray;penWidht=1;stepX=10;stepY=0;stepMax=428;x=0;xMax=0;y=0;yMax=428;"
draw["lines"][2]="penColor=LightGray;penWidht=1;stepX=0;stepY=10;stepMax=598;x=0;xMax=598;y=0;yMax=0;"
draw["lines"][3]="penColor=LightGray;penWidht=2;stepX=50;stepY=0;stepMax=428;x=0;xMax=0;y=0;yMax=428;"
draw["lines"][4]="penColor=LightGray;penWidht=2;stepX=0;stepY=50;stepMax=598;x=0;xMax=598;y=0;yMax=0;"
'
'ejes de cordenadas
draw["lines"][5]="penColor=Gray;penWidht=2;stepX=0;stepY=0;stepMax=1;x=50;xMax=0;y=0;yMax=350;"
draw["lines"][6]="penColor=Gray;penWidht=2;stepX=0;stepY=0;stepMax=1;x=50;xMax=550;y=350;yMax=0;"
EndSub