ーー  python (GUI 開発の基礎) ーー

python [ IDLE ] でリアルタイムに画像処理する手法。

Game開発などで使われる

今まで謎だったリアル画像の動的処理を Win10 上で行う試み

Game開発の基礎を学ぶ

pythonでRPG,ダンジョンGameを解析し構造を理解する。

##sinnki 2
import tkinter
import random

FNT = ("Times New Roman", 20, "bold")

key = ""
keyoff = False
idx = 0
tmr = 0
stage = 0
score = 0
bar_x = 0
bar_y = 540
ball_x = 0
ball_y = 0
ball_xp = 0
ball_yp = 0
is_clr = True

block = []
for i in range(5):
    block.append([1]*10)
for i in range(10):
    block.append([0]*10)

def key_down(e):
    global key
    key = e.keysym

def key_up(e):
    global keyoff
    keyoff = True

def draw_block():
    global is_clr
    is_clr = True
    cvs.delete("BG")
    for y in range(15):
        for x in range(10):
            gx = x*80
            gy = y*40
            if block[y][x] == 1:
                cvs.create_rectangle(gx+1, gy+4, gx+79, gy+32, fill=block_color(x,y), width=0, tag="BG")
                is_clr = False
    cvs.create_text(200, 20, text="STAGE "+str(stage), fill="white", font=FNT, tag="BG")
    cvs.create_text(600, 20, text="SCORE "+str(score), fill="white", font=FNT, tag="BG")

def block_color(x, y): # format()命令で16進数の値に変換できる
    col = "#{0:x}{1:x}{2:x}".format(15-x-int(y/3), x+1, y*3+3)
    return col

def draw_bar():
    cvs.delete("BAR")
    cvs.create_rectangle(bar_x-80, bar_y-12, bar_x+80, bar_y+12, fill="silver", width=0, tag="BAR")
    cvs.create_rectangle(bar_x-78, bar_y-14, bar_x+78, bar_y+14, fill="silver", width=0, tag="BAR")
    cvs.create_rectangle(bar_x-78, bar_y-12, bar_x+78, bar_y+12, fill="white", width=0, tag="BAR")

def move_bar():
    global bar_x
    if key == "Left" and bar_x > 80:
        bar_x = bar_x - 40
    if key == "Right" and bar_x < 720:
        bar_x = bar_x + 40

def draw_ball():
    cvs.delete("BALL")
    cvs.create_oval(ball_x-20, ball_y-20, ball_x+20, ball_y+20, fill="gold", outline="orange", width=2, tag="BALL")
    cvs.create_oval(ball_x-16, ball_y-16, ball_x+12, ball_y+12, fill="yellow", width=0, tag="BALL")

def move_ball():
    global idx, tmr, score, ball_x, ball_y, ball_xp, ball_yp
    ball_x = ball_x + ball_xp
    if ball_x < 20:
        ball_x = 20
        ball_xp = -ball_xp
    if ball_x > 780:
        ball_x = 780
        ball_xp = -ball_xp
    x = int(ball_x/80)
    y = int(ball_y/40)
    if block[y][x] == 1:
        block[y][x] = 0
        ball_xp = -ball_xp
        score = score + 10

    ball_y = ball_y + ball_yp
    if ball_y >= 600:
        idx = 2
        tmr = 0
        return
    if ball_y < 20:
        ball_y = 20
        ball_yp = -ball_yp
    x = int(ball_x/80)
    y = int(ball_y/40)
    if block[y][x] == 1:
        block[y][x] = 0
        ball_yp = -ball_yp
        score = score + 10

    if bar_y-40 <= ball_y and ball_y <= bar_y:
        if bar_x-80 <= ball_x and ball_x <= bar_x+80:
            ball_yp = -10
            score = score + 1
        elif bar_x-100 <= ball_x and ball_x <= bar_x-80:
            ball_yp = -10
            ball_xp = random.randint(-20, -10)
            score = score + 2
        elif bar_x+80 <= ball_x and ball_x <= bar_x+100:
            ball_yp = -10
            ball_xp = random.randint(10, 20)
            score = score + 2

