デジタルこどもBASEのロゴ 特定非営利活動法人デジタルこどもBASE 📚 目次
第84回 Lv3 ⏱ 25〜35分

かんたんシューティングを作ろう

🎯 きょうのミッション

プレイヤーから弾を撃って敵を倒すシューティング。スペースキーで発射、矢印キーで移動。当たり判定で敵が消える。

🧠 できるようになること

  • 弾の発射と移動が実装できる
  • 敵への命中判定が書ける
  • シューティングゲームの基本形が完成する

🧰 用意するもの

  • パソコン
  • ブラウザ(Chrome / Edge / Safari)
  • インターネット接続
  • このページの「▶ このページで実行」ボタン(絵もゲームもそのまま動きます)
  • Trinket(予備の実行サイト:https://trinket.io/python)

🖼 できあがり

下のプレイヤーを左右に動かしながら、スペースキーで弾を発射。敵に当たると敵が消える。

📺 実行結果
(シューティングのプレイ画面)

🚀 やりかた

  1. プレイヤー(下)・敵(上)・弾(最初は隠す)を用意。
  2. 矢印キーでプレイヤー操作。
  3. スペースキーで弾を発射(プレイヤー位置から上に移動)。
  4. 弾と敵の距離をチェック。当たったら敵を上にリセット。

🐍 きょうのコード

Python main.py
import turtle
import random

screen = turtle.Screen()
screen.bgcolor("black")
screen.setup(600, 600)
screen.tracer(0)

player = turtle.Turtle()
player.shape("triangle")
player.color("cyan")
player.penup()
player.left(90)
player.goto(0, -200)

enemy = turtle.Turtle()
enemy.shape("circle")
enemy.color("red")
enemy.penup()
enemy.goto(random.randint(-200, 200), 200)

bullet = turtle.Turtle()
bullet.shape("square")
bullet.shapesize(0.5, 0.5)
bullet.color("yellow")
bullet.penup()
bullet.hideturtle()

bullet_state = "ready"

def go_left(): player.setx(max(-275, player.xcor() - 25))
def go_right(): player.setx(min(275, player.xcor() + 25))

def fire():
    global bullet_state
    if bullet_state == "ready":
        bullet.goto(player.xcor(), player.ycor() + 20)
        bullet.showturtle()
        bullet_state = "fire"

screen.onkey(go_left, "Left")
screen.onkey(go_right, "Right")
screen.onkey(fire, "space")
screen.listen()

def game_loop():
    global bullet_state
    enemy.sety(enemy.ycor() - 3)
    if enemy.ycor() < -250:
        enemy.goto(random.randint(-200, 200), 200)
    if bullet_state == "fire":
        bullet.sety(bullet.ycor() + 10)
        if bullet.ycor() > 280:
            bullet.hideturtle()
            bullet_state = "ready"
        if bullet.distance(enemy) < 25:
            bullet.hideturtle()
            bullet_state = "ready"
            enemy.goto(random.randint(-200, 200), 200)
            print("💥 命中!")
    screen.update()
    screen.ontimer(game_loop, 20)

game_loop()
▶ Trinketを開いて動かす

このページの「▶ このページで実行」でそのまま動きます。キー操作のゲームは、絵をクリックしてからキーを押してね。Trinketを使うときは、上のコードをコピーして貼り付けます。

💡 きょうのポイント

global 文で関数の中から外側の変数を変えられます。bullet_state で「弾を撃てる/撃てない」状態管理。これがゲームの状態管理の基本。

game_loop のたびに「敵を動かす→弾を動かす→命中を判定→画面を更新→次を予約」の順に処理します。順番を言葉にできると、不具合の場所を探しやすくなります。

🎮 チャレンジ

  • 撃った数をスコアにしよう
  • 敵を3体に増やそう
  • 弾を3発まで同時発射可能にしよう(リスト管理)

🔁 ふりかえり

  • global はなぜ必要?
  • 弾の状態管理はどう作る?
  • 次回はミニ作品。何を作りたい?

👨‍👩‍👧 おうちの人・先生へ

  • 準備:キャンバスをクリックしてから、左右キーとスペースキーを確認します。スペースキーは "space" と小文字で書きます。
  • つまずきポイント:global 概念は新しいため、「関数の外にある弾の状態を、関数の中から変える合図」と説明します。弾が出ないときは bullet_state の値と global の有無を確認します。
  • 声かけ例:「弾の速さ、敵の位置、当たり判定の広さを変えると遊びやすさが変わる」と伝え、完成後の調整につなげます。