Microsoft Small Basic

Program Listing:
Embed this in your website
'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
Copyright (c) Microsoft Corporation. All rights reserved.