「100m走」と「走り幅跳び」を作る (その3)

走り幅跳び

 

日経ソフトウェア7月号の「スポーツゲームを作って遊ぼう」の走り幅跳びのプログラムを実行してみます。

 

今回はジャンプした結果を記録するランキング用の関数が新たに追加されています。

  • 配列rankingにはあらかじめ以下のように値が設定されています。
    優勝するためには6mを超える必要があります。
ranking = [6, 5, 4, 3, 2, 1, 0] 

 

disprankのフローチャートソースコードです。

 

f:id:yo4-su:20201123075947p:plain

 

# ランキング表示
def disprank(myscore):
  medalcolor = ['GOLD', 'GRAY80', 'BROWN']
  for i in range(len(ranking)):
    tempcolor = 'GRAY'
    if myscore == ranking[i]: tempcolor = 'RED'
    if i < 3:
      screen.draw.filled_circle((200, i*60+75),
        25, medalcolor[i])
      screen.draw.circle((200, i*60+75),
        25, 'BLACK')

    tempstr = "RANK" + str(i+1) + \
      " : " + '{:6.3f}'.format(ranking[i])
    screen.draw.text(tempstr, left=250, 
      top=i*60+50, fontsize=64,
      color=tempcolor, owidth=2, ocolor='WHITE')

 

設定されている値の確認

  • ジャンプ時の角度はangleで-45 に指定されています。時計回りがプラスとなるからです。
  • 重力加速度は9.8ですが、Game上は0.025に設定されています。この値をもっと小さくするともっと遠くまで飛び、大きくすると短いジャンプになります。
  • playerの加速はplayer.speed+8 で加速しています。
  • playerの位置はplayerが加速するたびに1/8加算しています。
  • player.meterはplayer.length/70 で計算されています。値を変更することでメートルの値を変更できます。
  • rankingは初期設定で6m,5m,4m,3m 2m。

 

飛んでみました

オープニング画面

f:id:yo4-su:20201123082154p:plain

[opning画面]

 

1回目 ジャンプ失敗

f:id:yo4-su:20201123082251p:plain

[0m]

何度かやるとこつを少し覚えました。

f:id:yo4-su:20201123082338p:plain

[jump]

 

  


 ソースコードです。

# SPORT GAME (走り幅跳び)
import pgzrun
import math

WIDTH = 800   
HEIGHT = 600  

def init():
  global player, length, countdown
  global gameover, titlemode, bx, by, keyold
  player = Actor('player_stand',(150, 400))  
  player.anime = 0   
  player.speed = 0   # 助走時の速度
  player.dx = 0      # ジャンプの速度(X成分)
  player.dy = 0      # ジャンプの速度(Y成分)
  player.length = -400 # 踏み切り線までの距離
  player.meter = 0   # ジャンプした距離
  keyold = False     
  countdown = 3    
  bx = player.x    
  by = player.y    
  gameover = 0     
  titlemode = True 

# ランキング表示
def disprank(myscore):
  medalcolor = ['GOLD', 'GRAY80', 'BROWN']
  for i in range(len(ranking)):
    tempcolor = 'GRAY'
    if myscore == ranking[i]: tempcolor = 'RED'
    if i < 3:
      screen.draw.filled_circle((200, i*60+75),
        25, medalcolor[i])
      screen.draw.circle((200, i*60+75),
        25, 'BLACK')

    tempstr = "RANK" + str(i+1) + \
      " : " + '{:6.3f}'.format(ranking[i])
    screen.draw.text(tempstr, left=250, 
      top=i*60+50, fontsize=64,
      color=tempcolor, owidth=2, ocolor='WHITE')

def draw():
  message = ['G O !', 'READY...', 'READY','']
  if titlemode == True:
    screen.fill('RED')
    screen.draw.text('SPORT GAME(Long Jump)',
      left=150, top=250, fontsize=64,
      color='BLUE', owidth=2, ocolor='WHITE')
  else:
    screen.blit('background', (0, 0))
    screen.draw.filled_rect(Rect((0, 250),
      (WIDTH, 100)), 'DARKGREEN')
    screen.draw.filled_rect(Rect((0, 350),
      (WIDTH, 250)), 'ORANGE')
    screen.blit('track2', (bx, by))
    player.draw()
    if countdown >= 0:
      screen.draw.text(message[int(countdown)],
        left=300, top=50, fontsize=64,
        color='RED', owidth=2, ocolor='WHITE')
    screen.draw.text('Meter : ' + 
      '{:6.3f}'.format(player.meter),
      left=250, top=520, fontsize=64,
      color='BLUE', owidth=2, ocolor='WHITE')

    if gameover == 0:
      screen.draw.text(
        '[SPACE]:RUN   [CTRL]:JUMP', left=200,
        top=285, fontsize=40, color='WHITE')
    else:
      disprank(player.meter)  # ランキング表示

def update():
  global player, countdown, titlemode
  global gameover, keyold,bx, ranking

  if titlemode == True:
    if keyboard.space: titlemode = False
    return

  if countdown >= 0:  
    countdown = countdown - 0.01666
    return

  player.speed = player.speed - 1  
  if player.speed < 0: player.speed = 0
  bx = player.x - (400 + player.length)
  if gameover == 0:
    if player.dx == 0:   # 助走中
      keynew = keyboard.space
      if keynew != keyold:
        keyold = keynew
        player.anime = (player.anime + 1) % 4
        if player.anime == 0: 
          player.image = 'player_walk1'
        if player.anime == 2: 
          player.image = 'player_walk2'
        if keynew == True:
          player.speed = player.speed + 8
          if player.speed > 20: 
            player.speed = 20

      player.length = player.length + \
        (player.speed / 8)
      # コントロールキーでジャンプ
      if keyboard.rctrl == True or \
        keyboard.lctrl == True:  
        if player.length > 0:
          # 踏み切り線を越えたらファール
          gameover = 1   
        else: # ジャンプ
          angle = -45
          rad = math.radians(angle)
          player.dx = \
            math.cos(rad) * (player.speed / 5)
          player.dy = \
            math.sin(rad) * (player.speed / 5)
    else: # ジャンプ中
      player.length = player.length + player.dx
      player.meter = player.length / 70
      if player.meter < 0: player.meter = 0
      # 重力加速度は0.025にする
      player.dy = player.dy + 0.025
      player.y = player.y + player.dy
      if player.y > by:  # 着地したら終了
        gameover = 1
        # 飛距離を登録
        ranking.append(player.meter)   
        # 降順でソート
        ranking.sort(reverse = True) 
        # 最後の要素を削除  
        ranking.remove(ranking[7])   
  else:
    gameover += 1
    if gameover > 300: init()

# ランキングデータ
ranking = [6, 5, 4, 3, 2, 1, 0]  
init()

pgzrun.go()

 

 

 

/* -----codeの行番号----- */