1 前のレッスンで作成した簡単なアニメーションを復習します。
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode([640, 480])
screen.fill([255, 255, 255])
ball = pygame.image.load("beach_ball.png")
x = 0
y = 100
speed = 50
yspeed = 50
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit(0)
pygame.draw.rect(screen, [255, 255, 255], [x, y, 90, 90])
x += speed
y += yspeed
if x + 90 > 640:
speed = -speed
if x < 0:
speed = -speed
if y + 90 > 480:
yspeed = -yspeed
if y < 0:
yspeed = -yspeed
screen.blit(ball, [x, y])
pygame.display.flip()
pygame.time.delay(100)
このプログラムは、ウィンドウ全体でボールのアニメーションを表示できます。
2 ボールと対応する動きを抽象化するクラスに整理する
ここで中の小球を取り出してクラスに詰め込み、小球の動きを関数 move で表現し、
次に、ボールは最初に変数イメージ (物理イメージからメモリにロードされた変数) を持ち、次にサイズと位置ポイントを持つ必要があります. これら 2 つは rect(x, y, width, height に結合できます) ) 、左右に移動する速さ、上下に移動する速さを表す速度 speed[x,y] もあります
コードは以下のように表示されます:
import pygame
class MyBall:
def __init__(self, image_file, point, speed):
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = point
self.speed = speed
移動のロジックは、毎回 speed の距離を移動し (速度とは、x を水平方向に移動し、y を垂直方向に移動することを意味します)、rect を更新し、左端または右端に達すると、x 方向の速度が逆になります。 farmost 上端または下端で、速度の y 方向が逆になります。
コードは以下のように表示されます:
size = width, height = 640, 480
def move(self):
self.rect = self.rect.move(self.speed)
if self.rect.left < 0 or self.rect.right > width:
self.speed[0] = -self.speed[0]
if self.rect.top < 0 or self.rect.bottom > height:
self.speed[1] = -self.speed[1]
このようにして、ボールの定義と動きのロジックが完成しました
次に、ボールのアニメーションをもう一度実行しましょう。
1) 背景を復元する
2) ボールを動かして位置を更新する
3) 新しい位置にボールを描く
4) ボールを画面に出力する
5) 適切な時期を遅らせる
コードは以下のように表示されます:
def run(ball):
screen.fill([255, 255, 255])
ball.move()
screen.blit(ball.image, ball.rect)
pygame.display.flip()
pygame.time.delay(20)
次に、このクラスを実行します
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
image_file = "beach_ball.png"
ball = MyBall(image_file, width/2, height/2, [2, 2])
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
run(ball)
3 正面から抽象化されたオブジェクトを使用して、9 つの小さなボールを同時にアニメーション化します。
変更するコード:
def run(balls):
screen.fill([255, 255, 255])
for ball in balls:
ball.move()
screen.blit(ball.image, ball.rect)
pygame.display.flip()
pygame.time.delay(20)
balls = []
for row in range(3):
for column in range(3):
ball = MyBall(image_file, [180*row+10, 180*column+10], [2, 2])
balls.append(ball)
4 衝突検出にアニメーション スプライト クラスを使用します。
アニメーション スプライトの基本的なプロパティ:
1) 画像
2) 長方形エリア
ボール クラスにアニメーション スプライト クラスを継承させると、衝突検出に spritecollide を使用できます。
class MyBall(pygame.sprite.Sprite):
def __init__(self, image_file, point, speed):
pygame.sprite.Sprite.__init__(self)
def run(balls):
screen.fill([255, 255, 255])
for ball in balls:
ball.move()
screen.blit(ball.image, ball.rect)
for ball in balls:
balls.remove(ball)
if pygame.sprite.spritecollide(ball, balls, False):
ball.speed[0] = -ball.speed[0]
ball.speed[1] = -ball.speed[1]
balls.append(ball)
pygame.display.flip()
pygame.time.delay(20)
説明: ここでの衝突検出は長方形を確認するためのものであるため、実際には触れずに検出が行われていることがわかります。
最後に、改善されたすべてのコードをクラスに添付します。
import pygame, sys
class MyBall(pygame.sprite.Sprite):
def __init__(self, point, speed):
pygame.sprite.Sprite.__init__(self) #####
self.image = pygame.image.load("beach_ball.png")
self.rect = self.image.get_rect()
self.rect.left = point[0]
self.rect.top = point[1]
self.speed = speed
def move(self):
self.rect = self.rect.move(self.speed)
if self.rect.right > width or self.rect.left < 0:
self.speed[0] = -self.speed[0]
if self.rect.bottom > height or self.rect.top < 0:
self.speed[1] = -self.speed[1]
screen.blit(self.image, self.rect) # 显示
def peng(self, balls):
balls.remove(self)
if pygame.sprite.spritecollide(self, balls, False):
self.speed[0] = -self.speed[0]
self.speed[1] = -self.speed[1]
balls.append(self)
pygame.init()
size = width,height = 640, 480
screen = pygame.display.set_mode(size)
screen.fill([255, 255, 255])
balls = []
for row in range(3):
for col in range(3):
speed = [2, 2]
point = [row * 180 + 10, col * 180 + 10]
ball = MyBall(point, speed)
balls.append(ball)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill([255, 255, 255])
for ball in balls:
ball.move()
for ball in balls:
ball.peng(balls)
pygame.display.flip()
pygame.time.delay(50)