def main_proc():
    global key, keyoff
    global idx, tmr, stage, score
    global bar_x, ball_x, ball_y, ball_xp, ball_yp
    if idx == 0:
        tmr = tmr + 1
        if tmr == 1:
            stage = 1
            score = 0
        if tmr == 2:
            ball_x = 160
            ball_y = 240
            ball_xp = 10
            ball_yp = 10
            bar_x = 400
            draw_block()
            draw_ball()
            draw_bar()
            cvs.create_text(400, 300, text="START", fill="cyan", font=FNT, tag="TXT")
        if tmr == 30:
            cvs.delete("TXT")
            idx = 1
    elif idx == 1:
        move_ball()
        move_bar()
        draw_block()
        draw_ball()
        draw_bar()
        if is_clr == True:
            idx = 3
            tmr = 0
    elif idx == 2:
        tmr = tmr + 1
        if tmr == 1:
            cvs.create_text(400, 260, text="GAME OVER", fill="red", font=FNT, tag="TXT")
        if tmr == 15:
            cvs.create_text(300, 340, text="[R]eplay", fill="cyan", font=FNT, tag="TXT")
            cvs.create_text(500, 340, text="[N]ew game", fill="yellow", font=FNT, tag="TXT")
        if key == "r":
            cvs.delete("TXT")
            idx = 0
            tmr = 1
        if key == "n":
            cvs.delete("TXT")
            for y in range(5):
                for x in range(10):
                    block[y][x] = 1
            idx = 0
            tmr = 0
    elif idx == 3:
        tmr = tmr + 1
        if tmr == 1:
            cvs.create_text(400, 260, text="STAGE CLEAR", fill="lime", font=FNT, tag="TXT")
        if tmr == 15:
            cvs.create_text(400, 340, text="NEXT [SPACE]", fill="cyan", font=FNT, tag="TXT")
        if key == "space":
            cvs.delete("TXT")
            for y in range(5):
                for x in range(10):
                    block[y][x] = 1
            idx = 0
            tmr = 1
            stage = stage + 1

    if keyoff == True:
        keyoff = False
        if key != "":
            key = ""

    root.after(50, main_proc)

root = tkinter.Tk()
root.title("ブロックゲーム")
root.resizable(False, False)
root.bind("<Key>", key_down)
root.bind("<KeyRelease>", key_up)
cvs = tkinter.Canvas(root, width=800, height=600, bg="black")
cvs.pack()
main_proc()
root.mainloop()



## sinnki 1

import tkinter
import tkinter.messagebox
import pygame
import sys

idx = 0
tmr = 0
stage = 1
ix = 0
iy = 0
key = 0

def key_down(e):
    global key
    key = e.keysym

def key_up(e):
    global key
    key = 0

maze = [[],[],[],[],[],[],[],[]]

def stage_data():
    global ix, iy
    global maze##リスト全体を変更する場合global宣言が必要
    if stage == 1:
        ix = 1
        iy = 1
        maze = [##0が床、1が塗った場所、9が壁
            [9,9,9,9,9,9,9,9,9,9],
            [9,0,9,0,0,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,9,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,9,0,9],
            [9,0,0,0,9,0,0,0,0,9],
            [9,9,9,9,9,9,9,9,9,9]
            ]
    if stage == 2:
        ix = 8
        iy = 6
        maze = [##0が床、1が塗った場所、9が壁
            [9,9,9,9,9,9,9,9,9,9],
            [9,0,0,0,9,0,0,0,0,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,9,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,9,0,9],
            [9,0,0,0,0,0,9,9,0,9],
            [9,9,9,9,9,9,9,9,9,9]
            ]
    if stage == 3:
        ix = 1
        iy = 1
        maze = [##0が床、1が塗った場所、9が壁
            [9,9,9,9,9,9,9,9,9,9],
            [9,0,9,0,0,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,0,0,0,9],
            [9,0,9,0,9,9,9,9,0,9],
            [9,0,9,0,9,9,9,9,0,9],
            [9,0,0,0,0,0,0,0,0,9],
            [9,9,9,9,9,9,9,9,9,9]
            ]
    if stage == 4:
        ix = 1
        iy = 1
        maze = [##0が床、1が塗った場所、9が壁
            [9,9,9,9,9,9,9,9,9,9],
            [9,0,9,0,0,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,9,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,9,0,9],
            [9,0,0,0,9,0,0,0,0,9],
            [9,9,9,9,9,9,9,9,9,9]
            ]
    if stage == 5:
        ix = 1
        iy = 1
        maze = [##0が床、1が塗った場所、9が壁
            [9,9,9,9,9,9,9,9,9,9],
            [9,0,9,0,0,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,0,9,9],
            [9,0,9,0,9,0,9,0,0,9],
            [9,0,9,0,9,0,9,9,0,9],
            [9,0,0,0,9,0,0,0,0,9],
            [9,9,9,9,9,9,9,9,9,9]
            ]
    maze[iy][ix] = 1

def draw_bg():
    for y in range(8):
        for x in range(10):
            gx = 80*x
            gy = 80*y
            if maze[y][x] == 0:
                cvs.create_rectangle(gx, gy, gx+80, gy+80, fill="white", width=0, tag="BG")
            if maze[y][x] == 9:
                cvs.create_image(gx+40, gy+40, image=wall, tag="BG")
    cvs.create_text(120, 40, text="STAGE "+str(stage), fill="white", font=("TImes New Roman", 30, "bold"), tag="BG")
    gx = 80*ix
    gy = 80*iy
    cvs.create_rectangle(gx, gy, gx+80, gy+80, fill="pink", width=0, tag="BG")
    cvs.create_image(gx+42, gy+40, image=pen, tag="PEN")

