FIT2-2024b 第06回 オブジェクト
アナウンス
12/18(水) 中間 1発表、01/22(水) 最終発表は必ず出席を!
中間発表は翌週が予備日、NGの方を集めて12/25を予備日として別途開催
前回授業の復習
先週の成果物のミソ
①ボールを3個に増やす
https://gyazo.com/e0c44ebbd093e62404940fe0a33aa6d0
②ゲームオーバーを管理する
https://gyazo.com/1a6c598daa6419dedea97a633afcece8
①ボールを3個に増やす = 「リスト」の利用
code:python
import pyxel
pyxel.init(200, 200)
def update():
for i in range(0, len(ballx)):
# 全てのボールを毎フレーム右下に向けて動かす
def draw():
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 0) pyxel.text(ballxi, ballyi, str(i), 7) pyxel.run(update, draw)
②ゲームオーバーを管理する
code:python
# 新しい変数を2つ用意する
failed = 0
gameover = False
def update():
global ballx, bally ...(中略)... failed, gameover
# (中略)
if gameover:
if pyxel.btnp(pyxel.KEY_SPACE):
gameover = False
failed = 0
return
for i in range(0, len(ballx)):
# (中略)
# ボールがキャッチできずに画面下端に来た時にmissを1増やす
failed = failed + 1
if failed >= 10:
# failedが10以上になったら isGameoverをTrueに変更
gameover = True
# (中略)
def draw():
if gameover:
# ゲームオーバー時の描画
pyxel.text(50, 100, 'GAME OVER', 0)
else:
# 通常のゲーム画面描画はisGameoverがTrueになると以後実行されない
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 6) # 中略
最終形
code:python
import pyxel
pyxel.init(200, 200)
speed = 1 # 速度の係数
score = 0 # 点数
miss = 0 # 失敗した回数を記録する変数
success = 0 # キャッチに成功した回数を記録する変数
gameover = False # ゲームオーバーかどうかを記録する変数
padx = 100
def update():
global ballx, bally, vx, vy, padx, speed, score, miss, gameover, success
if gameover:
# 処理を何もせずupdateをここで処理中断する
# ゲームオーバー後は内部処理が止まるように
return
# padの座標更新は1回で良いのでfor文の外
padx = pyxel.mouse_x
# ボールの数だけ以下処理を回す
for i in range(0, len(ballx)):
# ボールのy座標が195 (padの上端)より下にいる
# なおかつ、ボールのx座標がpadの左端(padx-20)と右端(padx+20)の間にある場合に
if ballyi >= 195 and padx - 20 <= ballxi <= padx + 20: # 点数を100増やす
score = score + 100
success = success + 1
if success >= 10:
# ボールを増やす
ballx.append(pyxel.rndi(0, 199))
bally.append(0)
angle.append(pyxel.rndi(30, 150))
vx.append(pyxel.cos(angle-1)) # -1は最後から1番目の要素を指す vy.append(pyxel.sin(angle-1)) # スピードをもとに戻す
speed = 1
# successも0に戻す
success = 0
# 接触後、ボールを上に戻してあげないと、そのまま進み続けて連続ヒットしてしまう
ballxi = pyxel.rndi(0, 199) speed = speed + 0.5 # スピードを少し早くする
if ballyi >= 200: # ボールが下端まで来たら # 失敗カウントを増やす
miss = miss + 1
if miss >= 10:
gameover = True
ballxi = pyxel.rndi(0, 199) speed = speed + 0.5 # スピードを少し早くする
if ballxi >= 200: # ボールが右端まで来たら if ballxi <= 0: # ボールが左端まで来たら def draw():
global ballx, bally, vx, vy, padx, score, miss, gameover, success
if gameover:# ゲームオーバーだったら…
# pyxel.cls(7) をあえて実行しないことで、前回処理時の画面をそのまま表示する
pyxel.text(50, 100, "GAME OVER", 0)
pyxel.cls(7)
for i in range(0, len(ballx)):
pyxel.circ(ballxi, ballyi, 10, 6) pyxel.rect(padx-20, 195, 40, 5, 14)
pyxel.text(0, 0, str(score), 0)
pyxel.run(update, draw)
本日の講義
https://gyazo.com/1b52d2562e63d84be2f13e151a960d2f
リストの可読性の悪さを解決するための手段を伝えます
左がbefore、右がafter 上からなんとなく読んでみましょう
https://gyazo.com/0b7bbffb6670bc646c2fda8ee88f26ec
Ballという概念はどのようなものかを定義 (class Ball)
Ballという概念はどのような処理を持つかを定義 (def move)
Ballという概念に共通する値は class Ball直下に記載 (Ball.speed)
個別のBallが持つ固有の値は self.XXX で管理 (self.x, self.y)
for文がわかりやすくなっている点にも要注目
ミニプロの配点としては4点分
プログラミングを今後やっていきたなら必須で理解が求められる概念です
理解せずとも単位は取得可能です (それだけ最後のハードルではある)
余談
オブジェクト/メソッドがわかるとこんなに便利!
例えばシューティングゲームを作るとして…
code:python
class Enemy:
size = 3
color = 2
def __init__(self, x, y, vx, vy):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.hp = 100
def move(self):
self.x = self.x + self.vx
self.y = self.y + self.vy
def isDead(self):
return self.hp <= 0
def draw(self):
pyxel.rect(self.x, self.y, Enemy.size, Enemy.size, Enemy.color)
for enemy in enemies:
enemy.move()
enemy.draw()
演習
Part1 B-12-2まで!
課題
B-11系統一式
必須は★★★まで (=今週は全部!)
企画書の提出も11/14期日です!