この記事は、岩手県八幡平市のプログラミング教室「アクセルキャンプ」の公開教材です。
アクセルキャンプ(フリースペースプラウド)のリンク
教材の作成依頼等も承っております。ご意見等は、リンク先の問い合わせ欄からお願いします。
教材の転用・利用等は自由です
寒っ(半ギレ)
季節の変わり目っていうか、すでに冬な気がしてます。ハワイでは一年中夏で海で泳げますが、やっぱりこの時期は結構寒いです。でもTシャツで過ごせるので、東北とは全く違いますけどね。
もうちょっとすると手がかじかんでコード書くのも辛い時期になってきます。。。
それでは今日もゴリゴリコードを書いていきましょう!!
今日の目標
こんな感じで、簡単なバトル画面のメニュー表示を作っていきます。今選択しているものを黄色で表示し、なにかのキーを押すと、矢印と一緒に移動します。前回まで習ったことがでほとんどの部分をカバーできる人は、自信あるニキはちょっとやってみてから、以下の説明を読むのも、いいと思います。
前回のまでのスクリプト
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() # Pygameの初期化
screen = pygame.display.set_mode((800,600)) # 400 x 300の大きさの画面を作る
pygame.display.set_caption("いけめんがつくったげえむ") # 画面上部に表示するタイトルを設定
rect_x = 20 #長方形左上のx座標
rect_y = 400 #長方形左上のx座標
rect_width = 800 - (rect_x * 2) #長方形の幅
rect_height = 600 - (rect_y + 20) #長方形の高さ
slyme_image = pygame.image.load("image/slyme.png")
font = pygame.font.Font("font/DragonQuestFC.ttf", 30)
while (1):
screen.fill((0,0,0)) # 画面を黒色に塗りつぶし
screen.blit(slyme_image, (400 - (400 / 2), 0))
pygame.draw.rect(screen,(255, 255, 255), Rect(rect_x, rect_y, rect_width, rect_height), 10)
text = font.render("りっきーが あらわれた!", True, (255, 255, 255))
screen.blit(text, (40, 420))
pygame.display.update() # 画面を更新
# イベント処理
for event in pygame.event.get():
if event.type == QUIT: # 閉じるボタンが押されたら終了
pygame.quit() # Pygameの終了(画面閉じられる)
sys.exit()
if __name__ == "__main__":
main()
こんな感じでスライムリッキーを表示しました。前回までの主な内容は
・四角を表示する
・スライムの画像を表示する
。文字を画像に変換して表示する
といった感じでした。ここらへんのことを応用して、「たたかう」「じゅもん」「にげる」の選択肢を作っていきます。
そしてそれができたら、まず選択肢の色を変えます。そのときに、選択肢の左側に矢印を表示させるのですが、この仕組み、多分皆さんが考えて いるよりも単純です。早速やってみましょう。
まずは選択肢の配置から
この部分は先週の復習なので、さらっと行きます。文字を表示するときは、
①文字のフォントの設定(フォントの種類と文字の大きさ)
②フォントに(表示したい文字列)(アンチエイリアス=true)(文字の色)を与えて、文字を画像データとして扱えるようにする
③変換した文字の表示
の3ステップを踏みます。それぞれ
font = font.Font("使いたいフォント", フォントの大きさ)
text = font.render("表示したい文字列". true, 色)
screen.blit(text, (表示位置の座標))
みたいな感じです(変数名は実際のコードに合わせてありますが、自由です)
それでは、3つの文字列(たたかう、じゅもん、にげる)を表示してみましょう。
while (1):
screen.fill((0,0,0)) # 画面を黒色に塗りつぶし
screen.blit(slyme_image, (400 - (400 / 2), 0))
pygame.draw.rect(screen,(255, 255, 255), Rect(rect_x, rect_y, rect_width, rect_height), 10)
text = font.render("りっきーが あらわれた!", True, (255, 255, 255))
#選択肢を画像として格納
battle_text = font.render("たたかう", True, color0)
spell_text = font.render("じゅもん", True, color1)
run_text = font.render("にげる", True, color2)
screen.blit(text, (40, 420))
# 表示
screen.blit(battle_text, (45, 450))
screen.blit(spell_text, (45, 480))
screen.blit(run_text, (45, 510))
pygame.display.update() # 画面を更新
# イベント処理
for event in pygame.event.get():
if event.type == QUIT: # 閉じるボタンが押されたら終了
pygame.quit() # Pygameの終了(画面閉じられる)
sys.exit()
しれっと、色の変数(yellow, white)を追加しているの、気づきました?そう、選択されている文字だけ黄色で表示する予定です。とりあえず、デフォルトとして、「たたかう」を黄色くしちゃいましょう
color0 = yellow
選択している文字を黄色にする
では、下キーを押して、選択したいものを黄色くなるようにしてみましょう。
選択肢を変更するには、キーを押す、マウスをクリックするなど、それを引き起こすためのトリガーとなる「イベント」が必要になります。コードの下のほうに、「イベント処理」とあるので、その辺に書き足していけば行けそうな感じですね。
QUITという、Xボタンが押されたときのイベント処理が書いてあるので、その下に処理を追加してみましょう。キーが押されたときのイベントの種類(タイプ=type)は、KEYDOWNとなります。
elif event.type = KEYDOWN:
#押されたときの処理
では、この処理はどのように書いていけばいいでしょう。今回は、action_numberという変数を用いて、黄色く表示する選択肢を決定する仕組みにします。まず、numberに0を代入します。
selected_action = 0
そして、キーが押されたとき、selected_actionに1を足します。もしselected_numberが2であったときは、選択肢は3つしかないので、0に戻します。
elif event.type == KEYDOWN:
if acrion_number == 2:
acrion_number = 0
else:
acrion_number += 1
それでは、選択肢番号の処理ができそうなので、それにあわせて選択肢の色を変えて行きましょう。ここで、ちょっとしたテクニックを教えます。
if文を使って、選択肢の色(color0, color1, color2)を変える処理は、こんな感じで思い浮かべる人がおおいのでは?
if acrion_number == 0:
color0 = yellow
color1 = white
color2 = white
if acrion_number == 1:
color0 = white
color1 = yellow
color2 = white
if acrion_number == 2:
color0 = white
color1 = white
color2 = yellow
いいですね!では実行してみましょう。
できた!よし!きょうの勉強おわり!
ってなってもいいのですが、ちょっとまってください。このコード、めちゃくちゃ無駄が多いんですよね!特に3つのcolor変数の扱いがひどい!ので、リファクタリングしましょう。複数のデータを扱うときは、リストを使うのが便利です。リストの使い方を忘れちゃった人は、ここで復習してみてください。
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() # Pygameの初期化
screen = pygame.display.set_mode((800, 600)) # 400 x 300の大きさの画面を作る
pygame.display.set_caption("いけめんがつくったげえむ") # 画面上部に表示するタイトルを設定
rect_x = 20 # 長方形左上のx座標
rect_y = 400 # 長方形左上のx座標
rect_width = 800 - (rect_x * 2) # 長方形の幅
rect_height = 600 - (rect_y + 20) # 長方形の高さ
slyme_image = pygame.image.load("image/slyme.png")
font = pygame.font.Font("font/DragonQuestFC.ttf", 30)
action_number = 0 # 選択肢の番号
white = (255, 255, 255)
yellow = (255, 255, 0)
"""
メインループ内で決めればいいので、削除
color0 = white
color1 = white
color2 = white
"""
while (1):
"""
一度全部白にしてから、指定の部分だけ黄色にする
"""
colors = [white, white, white]
colors[action_number] = yellow
screen.fill((0, 0, 0)) # 画面を黒色に塗りつぶし
screen.blit(slyme_image, (400 - (400 / 2), 0))
pygame.draw.rect(screen, (255, 255, 255), Rect(rect_x, rect_y, rect_width, rect_height), 10)
text = font.render("りっきーが あらわれた!", True, (255, 255, 255))
"""
colorsリストから、それぞれの文字の色を取得する
"""
battle_text = font.render("たたかう", True, colors[0])
spell_text = font.render("じゅもん", True, colors[1])
run_text = font.render("にげる", True, colors[2])
screen.blit(text, (40, 420))
screen.blit(battle_text, (45, 450))
screen.blit(spell_text, (45, 480))
screen.blit(run_text, (45, 510))
pygame.display.update() # 画面を更新
# イベント処理
for event in pygame.event.get():
if event.type == QUIT: # 閉じるボタンが押されたら終了
pygame.quit() # Pygameの終了(画面閉じられる)
sys.exit()
elif event.type == KEYDOWN:
if action_number == 2:
action_number = 0
else:
action_number += 1
if __name__ == "__main__":
main()
ひさびさの しゅくだい!
①上のコードでは、どのキーを押しても選択肢が下に移動します。上矢印を打てば上、下矢印を打てば下に移動するようにするには、どうしたらいいでしょうか。
②一番最初の画像のように、矢印をつけるにはどうしたらいいでしょう?考えてみよう
③上のコードは、一度リファクタリングをしましたが、まだまだキレイなコードとは言えない部分が実はあります。自分で考えて、「ここもっとこうしたほうがよくね?」みたいなところを探して、リファクタリングしてみましょう。
例1)action_numberていう変数名なんかダサくね?
例2)screen.blitのところ、繰り返しとか使ったほうがいんじゃね?
などなど
では、また来週!