def erase_bg():
    cvs.delete("BG")
    cvs.delete("PEN")

def move_pen():
    
    global idx, tmr, ix, iy, key
    bx = ix
    by = iy
    if key == "Left" and maze[iy][ix-1] == 0:
        ix = ix-1
    if key == "Right" and maze[iy][ix+1] == 0:
        ix = ix+1
    if key == "Up" and maze[iy-1][ix] == 0:
        iy = iy-1
    if key == "Down" and maze[iy+1][ix] == 0:
        iy = iy+1
    if ix != bx or iy != by:
        maze[iy][ix] = 2
        gx = 80*ix
        gy = 80*iy
        cvs.create_rectangle(gx, gy ,gx+80, gy+80, fill="pink", width=0, tag="BG")
        cvs.delete("PEN")
        cvs.create_image(gx+42, gy+40, image=pen, tag="PEN")

    if key == "g" or key == "G" or key == "Shift_L":
        key = 0
        ret = tkinter.messagebox.askyesno("ギブアップ","やり直しますか?")
        root.focus_force()##for mac
        if ret == True:
            stage_data()
            erase_bg()
            draw_bg()

def count_tile():
    cnt = 0
    for y in range(8):
        for x in range(10):
            if maze[y][x] == 0:
                cnt = cnt + 1
    return cnt

def game_main():
    
    global idx, tmr, stage
    if idx == 0:##初期化
        pygame.mixer.music.load("ohd_bgm_field.ogg")
        pygame.mixer.music.play(-1)
        pygame.mixer.music.set_volume(0.3)##BGMボリューム設定0から1まで
        stage_data()
        draw_bg()
        idx = 1
    if idx == 1:##ペンの移動とクリアの判定
        move_pen()
        if count_tile() == 0:
            txt = "STAGE CLEAR"
            if stage == 5:
                txt = "ALL STAGE CLEAR!"
            cvs.create_text(400, 320, text=txt, fill="white", font=("Times New Roman", 40, "bold"), tag="BG")
            idx = 2
            tmr = 0
    if idx == 2:##ステージクリア
        tmr = tmr + 1
        if tmr == 30:
            if stage < 5:
                stage = stage + 1
                stage_data()
                erase_bg()
                draw_bg()
                idx = 1
            if stage == 5:
                stage = 0
    root.after(200, game_main)

pygame.init()
root = tkinter.Tk()
root.title("一筆書き迷路ゲーム")
root.resizable(False, False)
root.bind("<KeyPress>", key_down)
root.bind("<KeyRelease>", key_up)
cvs = tkinter.Canvas(root, width=800, height=640)
cvs.pack()
pen = tkinter.PhotoImage(file="pen.png")
wall = tkinter.PhotoImage(file="wall.png")
game_main()
root.mainloop()

##Dungeon Game 解析用

import pygame
import sys
import random
from pygame.locals import *

# 色の定義
WHITE = (255, 255, 255)
BLACK = (  0,   0,   0)
RED   = (255,   0,   0)
CYAN  = (  0, 255, 255)
BLINK = [(224,255,255), (192,240,255), (128,224,255), (64,192,255), (128,224,255), (192,240,255)]

# 画像の読み込み
imgTitle = pygame.image.load("image/title.png")
imgWall = pygame.image.load("image/wall.png")
imgWall2 = pygame.image.load("image/wall2.png")
imgDark = pygame.image.load("image/dark.png")
imgPara = pygame.image.load("image/parameter.png")
imgBtlBG = pygame.image.load("image/btlbg.png")
imgEnemy = pygame.image.load("image/enemy0.png")##敵のimage
imgItem = [
    pygame.image.load("image/potion.png"),
    pygame.image.load("image/blaze_gem.png"),
    pygame.image.load("image/spoiled.png"),
    pygame.image.load("image/apple.png"),
    pygame.image.load("image/meat.png")
]
imgFloor = [
    pygame.image.load("image/floor.png"),##床0
    pygame.image.load("image/tbox.png"),##宝1
    pygame.image.load("image/cocoon.png"),##繭2
    pygame.image.load("image/stairs.png")##階段3
]
imgPlayer = [
    pygame.image.load("image/mychr0.png"),##上
    pygame.image.load("image/mychr1.png"),##上2
    pygame.image.load("image/mychr2.png"),##下
    pygame.image.load("image/mychr3.png"),##下2
    pygame.image.load("image/mychr4.png"),##左
    pygame.image.load("image/mychr5.png"),##左2
    pygame.image.load("image/mychr6.png"),##右
    pygame.image.load("image/mychr7.png"),##右2
    pygame.image.load("image/mychr8.png")##死亡
]
imgEffect = [
    pygame.image.load("image/effect_a.png"),##py攻撃 剣
    pygame.image.load("image/effect_b.png")##py魔法 炎
]

