初心者向けのPythonゲームプログラミング入門講座(第2回:まいっちんぐマチコ先生ゲームを作ろう)

プログラミング入門講座

どうも、こんにちは、だんなです。

2020年、プログラミング教育が小学校で必修化されることをきっかけに、本業システムエンジニアのだんなが息子に簡単なプログラミング(Python:パイソン)を教えているうちに、自分もだんだんスイッチが入ってしまい約30年ぶりにゲームを作ってみたくなりました

本業はゲーム屋さんではありませんので、ゲームが大好きな小学生の息子から「ここの動きがおかしい」とか「こうしないと面白くない」などの意見をもらいながら、プログラムを作っていく過程をブログ記事に残していきます。今から子供にプログラミングを教えたい、親子で一緒に学んでみたい方にもpythonのインストールから進められるお勧めの入門記事になると思います。

だんな
だんな

第2回のゲームはコチラ「まいっちんぐマチコ先生ゲーム」です。

だんなのゲームプログラミング講座(第2回:まいっちんぐマチコ先生ゲームを作ろう)

このゲームプログラミング入門講座では、pythonライブラリを使って開発ができる環境をパソコンにインストールして、プログラムを作って行きます。まだ環境が作れていない方は、先にこちらの記事をご覧下さい。
第1回:pythonライブラリを使える開発環境をパソコンにインストールしよう

誰に向けての記事なのか
  • 簡単なプログラミングを作ってみて、すごく楽しいと思った方
  • 配布されているライブラリを使って、アレコレ試してみたい方
記事の内容は何か
  • Python開発環境(Anaconda)を使ってプログラムを実行します。
  • pygameライブラリを使ってゲームを作る入門過程を記事にしていきます。
  • 疑問点があれば、コメントやtwitterに書いてくれればお答えします
記事を読むメリットは何か
  • 100万種類以上あるpythonの各種ライブラリを使える実行環境を構築。
  • pythonのプログラム言語で簡単なゲームを作る入門過程を覚えられます。

本業のシステムエンジニアの皆さんがプログラミングをする場合と同じように、少し面倒な準備が必要になりますが、このプログラミング入門講座では「すべて無料で」プログラム実行できます。

実行手順は以下の3点となります。

プログラム実行までの手順

(準備①) pythonの開発環境(Anaconda)のインストール
(準備②) ゲーム作成用ライブラリpygameのインストール

入門① Anaconda付属のプログラムエディタ(Spyder)を開く。
入門② Spyderでプログラムを書く。または、ダウンロードしたファイルを開く。
入門③ Spyderで実行ボタンを押す。

(準備①) pythonの開発環境(Anaconda)のインストール

インストールがまだ終わっていない方は、こちらの記事をご覧下さい。
第1回:pythonライブラリを使える開発環境をパソコンにインストールしよう

(準備②) ゲーム作成用ライブラリpygameのインストール

インストールがまだ終わっていない方は、こちらの記事をご覧下さい。
第1回:pythonライブラリを使える開発環境をパソコンにインストールしよう

入門① Anaconda付属のプログラムエディタ(Spyder)を開く。

プログラムを書いたり実行したりするAnaconda付属のプログラムエディタ(Spyder)を開きます。

プログラムエディタについては、いろんな種類の無料ツールがダウンロードできるようになっていますので、Spyderが合わない方や環境構築に自信のある方は探してみて下さい。ちなみに私は、仕事の開発では「eclipse」と「Visual Studio Code」をメインで使っています。

入門② Spyderでプログラムを書く。または、ダウンロードしたファイルを開く。

第2回は、私だんなが作成してアップロードしたファイルをダウンロードして実行してみましょう。アップロード先は、GitHub(ギットハブ)というサイトになります。
https://github.com/mat-tun-neo/machiko-sensei

GitHub(ギットハブ)は、ソフトウェア開発のプラットフォームであり、ソースコードをホスティングする。コードのバージョン管理システムにはGitを使用する。Ruby on RailsおよびErlangで記述されており、アメリカのカリフォルニア州サンフランシスコ市に拠点を置くGitHub社によって保守されている。

ウィキペディア(Wikipedia) https://ja.wikipedia.org/wiki/GitHub

GitHubのアップロード先から、以下の手順でzip圧縮ファイルをダウンロードして下さい。

