• 検索結果がありません。

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 ゲームプログラミング スプライト スプライト Pygame では pygame.sprite を用いる事でスプライトの管理 描画 衝突判定等を簡単に行う事が出来る 此れを利用してキャラクター操作に関する各種機能をスプライトクラスとして 1 個

N/A
N/A
Protected

Academic year: 2021

シェア "PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 ゲームプログラミング スプライト スプライト Pygame では pygame.sprite を用いる事でスプライトの管理 描画 衝突判定等を簡単に行う事が出来る 此れを利用してキャラクター操作に関する各種機能をスプライトクラスとして 1 個"

Copied!
7
0
0

読み込み中.... (全文を見る)

全文

(1)

■ ゲームプログラミング ■ § スプライト § ■ スプライト Pygame では pygame.sprite を用いる事でスプライトの管理、描画、衝突判定等を簡単に行う事が出来 る。此れを利用してキャラクター操作に関する各種機能をスプライトクラスとして 1 個に纏め、複数の キャラクターを扱い易くしたコードを、下記に示す。 PYTHON3 import pygame

from pygame.locals import * import sys

SCREEN = Rect(0, 0, 400, 400) # スプライトのクラス

class Sprite(pygame.sprite.Sprite):

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) def __init__(self, filename, x, y, vx, vy, angle=0):

pygame.sprite.Sprite.__init__(self)

self.img = pygame.image.load(filename).convert_alpha()

if angle != 0: self.img = pygame.transform.rotate(self.img, angle) w = self.img.get_width() h = self.img.get_height() self.rect = Rect(x, y, w, h) self.vx = vx self.vy = vy self.angle = angle def update(self): self.rect.move_ip(self.vx, self.vy) # 壁と衝突時の処理(跳ね返り)

if self.rect.left < 0 or self.rect.right > SCREEN.width: self.vx = -self.vx

if self.rect.top < 0 or self.rect.bottom > SCREEN.height: self.vy = -self.vy

# 壁と衝突時の処理(壁を超えない様に) self.rect = self.rect.clamp(SCREEN) def draw(self, screen):

screen.blit(self.img, self.rect) # メイン def main(): pygame.init() screen = pygame.display.set_mode(SCREEN.sice)

P

PY

YT

TH

HO

ON

N

入門

(2)

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) player = Sprite("player1.png", 200, 200, 2, 0, 0) enemy1 = Sprite("enemy1.png", 200, 200, 0, 2, 0) enemy2 = Sprite("enemy2.png", 200, 200, 2, 2, 10) clock = pygame.time.Clock() while (1): clock.tick(30) # フレームレート(30fps) screen.fill((0, 20, 0, 0)) # 画面の背景色 # スプライトを更新 player.update() enemy1.update() enemy2.update() # スプライトを描画 player.draw(screen) enemy1.draw(screen) enemy2.draw(screen) # 画面更新 pygame.display.update() # イベント処理

for event in pygame.event.get(): # 終了用のイベント処理

if event.type == QUIT: # 閉じるボタンが押された時 pygame.quit()

sys.exit()

if event.type == KEYDOEN: # キーを押した時 if event.key == K_ESCAPE: # Esc キーが押された時 pygame.quit() sys.exit() if __name__ == "__main__": main() プログラムの処理の流れは下記の通りで有る。 処理 コード

① ゲームライブラリ pygame をインポートする。 import pygame

② 画面のサイズを設定する。 SCREEN=Rect(0, 0, 400, 400) ③ スプライトのクラスを定義する。 class Sprite ④ Pygame を初期化する。 pygame.init ⑤ 大きさ SCREEN.sice の画面(ウィンドウ)を生成する。 pygame.display.set_mode ⑥ スプライトを作成する。 player、enemy1、enemy2 ⑦ 指定したミリ秒の間プログラムを停止する。 clock.tick(30) ⑧ 画面を濃緑色(R=0, G=20, B=0, A=0)に塗り潰す。 screen.fill ⑨ スプライトを更新する。 player.update 等 ⑩ スプライトを描画する。 player.draw 等 ⑪ 画面を更新する。 pygame.display.update ⑫ 閉じるボタンが押されたら画面を閉じて終了する。 pygame.quit、sys.exit ⑬ Esc キーが押されたら画面を閉じて終了する。 pygame.quit、sys.exit

(3)

■ スプライトグループ スプライトグループを使用すると、スプライトの更新や描画が簡単に成り、複数のスプライトを効率良 く管理する事が出来る。大量のスプライトを使用する弾幕ゲーム等では便利な機能で有る。 Pygame ではスプライトグループを使う方法がいくつかあります。 亦、Pygame では pygame.sprite.RenderUpdates を用いる事でスプライトグループを作成する事が出 来る。此れを利用して前述のサンプルの 3 体を一括して更新し描画するコードを、下記に示す。 PYTHON3 import pygame

from pygame.locals import * import sys

SCREEN = Rect(0, 0, 400, 400) # スプライトのクラス

class Sprite(pygame.sprite.Sprite):

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) def __init__(self, filename, x, y, vx, vy, angle=0):

pygame.sprite.Sprite.__init__(self)

