import tkinter
# 解読関数
def decode_line(event):
global current_line, bgimg, lcharimg, ccharimg, rcharimg
if current_line >= len(scenario):
return;
# 1行読み込み
line = scenario[current_line]
current_line = current_line + 1
line = line.replace("\\n", "\n").strip()
params = line.split(" ")
# 分岐
if line[0] != "#":
message["text"] = line
return
elif params[0] == "#back":
canvas.delete("all")
bgimg = tkinter.PhotoImage(file=params[1])
canvas.create_image(450, 230, image=bgimg)
elif params[0] == "#putChar":
if params[2] == "L":
canvas.delete("left")
lcharimg = tkinter.PhotoImage(file=params[1])
canvas.create_image(200, 160, image=lcharimg, tag="left")
elif params[2] == "R":
canvas.delete("right")
rcharimg = tkinter.PhotoImage(file=params[1])
canvas.create_image(700, 160, image=rcharimg, tag="right")
else:
canvas.delete("center")
ccharimg = tkinter.PhotoImage(file=params[1])
canvas.create_image(450, 160, image=ccharimg, tag="center")
elif params[0] == "#branch":
message.unbind("<Button-1>")
btn = tkinter.Button(text=params[2], width=20)
branch.append(btn)
btn["command"] = lambda : jump_to_line(int(params[1])-1)
btn.place(x=300, y=60+int(params[1])*60)
jumplabel.append(params[3])
if params[4] == "n":
return
elif params[0] == "#jump":
label = params[1].strip()
# ジャンプ先を探す
for l in range(len(scenario)):
if scenario[l].strip() == "## " + label:
current_line = l
decode_line(None)
return
elif params[0].strip() == "#end":
message["text"] = "終わり"
message.unbind("<Button-1>")
current_line = 999999999
# 再帰呼び出し
decode_line(None)
# ジャンプ関数
def jump_to_line(branchID):
global current_line
# ボタンを消す
for btn in branch:
btn.place_forget()
btn.destroy()
branch.clear()
label = jumplabel[branchID]
jumplabel.clear()
message.bind("<Button-1>", decode_line)
# ジャンプ先を探す
for l in range(len(scenario)):
if scenario[l].strip() == "## " + label:
current_line = l
decode_line(None)
return
# ウィンドウ作成
root = tkinter.Tk()
root.title("よろしくアドベンチャー")
root.minsize(900, 460)
root.option_add("*font", ["メイリオ", 14])
# キャンバス作成
canvas = tkinter.Canvas(width=900, height=460)
canvas.place(x=0, y=0)
# メッセージエリア
message = tkinter.Label(width=70, height=5, wraplength=840,
bg="white", justify="left", anchor="nw")
message.place(x=28, y=284)
message["text"] = "クリックしてスタート"
# ファイル読み込み
scenario = []
file = open("img8/scenario.txt", "r", encoding="utf-8")
while True:
line = file.readline()
scenario.append(line)
if not line:
file.close()
break
# 現在の行数
current_line = 0
# イベント設定
message.bind("<Button-1>", decode_line)
# 画像
bgimg = None
lcharimg = None
ccharimg = None
rcharimg = None
# 選択肢
branch = []
jumplabel = []
root.mainloop()
カテゴリー: Python
mine_sweeper.py
[python]
""" mine_sweeper.py – Copyright 2016 Kenichiro Tanaka """
import sys
from math import floor
from random import randint
import pygame
from pygame.locals import QUIT, MOUSEBUTTONDOWN
WIDTH = 20
HEIGHT = 15
SIZE = 50
NUM_OF_BOMBS = 20
EMPTY = 0
BOMB = 1
OPENED = 2
OPEN_COUNT = 0
CHECKED = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)]
pygame.init()
SURFACE = pygame.display.set_mode([WIDTH*SIZE, HEIGHT*SIZE])
FPSCLOCK = pygame.time.Clock()
def num_of_bomb(field, x_pos, y_pos):
""" 周囲にある爆弾の数を返す """
count = 0
for yoffset in range(-1, 2):
for xoffset in range(-1, 2):
xpos, ypos = (x_pos + xoffset, y_pos + yoffset)
if 0 <= xpos < WIDTH and 0 <= ypos < HEIGHT and \
field[ypos][xpos] == BOMB:
count += 1
return count
def open_tile(field, x_pos, y_pos):
""" タイルをオープン """
global OPEN_COUNT
if CHECKED[y_pos][x_pos]: # 既にチェック済みのタイル
return
CHECKED[y_pos][x_pos] = True
for yoffset in range(-1, 2):
for xoffset in range(-1, 2):
xpos, ypos = (x_pos + xoffset, y_pos + yoffset)
if 0 <= xpos < WIDTH and 0 <= ypos < HEIGHT and \
field[ypos][xpos] == EMPTY:
field[ypos][xpos] = OPENED
OPEN_COUNT += 1
count = num_of_bomb(field, xpos, ypos)
if count == 0 and \
not (xpos == x_pos and ypos == y_pos):
open_tile(field, xpos, ypos)
def main():
""" メインルーチン """
smallfont = pygame.font.SysFont(None, 36)
largefont = pygame.font.SysFont(None, 72)
message_clear = largefont.render("!!CLEARED!!",
True, (0, 255, 225))
message_over = largefont.render("GAME OVER!!",
True, (0, 255, 225))
message_rect = message_clear.get_rect()
message_rect.center = (WIDTH*SIZE/2, HEIGHT*SIZE/2)
game_over = False
field = [[EMPTY for xpos in range(WIDTH)]
for ypos in range(HEIGHT)]
# 爆弾を設置
count = 0
while count < NUM_OF_BOMBS:
xpos, ypos = randint(0, WIDTH-1), randint(0, HEIGHT-1)
if field[ypos][xpos] == EMPTY:
field[ypos][xpos] = BOMB
count += 1
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN and \
event.button == 1:
xpos, ypos = floor(event.pos[0] / SIZE),\
floor(event.pos[1] / SIZE)
if field[ypos][xpos] == BOMB:
game_over = True
else:
open_tile(field, xpos, ypos)
# 描画
SURFACE.fill((0, 0, 0))
for ypos in range(HEIGHT):
for xpos in range(WIDTH):
tile = field[ypos][xpos]
rect = (xpos*SIZE, ypos*SIZE, SIZE, SIZE)
if tile == EMPTY or tile == BOMB:
pygame.draw.rect(SURFACE,
(192, 192, 192), rect)
if game_over and tile == BOMB:
pygame.draw.ellipse(SURFACE,
(225, 225, 0), rect)
elif tile == OPENED:
count = num_of_bomb(field, xpos, ypos)
if count > 0:
num_image = smallfont.render(
"{}".format(count), True, (255, 255, 0))
SURFACE.blit(num_image,
(xpos*SIZE+10, ypos*SIZE+10))
# 線の描画
for index in range(0, WIDTH*SIZE, SIZE):
pygame.draw.line(SURFACE, (96, 96, 96),
(index, 0), (index, HEIGHT*SIZE))
for index in range(0, HEIGHT*SIZE, SIZE):
pygame.draw.line(SURFACE, (96, 96, 96),
(0, index), (WIDTH*SIZE, index))
# メッセージの描画
if OPEN_COUNT == WIDTH*HEIGHT – NUM_OF_BOMBS:
SURFACE.blit(message_clear, message_rect.topleft)
elif game_over:
SURFACE.blit(message_over, message_rect.topleft)
pygame.display.update()
FPSCLOCK.tick(15)
if __name__ == ‘__main__’:
main()
[/python]
[python]
""" cave – Copyright 2016 Kenichiro Tanaka """
import sys
from random import randint
import pygame
from pygame.locals import QUIT, Rect, KEYDOWN, K_SPACE
pygame.init()
pygame.key.set_repeat(5, 5)
SURFACE = pygame.display.set_mode((800, 600))
FPSCLOCK = pygame.time.Clock()
def main():
""" メインルーチン """
walls = 80
ship_y = 250
velocity = 0
score = 0
slope = randint(1, 6)
sysfont = pygame.font.SysFont(None, 36)
ship_image = pygame.image.load("ship.png")
bang_image = pygame.image.load("bang.png")
holes = []
for xpos in range(walls):
holes.append(Rect(xpos * 10, 100, 10, 400))
game_over = False
while True:
is_space_down = False
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_SPACE:
is_space_down = True
# 自機を移動
if not game_over:
score += 10
velocity += -3 if is_space_down else 3
ship_y += velocity
# 洞窟をスクロール
edge = holes[-1].copy()
test = edge.move(0, slope)
if test.top <= 0 or test.bottom >= 600:
slope = randint(1, 6) * (-1 if slope > 0 else 1)
edge.inflate_ip(0, -20)
edge.move_ip(10, slope)
holes.append(edge)
del holes[0]
holes = [x.move(-10, 0) for x in holes]
# 衝突 ?
if holes[0].top > ship_y or \
holes[0].bottom < ship_y + 80:
game_over = True
# 描画
SURFACE.fill((0, 255, 0))
for hole in holes:
pygame.draw.rect(SURFACE, (0, 0, 0), hole)
SURFACE.blit(ship_image, (0, ship_y))
score_image = sysfont.render("score is {}".format(score),
True, (0, 0, 225))
SURFACE.blit(score_image, (600, 20))
if game_over:
SURFACE.blit(bang_image, (0, ship_y-40))
pygame.display.update()
FPSCLOCK.tick(15)
if __name__ == ‘__main__’:
main()
[/python]
[python]
""" draw_image_onkeydown.py """
import sys
import pygame
from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_UP, K_DOWN
pygame.init()
pygame.key.set_repeat(5, 5)
SURFACE = pygame.display.set_mode((400, 300))
FPSCLOCK = pygame.time.Clock()
def main():
""" main routine """
logo = pygame.image.load("pythonlogo.jpg")
pos = [200, 150]
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_LEFT:
pos[0] -= 5
elif event.key == K_RIGHT:
pos[0] += 5
elif event.key == K_UP:
pos[1] -= 5
elif event.key == K_DOWN:
pos[1] += 5
pos[0] = pos[0] % 400
pos[1] = pos[1] % 300
SURFACE.fill((225, 225, 225))
rect = logo.get_rect()
rect.center = pos
SURFACE.blit(logo, rect)
pygame.display.update()
FPSCLOCK.tick(30)
if __name__ == ‘__main__’:
main()
[/python]
[python]
""" draw_rect1.py """
import sys
import pygame
from pygame.locals import Rect
from pygame.locals import QUIT
pygame.init()
SURFACE = pygame.display.set_mode((400, 300))
FPSCLOCK = pygame.time.Clock()
def main():
""" main routine """
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
SURFACE.fill((255, 255, 255))
# 赤:矩形(塗りつぶし)
pygame.draw.rect(SURFACE, (255, 0, 0), (10, 20, 100, 50))
# 赤:矩形(太さ3)
pygame.draw.rect(SURFACE, (255, 0, 0), (150, 10, 100, 30), 3)
# 緑:矩形
pygame.draw.rect(SURFACE, (0, 255, 0), ((100, 80), (80, 50)))
# 青:矩形、Rectオブジェクト
rect0 = Rect(200, 60, 140, 80)
pygame.draw.rect(SURFACE, (0, 0, 255), rect0)
# 黄:矩形、Rectオブジェクト
rect1 = Rect((30, 160), (100, 50))
pygame.draw.rect(SURFACE, (255, 255, 0), rect1)
pygame.display.update()
FPSCLOCK.tick(3)
if __name__ == ‘__main__’:
main()
[/python]
draw_image4.py
[python]
#""" draw_image4.py """
import sys
import pygame
from pygame.locals import QUIT
pygame.init()
SURFACE = pygame.display.set_mode((400, 300))
FPSCLOCK = pygame.time.Clock()
def main():
""" main routine """
logo = pygame.image.load("pythonlogo.jpg")
theta = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
theta += 1
SURFACE.fill((225, 225, 225))
# ロゴを回転し、中心が(200, 150)の位置にロゴを描画
new_logo = pygame.transform.rotate(logo, theta)
rect = new_logo.get_rect()
rect.center = (200, 150)
SURFACE.blit(new_logo, rect)
pygame.display.update()
FPSCLOCK.tick(30)
if __name__ == ‘__main__’:
main()
[/python]
どうも少しおかしいようです。最初と最後にpreが付いてますが、これはいらないです。