ダウンロードが終わったら、自分の好みの場所に解凍して下さい。解凍したフォルダをSpyderで表示して、いよいよプログラムを実行していきます。

画面右の「ファイルエクスプローラー」を使って、解凍したmachiko-senseiフォルダにたどり着いて下さい。

実行するpythonのプログラムファイル「Machiko-Sensei.py」をダブルクリックして、画面左のエディタに表示させて下さい。

入門③ Spyderで実行ボタンを押す。

さて、いよいよゲームプログラムを実行します。メニューより「実行」→「プロファイル」をクリックして下さい。(「F10」キーを押しても同じことが可能です。)

無事、まいっちんぐマチコ先生ゲームが表示されましたか?

プログラム配布の際にはキャラクターを男の子と女の子の画像に変更させてもらっています。こちらもカワイイでしょ?

ちなみに、ゲーム画面で「ESC」キーを押すとエディタ画面に戻れます。初めてSpyderを使う方は徐々に使い方に慣れていきましょう!

次回の入門講座では、まいっちんぐマチコ先生ゲームのプログラムの各部分がなぜそのような動作をするのかを解説しようと思っています。お楽しみに!

from pygame_functions import *
from random import randint

setAutoUpdate(False)
screen = screenSize(1, 1, 1, 1)

# 画像の指定
IMAGE_SET="aishisugite"
PLAYER_IMAGE = "images/" + IMAGE_SET + "_player.png"
CHILD_IMAGE = "images/" + IMAGE_SET + "_child.png"
ITEM_IMAGE = "images/" + IMAGE_SET + "_item.png"
GAMEOVER_IMAGE = "images/" + IMAGE_SET + "_gameover.png"
SCORE_IMAGE =  "images/score.png"
BACK_IMAGE = "images/back.png"

SCREEN_X = 12                # 画面 横サイズ (×キャラ横ピクセル)
SCREEN_Y = 9                 # 画面 縦サイズ (×キャラ縦ピクセル)
PLAYER_ALLIMAGE = 16         # プレイヤー アニメーション全コマ数
PLAYER_SPEED = 5             # プレイヤー 移動スピード
CHILD_INTERVAL = 18          # 子キャラ 連鎖の間隔
player_xlist = []            # プレイヤー 移動履歴X
player_ylist = []            # プレイヤー 移動履歴Y
CHILD_TOUCH_JUDGE = 40       # プレイヤーと子キャラ 当たり判定 (ピクセル)
ITEM_TOUCH_JUDGE = 40        # プレイヤーとアイテム 当たり判定 (ピクセル)
SCORE_DIGIT = 3              # スコア 桁数