self.img = pygame.image.load(filename).convert_alpha()

if angle != 0: self.img = pygame.transform.rotate(self.img, angle) w = self.img.get_width() h = self.img.get_height() self.rect = Rect(x, y, w, h) self.vx = vx self.vy = vy self.angle = angle def update(self): self.rect.move_ip(self.vx, self.vy) # 壁と衝突時の処理(跳ね返り)

if self.rect.left < 0 or self.rect.right > SCREEN.width: self.vx = -self.vx

if self.rect.top < 0 or self.rect.bottom > SCREEN.height: self.vy = -self.vy

# 壁と衝突時の処理(壁を超えない様に) self.rect = self.rect.clamp(SCREEN)

def draw(self, screen):

screen.blit(self.img, self.rect) # メイン

def main(): pygame.init()

screen = pygame.display.set_mode(SCREEN.sice)

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) player = Sprite("player1.png", 200, 200, 2, 0, 0)

enemy1 = Sprite("enemy1.png", 200, 200, 0, 2, 0) enemy2 = Sprite("enemy2.png", 200, 200, 2, 2, 10)

# スプライトグループの作成

(4)

# スプライトの追加 group.add(player) group.add(enemy1) group.add(enemy2) clock = pygame.time.Clock() while (1): clock.tick(30) # フレームレート(30fps) screen.fill((0, 20, 0, 0)) # 画面の背景色 # スプライトグループを更新 group.update() # スプライトを描画 group.draw(screen) # 画面更新 pygame.display.update() # イベント処理

for event in pygame.event.get(): # 終了用のイベント処理

if event.type == QUIT: # 閉じるボタンが押された時 pygame.quit()

sys.exit()

if event.type == KEYDOEN: # キーを押した時 if event.key == K_ESCAPE: # Esc キーが押された時 pygame.quit() sys.exit() if __name__ == "__main__": main() 上記の様に、pygame.sprite.RenderUpdates でスプライトグループを作成し、其のグループに個々のス プライトを追加(group.add)する事で、更新や描画がグループ単位で行える様に成る。 上記以外にも、Pygame では幾つかのスプライトグループを使用する方法が有る。スプライトのクラス 定義で pygame.sprite.Sprite.init(self, self.containers) を使用すると、スプライトクラス内で予めグル ープ指定が為されるので、スプライトを作成すると自動的にグループに追加される。 PYTHON3 import pygame

from pygame.locals import * import sys

SCREEN = Rect(0, 0, 400, 400) # スプライトのクラス

class Sprite(pygame.sprite.Sprite):

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) def __init__(self, filename, x, y, vx, vy, angle=0):

pygame.sprite.Sprite.__init__(self, self.containers)

self.image = pygame.image.load(filename).convert_alpha()

if angle != 0: self.image = pygame.transform.rotate(self.image, angle) w = self.image.get_width()

h = self.image.get_height() self.rect = Rect(x, y, w, h)

(5)

self.vx = vx self.vy = vy self.angle = angle def update(self): self.rect.move_ip(self.vx, self.vy) # 壁と衝突時の処理(跳ね返り)

if self.rect.left < 0 or self.rect.right > SCREEN.width: self.vx = -self.vx

if self.rect.top < 0 or self.rect.bottom > SCREEN.height: self.vy = -self.vy # 壁と衝突時の処理(壁を超えない様に) self.rect = self.rect.clamp(SCREEN) # メイン def main(): pygame.init() screen = pygame.display.set_mode(SCREEN.sice) # スプライトグループを作成して group = pygame.sprite.RenderUpdates() # スプライトクラスにスプライトグループを割り当てる Sprite.containers = group

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) player = Sprite("player1.png", 200, 200, 2, 0, 0) enemy1 = Sprite("enemy1.png", 200, 200, 0, 2, 0) enemy2 = Sprite("enemy2.png", 200, 200, 2, 2, 10) clock = pygame.time.Clock() while (1): clock.tick(30) # フレームレート(30fps) screen.fill((0, 20, 0, 0)) # 画面の背景色 # スプライトグループを更新 group.update() # スプライトを描画 group.draw(screen) # 画面更新 pygame.display.update() # イベント処理

for event in pygame.event.get(): # 終了用のイベント処理

if event.type == QUIT: # 閉じるボタンが押された時 pygame.quit()

sys.exit()

if event.type == KEYDOEN: # キーを押した時 if event.key == K_ESCAPE: # Esc キーが押された時 pygame.quit() sys.exit() if __name__ == "__main__": main() クラス定義で赤字の部分を書き換えると、main 関数の赤字の部分で、グループをコンテナに登録する ので、個々のスプライトをグループに追加(group.add)する必要が無く成る。

(6)

亦、スプライトの描画を高速に行う為に dirty rect animation(汚い矩形のアニメーション)と謂う手 法が有り、此の手法では、画面を更新する時に、スプライトが更新された部分丈を再描画する。

PYTHON3 import pygame

from pygame.locals import * import sys

SCREEN = Rect(0, 0, 400, 400) # スプライトのクラス

class Sprite(pygame.sprite.Sprite):

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) def __init__(self, filename, x, y, vx, vy, angle=0):

