GIF
この記事の目的
会話ができるようにしたいと思います。
図形
この記事ではメッセージの背景を作るために使います。
ここをクリックしてください
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((320, 320))
pygame.display.set_caption('screen only')
while (1):
screen.fill((255, 255, 255))
pygame.draw.rect(screen,(0,0,0),(140,140,40,40))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.draw.rect(screen,(0,0,0),(140,140,40,40))
(0,0,0)色の指定をします。
(140,140,40,40) 座標と大きさです。(横、縦、幅、高さ)
枠
この記事ではテキストウィンドゥの枠のためです。
ここをクリックしてください
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((320, 320))
pygame.display.set_caption('screen only')
while (1):
screen.fill((255, 255, 255))
pygame.draw.rect(screen,(0,0,0),(140,140,40,40),5)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.draw.rect(screen,(0,0,0),(140,140,40,40),5)
最後の5が枠の太さです。
テキスト改行
この記事では使いませんが、長いセリフでは改行が必要になります。
ここをクリックしてください
¥n 環境によっては、\nでテキストを改行できます。
import pygame
pygame.init()
# 画面の設定
screen = pygame.display.set_mode((320, 160))
pygame.display.set_caption("Pygame Text Wrapping Example")
# フォントの設定
#ここにフォントのパスを貼り付ける
font = pygame.font.Font(パス, 20)
# テキストを改行して描画する関数
def draw_text(surface, text, pos, color=(255, 255, 255)):
lines = text.split('\n')
x, y = pos
for line in lines:
text_surface = font.render(line, True, color)
surface.blit(text_surface, (x, y))
y += text_surface.get_height()
# メインループ
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((0, 0, 0))
draw_text(screen, "ここは\nはじまりのむらです", (50, 50))
pygame.display.flip()
pygame.quit()
会話する
会話のためのコードを書いていきます。
ここをクリックしてください
Zキーを押すと会話します。
import pygame
from pygame.locals import *
import sys
GS = 32
DOWN,LEFT,RIGHT,UP = 0,1,2,3
def split_image(image):
"""32x128のキャラクターイメージを32x32の4枚のイメージに分割
分割したイメージを格納したリストを返す"""
imageList = []
for i in range(0, 128, GS):
for j in range(0, 128, GS):
surface = pygame.Surface((GS,GS))
surface.blit(image, (0,0), (j, i,GS,GS))
surface.set_colorkey(surface.get_at((0,0)), RLEACCEL)
surface.convert()
imageList.append(surface)
return imageList
pygame.init()
screen = pygame.display.set_mode((160,200))
pygame.display.set_caption('会話する')
#ここにフォントのパスを貼り付ける
font = pygame.font.Font(パス, 20)
#ここに一人目のパスを貼り付ける
playerImgList = split_image(pygame.image.load(パス))
#ここに二人目のパスを貼り付ける
playerImgList2 = split_image(pygame.image.load(パス))
text_window = False
chara_dict = {(3,2):"girl"}
x2,y2 = 3,2
x,y = 0,0
cx,cy = 0,0
chara_pos = 0
a = 0
direction = DOWN
direction2 = DOWN
animcycle = 24 # アニメーション速度
frame = 0
clock = pygame.time.Clock()
while True:
clock.tick(60)
screen.fill((128,128,128))
# 経過フレーム数に応じて表示する画像を変える
frame += 1
player = playerImgList[int(direction*4+frame/animcycle%4)]
player2 = playerImgList2[int(direction2*4+frame/animcycle%4)]
screen.blit(player, (x*GS, y*GS))
screen.blit(player2, (x2*GS, y2*GS))
if a == 0:
message = "わたし?"
if text_window == True and chara_pos in chara_dict:
text = font.render(message, True, (255,255,255))
pygame.draw.rect(screen, (0, 0, 0), Rect(10, 130, 140, 50))
pygame.draw.rect(screen, (255, 255, 255), Rect(10, 130, 140, 50), 3)
screen.blit(text, (15, 140))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_SPACE:
pygame.quit()
sys.exit()
elif event.key==K_DOWN:
direction = DOWN
y += 1
elif event.key==K_UP:
direction = UP
y -= 1
elif event.key==K_RIGHT:
direction = RIGHT
x += 1
elif event.key==K_LEFT:
direction = LEFT
x -= 1
elif event.key == K_z:
if direction == DOWN:
cx = x
cy = y + 1
elif direction == UP:
cx = x
cy = y - 1
elif direction == RIGHT:
cx = x + 1
cy = y
elif direction == LEFT:
cx = x - 1
cy = y
chara_pos = (cx,cy)
if chara_pos in chara_dict:
text_window = True
if direction == DOWN:
direction2 = UP
if direction == UP:
direction2 = DOWN
if direction == RIGHT:
direction2 = LEFT
if direction == LEFT:
direction2 = RIGHT
if chara_dict[chara_pos] == "girl":
if a == 0:
a += 1
elif a == 1:
message = "うん"
a = 2
elif a == 2:
message = "一緒に行く"
a = 3
elif a == 3:
text_window = False
a = 0
text_window = False
最初からテキストウィンドウがあると変なので消しておきます。
chara_dict = {(3,2):"girl"}
座標をキーに指定して、キャラクター名を取り出すための辞書です。
x2,y2 = 3,2
二人目のキャラクターの座標です。
x,y = 0,0
プレイヤーの座礁です。
cx,cy = 0,0
プレイヤーの隣の座標を入れるための変数です。
chara_pos = 0
cxとcyをまとめて、()に入れるための変数です。
a = 0
セリフを変更するための変数です。
direction = DOWN
プレイヤーの最初の向きです。
direction2 = DOWN
二人目のキャラクターの最初の向きです。
if a == 0:
message = "わたし?"
これがないと二回目以降に最初のセリフが出てきません。
elif event.key == K_z:
if direction == DOWN:
cx = x
cy = y + 1
elif direction == UP:
cx = x
cy = y - 1
elif direction == RIGHT:
cx = x + 1
cy = y
elif direction == LEFT:
cx = x - 1
cy = y
隣の座標をcxとcyに入れています。
chara_pos = (cx,cy)
cxとcyを一つにしています。
if chara_pos in chara_dict:
辞書の中に隣の座標が存在するか調べてます。
これがないと辞書にないキー(隣の座標)を指定したときにエラーが出ます。
text_window = True
テキストウィンドウを表示します。
if direction == DOWN:
direction2 = UP
if direction == UP:
direction2 = DOWN
if direction == RIGHT:
direction2 = LEFT
if direction == LEFT:
direction2 = RIGHT
二人目のキャラクターの向きを変えます。
if chara_dict[chara_pos] == "girl":
辞書にないキー(隣の座標)を指定するとここでエラーが出ます。
ゲームの画面ではキャラクターがいないところでZキーを押すとエラーが出ます。
細かい修正
辞書のキーには文字列以外も指定できるということで、キーを文字列から変更しました。f文字列を使う必要がなくなりました。
宝箱を開ける
会話するのとあまり変わらないのでここに書きました。
ここをクリックしてください
宝箱の画像はこのサイトからお借りするとよいです。
ぴぽや倉庫 ここからダウンロード
キャラチップ+.zipをダウンロードしましょう。
import pygame
from pygame.locals import *
import sys
GS = 32
DOWN,LEFT,RIGHT,UP = 0,1,2,3
def split_image(image):
"""32x128のキャラクターイメージを32x32の4枚のイメージに分割
分割したイメージを格納したリストを返す"""
imageList = []
for i in range(0, 128, GS):
for j in range(0, 128, GS):
surface = pygame.Surface((GS,GS))
surface.blit(image, (0,0), (j, i,GS,GS))
surface.set_colorkey(surface.get_at((0,0)), RLEACCEL)
surface.convert()
imageList.append(surface)
return imageList
pygame.init()
screen = pygame.display.set_mode((160,200))
pygame.display.set_caption('宝箱')
chara_dict = {"2,1":"treasure"}
#ここにキャラクターのパスを貼り付ける
playerImgList = split_image(pygame.image.load(パス))
#ここに宝箱のパスを貼り付ける
treasure = pygame.image.load(パス)
x2,y2 = 2,1
x,y = 2,4
cx,cy = 0,0
chara_pos = 0
a = (64,0,GS,GS)
direction = DOWN
animcycle = 24 # アニメーション速度
frame = 0
clock = pygame.time.Clock()
while True:
clock.tick(60)
screen.fill((0,0,0))
# 経過フレーム数に応じて表示する画像を変える
frame += 1
player = playerImgList[int(direction*4+frame/animcycle%4)]
screen.blit(player, (x*GS, y*GS))
screen.blit(treasure,(x2*GS,y2*GS), a)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_SPACE:
pygame.quit()
sys.exit()
elif event.key==K_DOWN:
direction = DOWN
y += 1
elif event.key==K_UP:
direction = UP
y -= 1
elif event.key==K_RIGHT:
direction = RIGHT
x += 1
elif event.key==K_LEFT:
direction = LEFT
x -= 1
elif event.key == K_z:
if direction == DOWN:
cx = x
cy = y + 1
elif direction == UP:
cx = x
cy = y - 1
elif direction == RIGHT:
cx = x + 1
cy = y
elif direction == LEFT:
cx = x - 1
cy = y
chara_pos = f"{cx},{cy}"
if chara_pos in chara_dict:
print(cx,cy)
if chara_dict[chara_pos] == "treasure":
a = (64,64,GS,GS)
screen.blit(treasure,(x2*GS,y2*GS), a)
a = (64,0,GS,GS)からa = (64,64,GS,GS)に変更してます。
(画像の横座標、画像の縦座標、横サイズ、縦サイズ)
宿屋
ここをクリックしてください
矢印キーで移動して、左クリックで話しかけます。
はい、いいえを選ぶのもセリフを進めるのも左クリックです。
必要なもの
- フォントファイル
- プレイヤー画像
- 宿屋のキャラクター画像
- BGMのファイル
- ボタンの音のファイル
- 泊まった時のメロディのファイル
以下のサイトからダウンロードできます。
一般社団法人文字情報技術促進協議会(ここから、フォントファイルをダウンロード)
キャラクター画像
ピ!(ボタンの音)
ほのぼの01(泊まった時のメロディ)
BGM(ひとやすみ)
BGM(石畳の下で)
FileNotFoundError
というエラーが出たら、パスの前に r(アール) をつけましょう。r"パス"
import pygame
from pygame.locals import *
import sys
import time
GS = 32
DOWN,LEFT,RIGHT,UP = 0,1,2,3
Gold = 300
def split_image(image):
"""32x128のキャラクターイメージを32x32の4枚のイメージに分割
分割したイメージを格納したリストを返す"""
imageList = []
for i in range(0, 128, GS):
for j in range(0, 128, GS):
surface = pygame.Surface((GS,GS))
surface.blit(image, (0,0), (j, i,GS,GS))
surface.set_colorkey(surface.get_at((0,0)), RLEACCEL)
surface.convert()
imageList.append(surface)
return imageList
# テキストを改行して描画する関数
def draw_text(surface, message, pos, font, color=(255, 255, 255)):
lines = message.split('\n')
x, y = pos
for line in lines:
text_surface = font.render(line, True, color)
surface.blit(text_surface, (x, y))
y += text_surface.get_height()
pygame.init()
screen = pygame.display.set_mode((320,250))
pygame.display.set_caption('宿屋')
text_window = False
chara_dict = {"3,0":"girl"}
#ここにフォントのパスを貼り付ける
font = pygame.font.Font(パス, 20)
# プレイヤーの画像のパスを貼り付ける
playerImgList = split_image(pygame.image.load(パス))
# 宿屋のキャラクター画像のパスを貼り付ける
playerImgList2 = split_image(pygame.image.load(パス))
# BGMのパスを貼り付ける
pygame.mixer.music.load(パス)
pygame.mixer.music.play(-1)
# ボタンの音のパスを貼り付ける
sound = pygame.mixer.Sound(パス)
# 泊まった時のメロディのパスを貼り付ける
sound2 = pygame.mixer.Sound(パス)
x2,y2 = 3,0
x,y = 3,2
mx,my = 0,0
cx,cy = 0,0
chara_pos = 0
a = 0
choose = 0
shop = 0
direction = DOWN
direction2 = DOWN
animcycle = 24
frame = 0
action_number44 = 0
action_number45 = 0
Max_HP = 80
player_HP = 10
change = 0
inn_melody = 0
clock = pygame.time.Clock()
walking = False
# 半透明のSurfaceを作成
# はい、いいえ
transparent_surface3 = pygame.Surface((70, 20), pygame.SRCALPHA)
# RGBA (白, 透明度128)
transparent_surface3.fill((255, 255, 255, 128))
# 半透明のSurfaceを作成
transparent_surface = pygame.Surface((320, 250), pygame.SRCALPHA)
transparent_surface.fill((0, 0, 0, change))
while True:
clock.tick(60)
screen.fill((128,128,128))
# 経過フレーム数に応じて表示する画像を変える
frame += 1
player = playerImgList[int(direction*4+frame/animcycle%4)]
player2 = playerImgList2[int(direction2*4+frame/animcycle%4)]
screen.blit(player, (x*GS, y*GS))
screen.blit(player2, (x2*GS, y2*GS))
#"はい"と"いいえ"の枠
if choose == 1:
pygame.draw.rect(screen, (0, 0, 0), Rect(250, 5, 70, 55))
pygame.draw.rect(screen, (255, 255, 255), Rect(250, 5, 70, 55), 3)
if mx >= 258 and mx <= 298:
if my >= 10 and my <= 30:
screen.blit(transparent_surface3, (258, 10))
action_number44 = 1
else:
action_number44 = 0
if my >=34 and my <= 54:
screen.blit(transparent_surface3, (258, 34))
action_number45 = 1
else:
action_number45 = 0
else:
action_number44 = 0
action_number45 = 0
text = font.render("はい", True, (255,255,255))
screen.blit(text, (258, 10))
text1 = font.render("いいえ", True, (255,255,255))
screen.blit(text1, (258, 33))
if a == 0:
message = "ここはやどやです。\n5ゴールドに なりますが?"
if text_window == True:
pygame.draw.rect(screen, (0, 0, 0), Rect(10, 130, 270, 80))
pygame.draw.rect(screen, (255, 255, 255), Rect(10, 130, 270, 80), 3)
draw_text(screen , message, (18,135), font)
if shop == 1 and a == 3 or a == 4:
if change < 255 and a == 3:
if inn_melody == 0:
pygame.mixer.music.pause()
sound2.play()
inn_melody = 1
change += 2
time.sleep(0.01)
if change >= 243:
change = 255
if change == 255:
a = 4
elif change > 0 and a == 4:
change -= 2
time.sleep(0.01)
message = "またおこしくださいませ"
if change == 1:
change = 0
if change == 0:
a = 5
transparent_surface.fill((0, 0, 0, change))
#透明のSurfaceを描画
screen.blit(transparent_surface, (0, 0))
if change == 0 and a == 5:
player_HP = Max_HP
choose = 0
a = 7
pygame.display.update()
for event in pygame.event.get():
mouse_pressed = pygame.mouse.get_pressed()
mouse_pos = pygame.mouse.get_pos()
mx = mouse_pos[0]
my = mouse_pos[1]
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif mouse_pressed[0]:
if shop == 0:
if direction == DOWN:
cx = x
cy = y + 1
elif direction == UP:
cx = x
cy = y - 1
elif direction == RIGHT:
cx = x + 1
cy = y
elif direction == LEFT:
cx = x - 1
cy = y
chara_pos = f"{cx},{cy}"
if chara_pos in chara_dict:
text_window = True
if direction == DOWN:
direction2 = UP
elif direction == UP:
direction2 = DOWN
elif direction == RIGHT:
direction2 = LEFT
elif direction == LEFT:
direction2 = RIGHT
if chara_dict[chara_pos] == "girl":
shop = 1
choose = 1
#宿屋
elif shop == 1:
if choose == 1 and a == 0:
a = 1
# はい お金ある
elif action_number44 == 1 and a == 1 and Gold >= 5:
sound.play()
message = "ごゆっくり どうぞ"
a = 2
choose = 0
Gold -= 5
elif shop == 1 and a == 2:
a = 3
# はい お金ない
elif action_number44 == 1 and a == 1 and Gold <= 5:
message = "お金が足りません"
sound.play()
a = 6
choose = 0
# いいえ 閉じる
elif action_number45 == 1 and a == 1:
sound.play()
text_window = False
choose = 0
a = 0
shop = 0
# またおこし
elif a == 7:
pygame.mixer.music.unpause()
message = "またおこしくださいませ"
a = 8
time.sleep(0.3)
# おかねがある 閉じる
elif a == 8:
sound.play()
a = 0
text_window = False
shop = 0
inn_melody = 0
# お金がない 閉じる
elif a == 6:
sound.play()
a = 0
text_window = False
shop = 0
elif event.type == KEYDOWN:
if event.key==K_DOWN:
direction = DOWN
y += 1
elif event.key==K_UP:
direction = UP
y -= 1
elif event.key==K_RIGHT:
direction = RIGHT
x += 1
elif event.key==K_LEFT:
direction = LEFT
x -= 1