LoginSignup
15
13

More than 3 years have passed since last update.

疑似ターン制バトル

Last updated at Posted at 2020-07-09

なんちゃってRPGの戦闘画面の全貌

疑似ターン制バトル
#coding:utf-8
import tkinter as tk
import tkinter.messagebox as tmsg

#Tkを定める
root = tk.Tk()

#タイトル画面設定
root.geometry("400x300")
root.title("RPG")
canvas = tk.Canvas(root,width = 390, height = 290, bg = "black")
canvas.place(x=4,y=5)
#タイトル文字
canvas.create_rectangle(20,10,370,200,outline="white",width=5,fill="blue")
label=tk.Label(root,font=("System",65),text="CIRCLE!!",)
label.place(x=50,y=50)
label=tk.Label(root,font=("System",10),text="PRESENTED BY SUNBOY",)
label.place(x=50,y=146)
label=tk.Label(root,font=("System",10),text="疑似ターン制RPG",)
label.place(x=50,y=174)


    #戦闘画面移行
def ButtonClick():

    #背景
    canvas=tk.Canvas(root,width=390,height=210,bg="black")
    canvas.place(x=3,y=0)

    #敵の描写
    x=200
    y=100
    canvas.create_oval(x-50,y-50,x+50,y+50,outline="white",width=3)
    x=180
    y=85
    canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)
    x=220
    y=85
    canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)

    #メッセージ
    messabox = tk.Text(root ,font=("System"))
    messabox.place(x=5, y=215, width=290, height=80)
    messabox.insert(tk.END,"CIRCLEが現れた"+"\n")

    #攻撃ボタンがクリックされたときの処理
    def ButtonClick1():
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"あなたの攻撃"+"\n")
        messabox.insert(tk.END,"CIRCLEに10のダメージ!!"+"\n")
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"CIRCLEの攻撃"+"\n")
        messabox.insert(tk.END,"あなたに5のダメージ"+"\n")

        #ここで背景を作り直さないとダメージエフェクトが出ない
        canvas=tk.Canvas(root,width=390,height=210,bg="black")
        canvas.place(x=3,y=0)
        x=200
        y=100
        canvas.create_oval(x-50,y-50,x+50,y+50,fill="black",width=3)

        #通常攻撃判定システム準備
        import random
        a = random.randint(0,9)

        #敗北判定
        if a==1:
            canvas=tk.Canvas(root,width=390,height=210,bg="red")
            canvas.place(x=3,y=0)

            x=200
            y=100
            canvas.create_oval(x-50,y-50,x+50,y+50,outline="black",width=3)
            x=180
            y=85
            canvas.create_oval(x-10,y-10,x+10,y+10,outline="black",width=2)
            x=220
            y=85
            canvas.create_oval(x-10,y-10,x+10,y+10,outline="black",width=2)

            tmsg.showinfo("敗北", "GAMEOVER")    
            root.destroy()     

        #勝利判定
        if (a%2==0) and (a%3==0):
            tmsg.showinfo("勝利", "あなたはCIRCLEを倒した")
            root.destroy()

        #その他
        else:
            def damageb():
                x=200
                y=100
                canvas.create_oval(x-50,y-50,x+50,y+50,outline="white",width=3)
                x=180
                y=85
                canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)
                x=220
                y=85
                canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)

            #タイマー
            root.after(200,damageb)

    #ボタン設置
    button1 = tk.Button(root,text = "攻撃", font=("System", 5),command = ButtonClick1)
    button1.place(x = 297, y = 220)

    #魔法攻撃判定
    def ButtonClick3():
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"あなたの魔法攻撃:ファイア!!"+"\n")        
        messabox.insert(tk.END,"CIRCLEに20のダメージ!!"+"\n")
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"CIRCLEの強攻撃"+"\n")
        messabox.insert(tk.END,"あなたに10のダメージ"+"\n")

        #炎上エフェクト
        canvas=tk.Canvas(root,width=390,height=210,bg="black")
        canvas.place(x=3,y=0)
        x=200
        y=100
        canvas.create_oval(x-50,y-50,x+50,y+50,fill="red",width=3)

        #敵を倒した判定魔法
        import random
        a = random.randint(0,9)

        #敗北判定
        if a==7:
            canvas=tk.Canvas(root,width=390,height=210,bg="red")
            canvas.place(x=3,y=0)

            x=200
            y=100
            canvas.create_oval(x-50,y-50,x+50,y+50,outline="black",width=3)
            x=180
            y=85
            canvas.create_oval(x-10,y-10,x+10,y+10,outline="black",width=2)
            x=220
            y=85
            canvas.create_oval(x-10,y-10,x+10,y+10,outline="black",width=2)
            tmsg.showinfo("敗北", "GAMEOVER")    
            root.destroy()        

        #勝利判定
        if (a%3==0):
            tmsg.showinfo("勝利", "あなたはCIRCLEを倒した")
            root.destroy()

        #その他
        else:
            def damageb():
                x=200
                y=100
                canvas.create_oval(x-50,y-50,x+50,y+50,fill="black",outline="white",width=3)
                x=180
                y=85
                canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)
                x=220
                y=85
                canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)

            #タイマー
            root.after(700,damageb)

    button3 = tk.Button(root,text = "魔法", font=("System", 5),command = ButtonClick3)
    button3.place(x = 346, y = 220)

    #逃走ボタンがクリックされたときの処理
    def ButtonClick2():
        tmsg.showinfo("逃走", "あなたは逃げ出した.....")
        root.destroy()

    button2 = tk.Button(root,text = "逃走", font=("System", 5),command=ButtonClick2)
    button2.place(x = 297, y = 253)

    #敵の情報確認
    def ButtonClick4():
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"CIRCLE"+"\n")
        messabox.insert(tk.END,"攻撃力:5/防御力:???/HP:???"+"\n")
        messabox.insert(tk.END,"謎の球体 じっとこちらを見つめてくる"+"\n")

    button4 = tk.Button(root,text = "情報", font=("System", 5),command = ButtonClick4)
    button4.place(x = 346, y = 253)