# 変数の宣言
speed = 1
idx = 0
tmr = 0
floor = 0
fl_max = 1
welcome = 0

pl_x = 0
pl_y = 0
pl_d = 0
pl_a = 0
pl_lifemax = 0
pl_life = 0
pl_str = 0
food = 0
potion = 0
blazegem = 0
treasure = 0

emy_name = ""
emy_lifemax = 0
emy_life = 0
emy_str = 0
emy_x = 0
emy_y = 0
emy_step = 0
emy_blink = 0

dmg_eff = 0
btl_cmd = 0

COMMAND = ["[A]ttack", "[P]otion", "[B]laze gem", "[R]un"]
TRE_NAME = ["Potion", "Blaze gem", "Food spoiled.", "Food +20", "Food +100"]
EMY_NAME = [
    "Green slime", "Red slime", "Axe beast", "Ogre", "Sword man",
    "Death hornet", "Signal slime", "Devil plant", "Twin killer", "Hell"
    ]

MAZE_W = 11
MAZE_H = 9
maze = []
for y in range(MAZE_H):
    maze.append([0]*MAZE_W)

DUNGEON_W = MAZE_W*3
DUNGEON_H = MAZE_H*3
dungeon = []
for y in range(DUNGEON_H):
    dungeon.append([0]*DUNGEON_W)

def make_dungeon(): # ダンジョンの自動生成
    XP = [ 0, 1, 0,-1]
    YP = [-1, 0, 1, 0]
    #周りの壁
    for x in range(MAZE_W):
        maze[0][x] = 1
        maze[MAZE_H-1][x] = 1
    for y in range(1, MAZE_H-1):
        maze[y][0] = 1
        maze[y][MAZE_W-1] = 1
    #中を何もない状態に
    for y in range(1, MAZE_H-1):
        for x in range(1, MAZE_W-1):
            maze[y][x] = 0
    #柱
    for y in range(2, MAZE_H-2, 2):
        for x in range(2, MAZE_W-2, 2):
            maze[y][x] = 1
    #柱から上下左右に壁を作る
    for y in range(2, MAZE_H-2, 2):
        for x in range(2, MAZE_W-2, 2):
         d = random.randint(0, 3)
         if x > 2: # 二列目からは左に壁を作らない
             d = random.randint(0, 2)
         maze[y+YP[d]][x+XP[d]] = 1

    # 迷路からダンジョンを作る
    #全体を壁にする
    for y in range(DUNGEON_H):
        for x in range(DUNGEON_W):
            dungeon[y][x] = 9
    #部屋と通路の配置
    for y in range(1, MAZE_H-1):
        for x in range(1, MAZE_W-1):
            dx = x*3+1
            dy = y*3+1
            if maze[y][x] == 0:
                if random.randint(0, 99) < 20: # 部屋を作る
                    for ry in range(-1, 2):
                        for rx in range(-1, 2):
                            dungeon[dy+ry][dx+rx] = 0
                else: # 通路を作る
                    dungeon[dy][dx] = 0
                    if maze[y-1][x] == 0: dungeon[dy-1][dx] = 0
                    if maze[y+1][x] == 0: dungeon[dy+1][dx] = 0
                    if maze[y][x-1] == 0: dungeon[dy][dx-1] = 0
                    if maze[y][x+1] == 0: dungeon[dy][dx+1] = 0

def draw_dungeon(bg, fnt): # ダンジョンを描画する
    bg.fill(BLACK)
    for y in range(-4, 6):
        for x in range(-5, 6):
            X = (x+5)*80
            Y = (y+4)*80
            dx = pl_x + x
            dy = pl_y + y
            if 0 <= dx and dx < DUNGEON_W and 0 <= dy and dy < DUNGEON_H:
                if dungeon[dy][dx] <= 3:
                    bg.blit(imgFloor[dungeon[dy][dx]], [X, Y])
                if dungeon[dy][dx] == 9:
                    bg.blit(imgWall, [X, Y-40])
                    if dy >= 1 and dungeon[dy-1][dx] == 9:
                        bg.blit(imgWall2, [X, Y-80])
            if x == 0 and y == 0: # 主人公キャラの表示
                bg.blit(imgPlayer[pl_a], [X, Y-40])
    bg.blit(imgDark, [0, 0]) # 四隅が暗闇の画像を重ねる
    draw_para(bg, fnt) # 主人公の能力を表示