# プレイヤークラス
class Player():
    # コンストラクタ
    def __init__(self, img, n):
        self.speed = PLAYER_SPEED
        self.sprite = makeSprite(img, PLAYER_ALLIMAGE)
        self.width = self.sprite.image.get_rect().width
        self.height = self.sprite.image.get_rect().height
        self.xpos = self.width * 3
        self.ypos = self.width * 3 - self.height
        self.x_direction = 0
        self.y_direction = 0
        self.timeOfNextFrame = clock()
        self.frame = 0
        self.child = None
        self.num = n
        if self.num == 0:
            self.next_xpos = self.width * (SCREEN_X - 1)
            self.next_ypos = self.ypos
    # 移動
    def move(self):
        if self.num > 0:
            self.next_xpos = player_xlist[self.num * CHILD_INTERVAL]
            self.next_ypos = player_ylist[self.num * CHILD_INTERVAL]
        if clock() > self.timeOfNextFrame:
            self.frame = (self.frame + 1) % 4
            self.timeOfNextFrame += 160
        if self.next_xpos != self.xpos:
            self.x_direction = (self.next_xpos - self.xpos) // abs(self.next_xpos - self.xpos)
            self.y_direction = 0
            self.xpos += self.speed * self.x_direction
            changeSpriteImage(self.sprite, (1 - self.x_direction) * PLAYER_ALLIMAGE//4 + self.frame)
        elif self.next_ypos != self.ypos:
            self.x_direction = 0
            self.y_direction = (self.next_ypos - self.ypos) // abs(self.next_ypos - self.ypos)
            self.ypos += self.speed * self.y_direction
            changeSpriteImage(self.sprite, (2 - self.y_direction) * PLAYER_ALLIMAGE//4 + self.frame)
        showSprite(self.sprite)
        moveSprite(self.sprite, self.xpos, self.ypos)
        if self.child != None:
            self.child.move()
    # 当たり判定
    def touching(self, x, y):
        if self.child != None and \
            abs(x - self.child.xpos) < ITEM_TOUCH_JUDGE and \
            abs(y - self.child.ypos) < ITEM_TOUCH_JUDGE:
                return True
        if self.child != None and self.child.touching(x, y):
            return True
        else:
            return False

# アイテムクラス
class Item():
    # コンストラクタ
    def __init__(self, img):
        self.sprite = makeSprite(img)
        self.width = self.sprite.image.get_rect().width
        self.height = self.sprite.image.get_rect().height
        self.move()
    # 移動
    def move(self):
        self.xpos = randint(0, SCREEN_X - 1) * self.width
        self.ypos = randint(0, SCREEN_Y - 1) * self.width
        showSprite(self.sprite)
        moveSprite(self.sprite, self.xpos, self.ypos)
        
# スコアクラス
class Score():
    # コンストラクタ
    def __init__(self, x, y, d = SCORE_DIGIT):
        self.sprite = makeSprite(SCORE_IMAGE, 10)
        self.xpos = x
        self.ypos = y
        self.digit = SCORE_DIGIT - d
        self.width = self.sprite.image.get_rect().width
        showSprite(self.sprite)
        moveSprite(self.sprite, self.xpos, self.ypos)
        changeSpriteImage(self.sprite, 0)
        if d > 1:
            self.child = Score(x + self.width, y, d - 1)
    # スコア更新
    def update(self, n):
        sc = str(n).zfill(SCORE_DIGIT)
        changeSpriteImage(self.sprite, int(sc[self.digit]))
        if hasattr(self, 'child'):
            self.child.update(n)

# スプライト配置/スクリーンサイズ/背景
p = Player(PLAYER_IMAGE, 0)
score = Score(0, 15)
item = Item(ITEM_IMAGE)
last = p
screenSize(p.width * SCREEN_X, p.width * SCREEN_Y, 350, 60)
setBackgroundImage(BACK_IMAGE)

# メインループ
n=0
score.update(0)
while True:
    # プレイヤーの移動履歴
    player_xlist.insert(0, p.xpos)
    player_ylist.insert(0, p.ypos)
    p.move()
    # キー判定
    if p.x_direction != -1 and keyPressed("left"):
        p.next_xpos = 0
        p.next_ypos = p.ypos
    if p.x_direction != 1 and keyPressed("right"):
        p.next_ypos = p.ypos
        p.next_xpos = p.width * (SCREEN_X - 1)
    if p.y_direction != -1 and keyPressed("up"):
        p.next_xpos = p.xpos
        p.next_ypos = 0
    if p.y_direction != 1 and keyPressed("down"):
        p.next_xpos = p.xpos
        p.next_ypos = p.width * SCREEN_Y - p.height
    # アイテム当たり判定
    if abs(p.xpos - item.xpos) < ITEM_TOUCH_JUDGE and abs(p.ypos - item.ypos) < ITEM_TOUCH_JUDGE:
        last.child = Player(CHILD_IMAGE, last.num + 1)
        last = last.child
        last.xpos = player_xlist[last.num * CHILD_INTERVAL]
        last.ypos = player_ylist[last.num * CHILD_INTERVAL]
        item.move()
        n += 1
        score.update(n)
    # 子キャラ当たり判定
    if p.touching(p.xpos, p.ypos):
        break;
    
    updateDisplay()
    tick(60)

# ゲームオーバー
gameover = makeImage(GAMEOVER_IMAGE)
screen.blit(gameover, (p.width * SCREEN_X/3, p.height * SCREEN_Y/5))
endWait()

以上、だんなのゲームプログラミング入門講座でした。

だんな
だんな

次回はコチラ

pythonゲームプログラミングのおすすめの書籍

ゲームセンターあらしと学ぶ プログラミング入門 まんが版こんにちはPython(すがや みつる (著))

だんな
だんな

Pythonでゲームプログラミングをしたい方にオススメな本を紹介します。

超オススメ!

コメント