日経ソフトウェア7月号の「スポーツゲームを作って遊ぼう」の走り幅跳びのプログラムを実行してみます。
今回はジャンプした結果を記録するランキング用の関数が新たに追加されています。
- 配列rankingにはあらかじめ以下のように値が設定されています。
優勝するためには6mを超える必要があります。
ranking = [6, 5, 4, 3, 2, 1, 0]
# ランキング表示 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。
飛んでみました
オープニング画面
1回目 ジャンプ失敗
何度かやるとこつを少し覚えました。
ソースコードです。
# 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()