pygame.sprite.Sprite.__init__(self, self.containers)

self.image = pygame.image.load(filename).convert_alpha()

if angle != 0: self.image = pygame.transform.rotate(self.image, angle) w = self.image.get_width() h = self.image.get_height() self.rect = Rect(x, y, w, h) self.vx = vx self.vy = vy self.angle = angle def update(self): self.rect.move_ip(self.vx, self.vy) # 壁と衝突時の処理(跳ね返り)

if self.rect.left < 0 or self.rect.right > SCREEN.width: self.vx = -self.vx

if self.rect.top < 0 or self.rect.bottom > SCREEN.height: self.vy = -self.vy

# 壁と衝突時の処理(壁を超えない様に) self.rect = self.rect.clamp(SCREEN)

def draw(self, screen):

screen.blit(self.img, self.rect) # メイン def main(): pygame.init() screen = pygame.display.set_mode(SCREEN.sice) # スプライトグループを作成して group = pygame.sprite.RenderUpdates() # スプライトクラスにスプライトグループを割り当てる Sprite.containers = group

# スプライトを作成(画像ファイル名, 位置(x, y), 速さ(vx, vy), 回転 angle) player = Sprite("player1.png", 200, 200, 2, 0, 0) enemy1 = Sprite("enemy1.png", 200, 200, 0, 2, 0) enemy2 = Sprite("enemy2.png", 200, 200, 2, 2, 10) clock = pygame.time.Clock() # 背景の作成と描画(背景は最初に 1 回丈描画) bg = pygame.Surface(SCREEN.sice) bg.fill((0, 20, 0)) # 画面の背景色 screen.blit(bg, (0,0))

(7)

pygame.display.update() while (1): clock.tick(30) # フレームレート(30fps) group.clear(screen, bg) # スプライトグループを更新 group.update() # スプライトを更新 dirty_rects = group.draw(screen) # 画面更新(dirty rect を渡すと其の部分丈を更新する) pygame.display.update(dirty_rects) # イベント処理

for event in pygame.event.get(): # 終了用のイベント処理

if event.type == QUIT: # 閉じるボタンが押された時 pygame.quit()

sys.exit()

if event.type == KEYDOEN: # キーを押した時 if event.key == K_ESCAPE: # Esc キーが押された時 pygame.quit() sys.exit() if __name__ == "__main__": main() ■ Sprite クラスのメソッド クラス 説明 pygame.sprite.Sprite 特定の画像をゲーム画面に表示する為の単純な基底クラス pygame.sprite.DirtySprite 属性を増やして機能を追加した Sprite のサブクラス。 pygame.sprite.Group 複数の Sprite を保持するクラス pygame.sprite.RenderUpdates 描写先範囲の情報を取得する Group クラス pygame.sprite.OrderedUpdates 追加された順番に従い画面描写を行う RenderUpdates クラス pygame.sprite.LayeredUpdates レイヤーを制御し画像描写処理を行う Group クラス

pygame.sprite.LayeredDirty DirtySprites 用の Group クラス

pygame.sprite.GroupSingle Sprite オブジェクトを 1 個しか格納出来ない Group クラス Sprite クラスのメソッドには、下記の物が有る。

メソッド 説明

pygame.sprite.spritecollide Group の中から指定した Sprite と接触して居る物を探す。 pygame.sprite.collide_rect rect 属性を使って 2 個の sprite の当たり判定を行う。 pygame.sprite.collide_rect_ratio rect の大きさを変換して 2 個の sprite の当たり判定を行う。 pygame.sprite.collide_circle 円に変換した大きさで 2 個の sprite の当たり判定を行う。 pygame.sprite.collide_circle_ratio radius の大きさ変換して 2 個の sprite の当たり判定を行う。 pygame.sprite.collide_mask mask 属性を使って 2 個の sprite の当たり判定を行う。 pygame.sprite.groupcollide 2 個の Group 間で接触して居る総ての Sprite を探す。

pygame.sprite.spritecollideany 指定した Sprite が Group 内で接触して居る Sprite を調べる。 ■ pygame ドキュメント

原文:https://www.pygame.org/docs/ref/transform.html

参照

関連したドキュメント

  BCI は脳から得られる情報を利用して,思考によりコ

 基本波を用いる近似はピクセル単位の時間放射能曲線に対しては用いることができる

攻撃者は安定して攻撃を成功させるためにメモリ空間 の固定領域に配置された ROPgadget コードを用いようとす る.2.4 節で示した ASLR が機能している場合は困難とな

テューリングは、数学者が紙と鉛筆を用いて計算を行う過程を極限まで抽象化することに よりテューリング機械の定義に到達した。

 食品事業では、「収益認識に関する会計基準」等の適用に伴い、代理人として行われる取引について売上高を純

 固定資産は、キャッシュ・フローを生み出す最小単位として、各事業部を基本単位としてグルーピングし、遊休資産に

「系統情報の公開」に関する留意事項

ペトロブラスは将来同造船所を FPSO の改造施設として利用し、工事契約落札事業 者に提供することを計画している。2010 年 12 月半ばに、ペトロブラスは 2011