def put_event(): # 床にイベントを配置する
    global pl_x, pl_y, pl_d, pl_a
    
    # 階段の配置
    while True:
        x = random.randint(3, DUNGEON_W-4)
        y = random.randint(3, DUNGEON_H-4)
        if(dungeon[y][x] == 0):
            for ry in range(-1, 2): # 階段の周囲を床にする
                for rx in range(-1, 2):
                    dungeon[y+ry][x+rx] = 0
            dungeon[y][x] = 3##階段imgFloor
            break
        
    # 宝箱 1 と繭 2 の配置
    for i in range(60):
        x = random.randint(3, DUNGEON_W-4)
        y = random.randint(3, DUNGEON_H-4)
        if(dungeon[y][x] == 0):
            dungeon[y][x] = random.choice([1,2,2,2,2])
            
    # プレイヤーの初期位置
    while True:
        pl_x = random.randint(3, DUNGEON_W-4)
        pl_y = random.randint(3, DUNGEON_H-4)
        if(dungeon[pl_y][pl_x] == 0):
            break
    pl_d = 1
    pl_a = 2
                
def move_player(key): # 主人公の移動
    global idx, tmr, pl_x, pl_y, pl_d, pl_a, pl_life, food, potion, blazegem, treasure

    if dungeon[pl_y][pl_x] == 1: # 宝箱 1 に載った
        dungeon[pl_y][pl_x] = 0
        treasure = random.choice([0,0,0,1,1,1,1,1,1,2])
        if treasure == 0:##potion入手
            potion = potion + 1
        if treasure == 1:##blazegem入手
            blazegem = blazegem + 1
        if treasure == 2:##毒 food/2
            food = int(food/2)
        idx = 3
        tmr = 0
        return
    
    if dungeon[pl_y][pl_x] == 2: # 繭 2 に載った
        dungeon[pl_y][pl_x] = 0
        r = random.randint(0, 99)
        if r < 40: # 食料
            treasure = random.choice([3,3,3,4])
            if treasure == 3: food = food + 20
            if treasure == 4: food = food + 100
            idx = 3
            tmr = 0
        else: # 敵出現
            idx = 10
            tmr = 0
        return
    if dungeon[pl_y][pl_x] == 3: # 階段 3 に載った
        idx = 2
        tmr = 0
        return

    # 方向キーで上下左右に移動
    x = pl_x
    y = pl_y
    
    if key[K_UP] == 1:##上 0 が押された 上が9の壁でなければ代入
        pl_d = 0
        if dungeon[pl_y-1][pl_x] != 9:
            pl_y = pl_y - 1
    if key[K_DOWN] == 1:##下 1
        pl_d = 1
        if dungeon[pl_y+1][pl_x] != 9:
            pl_y = pl_y + 1
    if key[K_LEFT] == 1:##左 2
        pl_d = 2
        if dungeon[pl_y][pl_x-1] != 9:
            pl_x = pl_x - 1
    if key[K_RIGHT] == 1:##右 3
        pl_d = 3
        if dungeon[pl_y][pl_x+1] != 9:
            pl_x = pl_x + 1
            
    pl_a = pl_d*2
    
    if pl_x != x or pl_y != y: # 移動したら食料の量と体力を計算
        pl_a = pl_a + tmr%2 # 移動したら足踏みのアニメーション
        if food > 0:
            food = food - 1
            if pl_life < pl_lifemax:
                pl_life = pl_life + 1
        else:##食料がなければ1マス動くごとにライフが-5
            pl_life = pl_life - 5
            if pl_life <= 0:
                pl_life = 0
                pygame.mixer.music.stop()
                idx = 9
                tmr = 0
##look## draw_text
def draw_text(bg, txt, x, y, fnt, col): # 影付き文字の表示
    sur = fnt.render(txt, True, BLACK)
    bg.blit(sur, [x+1, y+2])
    sur = fnt.render(txt, True, col)
    bg.blit(sur, [x, y])
##look## draw_para
def draw_para(bg, fnt): # 主人公の能力を表示
    X = 30
    Y = 600
    
    bg.blit(imgPara, [X, Y])##image/parameter
    
    col = WHITE
    
    if pl_life < 10 and tmr%2 == 0: col = RED
    draw_text(bg, "{}/{}".format(pl_life, pl_lifemax), X+128, Y+6, fnt, col)
    draw_text(bg, str(pl_str), X+128, Y+33, fnt, WHITE)
    col = WHITE
    
    if food == 0 and tmr%2 == 0: col = RED
    
    draw_text(bg, str(food), X+128, Y+60, fnt, col)
    draw_text(bg, str(potion), X+266, Y+6, fnt, WHITE)
    draw_text(bg, str(blazegem), X+266, Y+33, fnt, WHITE)

##look## init_battle
def init_battle(): # 戦闘に入る準備をする
    
    global imgEnemy, emy_name, emy_lifemax, emy_life, emy_str, emy_x, emy_y
    
    typ = random.randint(0, floor)##深層フロアに行くほどtyp数多くなる
    if floor >= 10:##10階以上は全ての敵が出現
        typ = random.randint(0, 9)
        
    lev = random.randint(1, floor)##敵レベルの決定   
    imgEnemy = pygame.image.load("image/enemy"+str(typ)+".png")##敵のimageを読み込む0~9まで   
    emy_name = EMY_NAME[typ] + " LV" + str(lev)##名前   
    emy_lifemax = 60*(typ+1) + (lev-1)*10##ライフ最大   
    emy_life = emy_lifemax##ライフ   
    emy_str = int(emy_lifemax/8)##攻撃力 ライフmaxの1/8   
    emy_x = 440-imgEnemy.get_width()/2##表示位置
    emy_y = 560-imgEnemy.get_height()
