DockerとPython(とSQL)で簡単なRPGゲームを作る Ⅰ~Docker+python3環境構築~


概要

在宅ワークに飽きてきたのでゲームでも作ってみようと思います.
暇なときにちょっとずつ作っていきます.

環境構築

Python3が使用可能なDocker環境を作る.
Tkinterとか使ってGUIも作れるといいと思っている.

ディレクトリ構成

Game
  |-Docker
  |   |-Dockerfile
  |   |-docker-compose.yml
  |   |-requirements.txt(pip用)
  |
  |-program
  |   |-(program)
  |-DB
     |-(player-data etc)

Dockerfile

FROM python:3.7.0-slim

WORKDIR /app
COPY /requirements.txt /app/

RUN apt-get update \
  && apt-get -y upgrade \
  && apt-get install -y python3-tk \
  && pip install --no-cache-dir -r requirements.txt \
  && rm -rf /tmp/* /var/tmp/* \
  && rm -rf /var/lib/apt/lists/* \
  rm -rf /var/lib/apt/lists/*

WORKDIR /work

ついでにcompose-upも作っておく(そのうちSQLにデータを保存したりしたい)

docker-compose.yml
version: '3'
services:
    quest-env:
        image: "quest-image"
        volumes:
            - ./../program/:/work
        tty: true

とりあえず動作確認

Hello world代わりに以下のプログラムを作成,実行

Battle.py
def Encount(monster):
    print("やせいの{}があらわれた!".format(monster))

if __name__ == '__main__':
    Encount('スライム')
python3 Battle.py
やせいのスライムがあらわれた!

やったね!

基本となるキャラクタークラスを作る

敵味方関係なく基本となるキャラクターのクラスを作る.ここから継承とかしていけたら勉強になっていいな...
名前,攻撃力,HPを持っていて攻撃とダメージ計算ができるクラス.超単純.

character.py
class character():
    def __init__(self, name, attack, HP):
        self.name = name
        self.atk = attack
        self.hp = HP

    def attack(self):
        return self.atk

    def damage(self, enemy_attack):
        damage = enemy_attack
        self.hp -= damage
        return damage

相手の攻撃力を一旦damageに移しているのは,後々たまにダメージ倍増とかを入れる準備.

さっきのBattle.pyに入れて動かしてみる.
とりあえずプレイヤーとモンスターのインスタンスを生成して戦わせる.

Battle.py
import character

def Encount(monster):
    print("やせいの{}があらわれた!".format(monster.name))

def Attack(attacker, defender):
    print("{}のこうげき!{}に{}のダメージ".format(attacker.name, defender.name, defender.damage(attacker.atk)))
    return defender.hp

def Battle(player, monster):
    Encount(monster)
    turn = 0
    while(1):
        turn += 1
        print("--------------------")
        print("ターン:{} HP:{}".format(turn, player.hp))     
        if Attack(player, monster) <= 0:
            print("{}を倒した!".format(monster.name))
            break
        if Attack(monster, player) <= 0:
            print("{}は倒れた!".format(player.name))
            break

if __name__ == '__main__':
    player = character.character('たこやき', 2, 10)
    monster = character.character('スライム', 2, 10)
    Battle(player, monster)

一応攻撃を関数化して共通化してみた.あと先制攻撃を入れるために遭遇も分けてみた.

一応勝ち負けのパターンでテストしたけど勝ったパターン載せときます.

python3 Battle.py
やせいのスライムがあらわれた!
--------------------
ターン:1 HP:10
たこやきのこうげき!スライムに2のダメージ
スライムのこうげき!たこやきに2のダメージ
--------------------
ターン:2 HP:8
たこやきのこうげき!スライムに2のダメージ
スライムのこうげき!たこやきに2のダメージ
--------------------
ターン:3 HP:6
たこやきのこうげき!スライムに2のダメージ
スライムのこうげき!たこやきに2のダメージ
--------------------
ターン:4 HP:4
たこやきのこうげき!スライムに2のダメージ
スライムのこうげき!たこやきに2のダメージ
--------------------
ターン:5 HP:2
たこやきのこうげき!スライムに2のダメージ
スライムを倒した!

勝った!

今日はこれくらいにしておきます.