#スタートボタン
button = tk.Button(root,text = "始める", font=("System", 5),command = ButtonClick)
button.place(x = 130, y = 220)

#終了ボタン
def ButtonClickfin():
    tmsg.showinfo("終わり", "ゲームを終了します")
    root.destroy()
button5 = tk.Button(root,text = "終わる", font=("System", 5),command = ButtonClickfin)
button5.place(x = 210, y = 220)


root.mainloop()

 タイトル画面作成

今回参考にしたいちばんやさしいPython入門教室:大澤文孝[著]であるが
以下入門教室と呼ぶ

大事な設定
#coding:utf-8
import tkinter as tk
import tkinter.messagebox as tmsg

今回は主にGUIツールキットを使用している。なので、一番最初にtkintermessageboximportしておく。さもないと、のちのtmsgtkが意味をなさない。

タイトル画面設定
#タイトル画面設定
root.geometry("400x300")
root.title("RPG")
canvas = tk.Canvas(root,width = 390, height = 290, bg = "black")
canvas.place(x=4,y=5)
#タイトル文字
canvas.create_rectangle(20,10,370,200,outline="white",width=5,fill="blue")
label=tk.Label(root,font=("System",65),text="CIRCLE!!",)
label.place(x=50,y=50)
label=tk.Label(root,font=("System",10),text="PRESENTED BY SUNBOY",)
label.place(x=50,y=146)
label=tk.Label(root,font=("System",10),text="疑似ターン制RPG",)
label.place(x=50,y=174)

タイトル画面は初代マリオを少し意識したものになっている。
これらは全て入門教室の6章でふれられていたlabelメソッドButtonメソッド、7章のcanvasメソッドの応用で作られている。

タイトルの画像

コメント 2020-07-10 015348.png
画面下にボタンが2つついている。
始めるを押すと戦闘画面に
コメント 2020-07-10 015811.png
終わるを押すとゲームが終了しウィンドウが閉じるようになっている。

戦闘システム

基本戦闘画面
#背景
    canvas=tk.Canvas(root,width=390,height=210,bg="black")
    canvas.place(x=3,y=0)

    #敵の描写
    x=200
    y=100
    canvas.create_oval(x-50,y-50,x+50,y+50,outline="white",width=3)
    x=180
    y=85
    canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)
    x=220
    y=85
    canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)

    #メッセージ
    messabox = tk.Text(root ,font=("System"))
    messabox.place(x=5, y=215, width=290, height=80)
    messabox.insert(tk.END,"CIRCLEが現れた"+"\n")

敵の姿は入門教室7章でもあったcreate_ovalというメソッドを使用した簡単な円で構成されている。

戦闘画面の画像