##look## draw_bar
def draw_bar(bg, x, y, w, h, val, max): # 敵の体力を表示するバー
    pygame.draw.rect(bg, WHITE, [x-2, y-2, w+4, h+4])##矩形表示 空の枠線が白
    pygame.draw.rect(bg, BLACK, [x, y, w, h])##中身が黒
    if val > 0:
        pygame.draw.rect(bg, (0,128,255), [x, y, w*val/max, h])##valはemy_life 敵にライフがあれば
        ##(0,128,255) =青 wは200   w*val/maxはw   ライフ分は青く 空白は黒く 表示


##draw_battle? emy_blink は idx 12で代入確認せよ 
def draw_battle(bg, fnt): # 戦闘画面の描画
    global emy_blink, dmg_eff
    bx = 0
    by = 0
    if dmg_eff > 0:##画面を揺らす
        dmg_eff = dmg_eff - 1
        bx = random.randint(-20, 20)
        by = random.randint(-10, 10)
    bg.blit(imgBtlBG, [bx, by])
    
    ##py攻撃 emy_blink敵の明滅 敵の攻撃 emy_step敵を前方へ
    if emy_life > 0 and emy_blink%2 == 0:
        bg.blit(imgEnemy, [emy_x, emy_y+emy_step])
    draw_bar(bg, 340, 580, 200, 10, emy_life, emy_lifemax)##draw_bar上の関数
    
    if emy_blink > 0:##emy_blink 敵を前に出す 数値を-1し減らしていく
        emy_blink = emy_blink - 1
        
    for i in range(10): # 戦闘メッセージの表示 10
        draw_text(bg, message[i], 600, 100+i*50, fnt, WHITE)
        
    draw_para(bg, fnt) # 主人公の能力を表示

##look## battle_command
def battle_command(bg, fnt, key): # コマンドの入力と表示 btl_cmdでカーソル制御 entがTrueの返り値
    global btl_cmd
    ent = False
    if key[K_a]: # Aキー
        btl_cmd = 0
        ent = True
    if key[K_p]: # Pキー
        btl_cmd = 1
        ent = True
    if key[K_b]: # Bキー
        btl_cmd = 2
        ent = True
    if key[K_r]: # Rキー
        btl_cmd = 3
        ent = True
    if key[K_UP] and btl_cmd > 0: #↑キー
        btl_cmd -= 1
    if key[K_DOWN] and btl_cmd < 3: #↓キー
        btl_cmd += 1
    if key[K_SPACE] or key[K_RETURN]:
        ent = True
        
    for i in range(4):##選択されているコマンドが虹色に表示される
        c = WHITE
        if btl_cmd == i: c = BLINK[tmr%6]##BKINK 色の配列 虹色に変化
        draw_text(bg, COMMAND[i], 20, 360+i*60, fnt, c)
    return ent

##戦闘メッセージの表示処理
message = [""]*10

##look## init_message
def init_message():
    for i in range(10):
        message[i] = ""
##look## set_message    
def set_message(msg):
    for i in range(10):
        if message[i] == "":
            message[i] = msg
            return
    for i in range(9):
        message[i] = message[i+1]
    message[9] = msg


def main(): # メイン処理
    global speed, idx, tmr, floor, fl_max, welcome
    global pl_a, pl_lifemax, pl_life, pl_str, food, potion, blazegem
    global emy_life, emy_step, emy_blink, dmg_eff
    dmg = 0
    lif_p = 0
    str_p = 0

    pygame.init()
    pygame.display.set_caption("One hour Dungeon")
    screen = pygame.display.set_mode((880, 720))
    clock = pygame.time.Clock()
    font = pygame.font.Font(None, 40)
    fontS = pygame.font.Font(None, 30)

    se = [ # 効果音とジングル
        pygame.mixer.Sound("sound/ohd_se_attack.ogg"),##プレイヤーアタック時
        pygame.mixer.Sound("sound/ohd_se_blaze.ogg"),
        pygame.mixer.Sound("sound/ohd_se_potion.ogg"),
        pygame.mixer.Sound("sound/ohd_jin_gameover.ogg"),
        pygame.mixer.Sound("sound/ohd_jin_levup.ogg"),
        pygame.mixer.Sound("sound/ohd_jin_win.ogg")
    ]

    while True:##スピード調整
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_s:
                    speed = speed + 1
                    if speed == 4:
                        speed = 1

        tmr = tmr + 1
        key = pygame.key.get_pressed()
