pygletでline移動

「プレイヤー」らしき形が描画できました。

今回は

  • 共通処理を GameObject class にまとめる
  • プレイヤーをキー入力に従って移動できるようにする

処理を書いてみましょう。

プレイヤー・弾・敵…などなど、共通部分が多くなりそうなので、”GameObject” という名前で共通のクラスを作ってみよう、というイメージです。まずは、GameObject class に何をどこまで処理してもらうのか、考えないといけません。

  • shape.Line で作られた shape を管理する
  • 位置を管理する
  • 定期的に呼び出される on_update を持つ

…くらいでしょうか。定期的に呼びだす処理はちょっと前に書いた通り、pyglet.clock.schedule_interval で書けます。

class GameObject():
    def __init__(self):
        pass

    def create_lines(self, lines, color):
        pass

    def on_update(self, dt):
        pass

game_objects = []

def on_update(dt):
    for game_object in game_objects:
        game_object.on_update(dt)

pyglet.clock.schedule_interval(on_update, 1 / 120.0)

みたいにして、Player を GameObject class として作ってやれば、プレイヤーの定期的な更新処理が呼ばれますね。その中でキー入力を取得すれば、移動が書けます。

まとめると、100行くらいになりました。

import pyglet
from pyglet import shapes
from pyglet.window import key
from collections import defaultdict

title = "Pyglet Shooting Game"

WINDOW_WIDTH = 640
WINDOW_HEIGHT = 480
window = pyglet.window.Window(WINDOW_WIDTH, WINDOW_HEIGHT, title)
batch = pyglet.graphics.Batch()

LINE_WIDTH = 2
PLAYER_SPEED = 120

@window.event
def on_draw():
    window.clear()
    batch.draw()

key_status = defaultdict(bool)

@window.event
def on_key_press(symbol, modifiers):
    key_status[symbol] = True

@window.event
def on_key_release(symbol, modifiers):
    key_status[symbol] = False

game_objects = []

class GameObject():
    def __init__(self):
        self.is_dead = False
        self.line_shapes = []
        self.lines = None
        self.x = 0
        self.y = 0

    def create_lines(self, lines, color):
        self.lines = lines
        for line in lines:
            x1 = self.x + line[0][0]
            y1 = self.y + line[0][1]
            x2 = self.x + line[1][0]
            y2 = self.y + line[1][1]
            self.line_shapes.append(shapes.Line(x1, y1, x2, y2, width=LINE_WIDTH, color=color, batch=batch))

    def on_update(self, dt):
        for (line, line_shape) in zip(self.lines, self.line_shapes):
            line_shape.x = self.x + line[0][0]
            line_shape.y = self.y + line[0][1]
            line_shape.x2 = self.x + line[1][0]
            line_shape.y2 = self.y + line[1][1]

def on_update(dt):
    for game_object in game_objects:
        game_object.on_update(dt)

pyglet.clock.schedule_interval(on_update, 1 / 120.0)

class Player(GameObject):
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y

        # 菱形
        lines = (
            ((0, 16), (8, 0)), ((8, 0), (0, -16)), 
            ((0, -16), (-8, 0)), ((-8, 0), (0, 16))
        )
        color = (0, 230, 0)
        self.create_lines(lines, color)

    def on_update(self, dt):
        d = dt * PLAYER_SPEED
        dx = 0
        dy = 0
        if key_status[key.W]: # up
            dy = d
        elif key_status[key.S]: # down
            dy = -d
      
        if key_status[key.A]: # left
            dx = -d
        elif key_status[key.D]: # right
            dx = d
        self.x += dx
        self.y += dy
        super().on_update(dt)

def create_player():
    player = Player(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 3)
    game_objects.append(player)

create_player()

pyglet.app.run()
タイトルとURLをコピーしました