コメント 2020-07-10 021236.png
コメント 2020-07-10 021319.png
右下にあるのボタンを押すと、テキストボックスにそれぞれメッセージが表示される。
テキストボックスは入門教室6章最後にある、履歴ボックスのinsertメソッドを応用して作成した。なので、メッセージは自動スクロールができないのでいちいち自分でスクロールする必用があるので少し不便だ。
コメント 2020-07-10 022301.png
コメント 2020-07-10 022418.png

勝敗の決め方

また、勝利や敗北の条件は、一番最初はきちんと数値通りのダメージを反映して一定のダメージで勝敗が決まるようにしたかったがいろいろ工夫したり、ネットで調べたりしてもやり方がよくわからなかった。なので、入門教室4章にあるIf構文による条件分岐とrandomモジュールを利用した。具体的には1~9までの数字の中でランダムに数字を決め、通常攻撃の場合6の倍数、魔法攻撃の場合3の倍数が出たら勝利にしてある。
ちなみに通常攻撃は1、魔法攻撃なら7が出たら敗北である。

攻撃システム

攻撃システム
 #攻撃ボタンがクリックされたときの処理
    def ButtonClick1():
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"あなたの攻撃"+"\n")
        messabox.insert(tk.END,"CIRCLEに10のダメージ!!"+"\n")
        messabox.insert(tk.END,"___________________________________"+"\n")
        messabox.insert(tk.END,"CIRCLEの攻撃"+"\n")
        messabox.insert(tk.END,"あなたに5のダメージ"+"\n")

        #ここで背景を作り直さないとダメージエフェクトが出ない!!
        canvas=tk.Canvas(root,width=390,height=210,bg="black")
        canvas.place(x=3,y=0)
        x=200
        y=100
        canvas.create_oval(x-50,y-50,x+50,y+50,fill="black",width=3)

        #通常攻撃判定システム準備
        import random
        a = random.randint(0,9)

        #敗北判定
        if a==1:
            canvas=tk.Canvas(root,width=390,height=210,bg="red")
            canvas.place(x=3,y=0)

            x=200
            y=100
            canvas.create_oval(x-50,y-50,x+50,y+50,outline="black",width=3)
            x=180
            y=85
            canvas.create_oval(x-10,y-10,x+10,y+10,outline="black",width=2)
            x=220
            y=85
            canvas.create_oval(x-10,y-10,x+10,y+10,outline="black",width=2)

            tmsg.showinfo("敗北", "GAMEOVER")    
            root.destroy()     

        #勝利判定
        if (a%2==0) and (a%3==0):
            tmsg.showinfo("勝利", "あなたはCIRCLEを倒した")
            root.destroy()

        #その他
        else:
            def damageb():
                x=200
                y=100
                canvas.create_oval(x-50,y-50,x+50,y+50,outline="white",width=3)
                x=180
                y=85
                canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)
                x=220
                y=85
                canvas.create_oval(x-10,y-10,x+10,y+10,outline="white",width=15)

            #タイマー
            root.after(200,damageb)

    #ボタン設置
    button1 = tk.Button(root,text = "攻撃", font=("System", 5),command = ButtonClick1)
    button1.place(x = 297, y = 220)

ぶっちゃけ、バトルの勝敗は確立なのでメッセージボックスに表示されているダメージの数字には何の意味もない

  • 個人的にダメージ演出には少しこだわっており、通常攻撃では相手が点滅、魔法攻撃だと相手は一瞬赤く染まる。

これらは、7章にあるタイマー機能を利用している。

タイトル画面のお話+α

タイトルから戦闘画面に飛ぶ

    #戦闘画面移行
def ButtonClick():

-----------------------------------------------------------------------------

#スタートボタン
button = tk.Button(root,text = "始める", font=("System", 5),command = ButtonClick)
button.place(x = 130, y = 220)

#終了ボタン
def ButtonClickfin():
    tmsg.showinfo("終わり", "ゲームを終了します")
    root.destroy()
button5 = tk.Button(root,text = "終わる", font=("System", 5),command = ButtonClickfin)
button5.place(x = 210, y = 220)

始めるボタンで戦闘画面に移行するためにdefを利用し、途中150行近くをすべて関数という扱いにした。

感想

私がPython初心者で未熟なこともあり、ターン制バトルと呼べるかも怪しいなんちゃって作品になってしまった。次にゲームを制作するときはBGMや効果音、派手なエフェクト、実際の攻撃力を反映したダメージや残りHPの確認、ちゃんとした画像が表示できるような作品が作りたい。

参考文献

  • いちばんやさしいPython入門教室:大澤文孝[著]
15
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13