##look## main 
        if idx == 0: # タイトル画面
            if tmr == 1:
                pygame.mixer.music.load("sound/ohd_bgm_title.ogg")
                pygame.mixer.music.play(-1)
            screen.fill(BLACK)
            screen.blit(imgTitle, [40, 60])
            if fl_max >= 2:
                draw_text(screen, "You reached floor {}.".format(fl_max), 300, 460, font, CYAN)
                
            draw_text(screen, "Press space key", 320, 560, font, BLINK[tmr%6])
            
            if key[K_SPACE] == 1:##Game START
                make_dungeon()##
                put_event()##pl_a 2 pl_b 1
                floor = 1
                welcome = 15
                pl_lifemax = 300
                pl_life = pl_lifemax
                pl_str = 100
                food = 300
                potion = 0
                blazegem = 0
                idx = 1
                pygame.mixer.music.load("sound/ohd_bgm_field.ogg")
                pygame.mixer.music.play(-1)
##look## idx 1
        elif idx == 1: # プレイヤーの移動
            move_player(key)##分岐の基幹部分
            draw_dungeon(screen, fontS)
            draw_text(screen, "floor {} ({},{})".format(floor, pl_x, pl_y), 60, 40, fontS, WHITE)
            if welcome > 0:##最高フロア回数を表示
                welcome = welcome - 1
                draw_text(screen, "Welcome to floor {}.".format(floor), 300, 180, font, CYAN)
                
##look## idx 2     $$解明$$ draw.rectの塗りつぶしと解放の配列の動作が不明 
        elif idx == 2: # 階段 画面切り替え
            draw_dungeon(screen, fontS)##ダンジョンを描写
            if 1 <= tmr and tmr <= 5:
                h = 80*tmr
                ##画面サイズ x880 y720 上下から黒で段々に塗る
                pygame.draw.rect(screen, BLACK, [0, 0, 880, h])
                pygame.draw.rect(screen, BLACK, [0, 720-h, 880, h])
                
            if tmr == 5:##全ての画面が塗りつぶされる
                floor = floor + 1
                
                if floor > fl_max:##floormaxが更新されていれば代入
                    fl_max = floor    
                welcome = 15
                make_dungeon()
                put_event()
                
            if 6 <= tmr and tmr <= 9:
                h = 80*(10-tmr)##6 320 7 240 8 160 9 80
                pygame.draw.rect(screen, BLACK, [0, 0, 880, h])
                pygame.draw.rect(screen, BLACK, [0, 720-h, 880, h])
            if tmr == 10:
                idx = 1
##look## idx 3
        elif idx == 3: # アイテム入手もしくはトラップ
            draw_dungeon(screen, fontS)# ダンジョンを描画する
            screen.blit(imgItem[treasure], [320, 220])##move_playerでtreasureを定義
            draw_text(screen, TRE_NAME[treasure], 380, 240, font, WHITE)
            if tmr == 10:
                idx = 1
##look## idx 9
        elif idx == 9: # ゲームオーバー def move_player(key)から tmr=0
            if tmr <= 30:
                PL_TURN = [2, 4, 0, 6]##キャラ 下 左 上 右 の回転
                pl_a = PL_TURN[tmr%4]##PL_TURNを順番に取り出す
                if tmr == 30: pl_a = 8 # 倒れた絵
                draw_dungeon(screen, fontS)##ダンジョンとキャラを描写する
            elif tmr == 31:
                se[3].play()##gemeover効果音とテキスト表示
                draw_text(screen, "You died.", 360, 240, font, RED)
                draw_text(screen, "Game over.", 360, 380, font, RED)
            elif tmr == 100:##idxからリスタート
                idx = 0
                tmr = 0
##look##  idx 10
        elif idx == 10: # 戦闘開始
            if tmr == 1:
                pygame.mixer.music.load("sound/ohd_bgm_battle.ogg")
                pygame.mixer.music.play(-1)
                init_battle()
                init_message()
                
            elif tmr <= 4:##ダンジョン画面から戦闘画面に左から右にスイープ挿入
                bx = (4-tmr)*220
                by = 0
                screen.blit(imgBtlBG, [bx, by])
                draw_text(screen, "Encounter!", 350, 200, font, WHITE)
                
            elif tmr <= 16:
                draw_battle(screen, fontS)
                draw_text(screen, emy_name+" appear!", 300, 200, font, WHITE)##emy_nameはLvまで代入されている
            else:
                idx = 11
                tmr = 0
##look## idx 11
        elif idx == 11: # プレイヤーのターン(入力待ち)
            draw_battle(screen, fontS)
            if tmr == 1: set_message("Your turn.")
            if battle_command(screen, font, key) == True:##battle_comanndの戻り値btl_cmd=数値によりコマンド実行
                if btl_cmd == 0:
                    idx = 12##確認
                    tmr = 0
                if btl_cmd == 1 and potion > 0:
                    idx = 20##確認
                    tmr = 0
                if btl_cmd == 2 and blazegem > 0:
                    idx = 21##確認
                    tmr = 0
                if btl_cmd == 3:
                    idx = 14##確認
                    tmr = 0
##look## idx12
        elif idx == 12: # プレイヤーの攻撃
            draw_battle(screen, fontS)
            
            if tmr == 1:
                set_message("You attack!")
                se[0].play()##効果音 「切る音」
                dmg = pl_str + random.randint(0, 9)##プレイヤーのstrに0~9までの値を加算し攻撃値とする
                
            if 2 <= tmr and tmr <= 4:##剣のエフェクト3回 2 $$460 140$$ 3 $$340 260$$ 4 220 380  
                screen.blit(imgEffect[0], [700-tmr*120, -100+tmr*120])
                
            if tmr == 5:##emy_blinkが5代入されるもemy_step無し 消費され次へ
                emy_blink = 5##敵を明滅させる変数4 2 1 で敵を表示 他 消す
                set_message(str(dmg)+"pts of damage!")
            ##dmgをemy_lifeから引き 敵ライフが0なら勝利 idx16 へ    
            if tmr == 11:
                emy_life = emy_life - dmg
                if emy_life <= 0:
                    emy_life = 0
                    idx = 16
                    tmr = 0
            ##tmr 16 なら idx13 敵のターンへ       
            if tmr == 16:
                idx = 13
                tmr = 0
##look## idx 13
        elif idx == 13: # 敵のターン、敵の攻撃
            draw_battle(screen, fontS)
            
            if tmr == 1:
                set_message("Enemy turn.")
                
            if tmr == 5:
                set_message(emy_name + " attack!")
                se[0].play()##効果音 「切る音」
                emy_step = 30##敵を前に出す変数
                
            if tmr == 9:
                dmg = emy_str + random.randint(0, 9)
                set_message(str(dmg)+"pts of damage!")
                dmg_eff = 5##pyを揺らす変数
                emy_step = 0##emyの位置を戻す変数
                
            if tmr == 15:##pyのライフを計算
                pl_life = pl_life - dmg
                if pl_life < 0:##pyのライフが0以下なら0とし idx15 敗北
                    pl_life = 0
                    idx = 15
                    tmr = 0
            ##pyが生存ならpyのターン
            if tmr == 20:
                idx = 11
                tmr = 0
##
        elif idx == 14: # 逃げられる?
            draw_battle(screen, fontS)
            if tmr == 1: set_message("...")
            if tmr == 2: set_message("......")
            if tmr == 3: set_message(".........")
            if tmr == 4: set_message("............")
            if tmr == 5:
                if random.randint(0, 99) < 60:
                    idx = 22
                else:
                    set_message("You failed to flee.")
            if tmr == 10:
                idx = 13
                tmr = 0
             
        elif idx == 15: # 敗北
            draw_battle(screen, fontS)
            if tmr == 1:
                pygame.mixer.music.stop()
                set_message("You lose.")
            if tmr == 11:
                idx = 9
                tmr = 29

        elif idx == 16: # 勝利
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("You win!")
                pygame.mixer.music.stop()
                se[5].play()
            if tmr == 28:
                idx = 22
                if random.randint(0, emy_lifemax) > random.randint(0, pl_lifemax):
                    idx = 17
                    tmr = 0

        elif idx == 17: # レベルアップ
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("Level up!")
                se[4].play()
                lif_p = random.randint(10, 20)
                str_p = random.randint(5, 10)
            if tmr == 21:
                set_message("Max life + "+str(lif_p))
                pl_lifemax = pl_lifemax + lif_p
            if tmr == 26:
                set_message("Str + "+str(str_p))
                pl_str = pl_str + str_p
            if tmr == 50:
                idx = 22

        elif idx == 20: # Potion
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("Potion!")
                se[2].play()
            if tmr == 6:
                pl_life = pl_lifemax
                potion = potion - 1
            if tmr == 11:
                idx = 13
                tmr = 0

        elif idx == 21: # Blaze gem
            draw_battle(screen, fontS)
            img_rz = pygame.transform.rotozoom(imgEffect[1], 30*tmr, (12-tmr)/8)
            X = 440-img_rz.get_width()/2
            Y = 360-img_rz.get_height()/2
            screen.blit(img_rz, [X, Y])
            if tmr == 1:
                set_message("Blaze gem!")
                se[1].play()
            if tmr == 6:
                blazegem = blazegem - 1
            if tmr == 11:
                dmg = 1000
                idx = 12
                tmr = 4

        elif idx == 22: # 戦闘終了
            pygame.mixer.music.load("sound/ohd_bgm_field.ogg")
            pygame.mixer.music.play(-1)
            idx = 1

        draw_text(screen, "[S]peed "+str(speed), 740, 40, fontS, WHITE)

        pygame.display.update()
        clock.tick(4+2*speed)

if __name__ == '__main__':
    main()
               
    
  

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA