キー入力とプレイヤーの移動

キーボードを使い、ラビップルを動かせるようにしたいと思います。

キー入力

キー入力を検出してそれに対応する処理をするプログラムを記述していきますが、キー入力の検出には二つの種類があります。

それは、キーが「押された」ことを検出するものと、「押されている」ことを検出するものです。

一見すると「なにが違うのだ?」と思うかもしれません。

でも、実際に書いて動かしてみると、けっこう違います。

キーが「押された」瞬間の処理

「押された」ことを検知するには、KEYDOWNやKEYUPといったイベントを取得する方法があります。

このやり方では、キーが押されたとき、あるいはキーから指が離されたときにイベントが起こりますので、その瞬間一度しか検出されません。

キーを長押ししていてもKEYDOWNイベントは発生しないので、もう一度キーを押しなおす必要があります。

もしこのやり方でプレイヤーの移動を実装してしまうと、例えば「左キーを押すと左に1進む」という処理の場合、左に100進むためには100回左キーを連打しなければならないわけです。

会話を進めるための「次へ」ボタンや、決定コマンドなどには向いてるかもしれません。

キーが「押されている」ときの処理

こちらのやり方のほうが、おそらくプレイヤーの移動の実装には向いています。

「左キーが押されているとき、左に1進む」という処理になるので、左キーを長押ししていてもプレイヤーは動き続けます。

今回はこちらのやり方でラビップルを動かしましょう。key_handler()にキー操作を記述します。

#!/usr/bin/env python
import pygame
from pygame.locals import *
import sys

import cursor, tools

SCR_RECT = Rect(0, 0, 640, 480)

class Main():
    def __init__(self):
        pygame.init()
        pygame.display.set_caption("sample")
        screen = pygame.display.set_mode(SCR_RECT.size)

        self.font = pygame.font.Font("data/minamoji04.ttf", 80)
        self.title = self.font.render("ラビップルの冒険", True, (0, 0, 0))
        self.start = self.font.render("はじめる", True, (0, 0, 0))

        self.image = tools.load_image("data", "rabipple.png", -1)
        # 画像の座標を設定
        self.x = 288
        self.y = 200
        # 移動速度
        self.speed = 5

        self.bg = tools.load_image("data", "bg.png")

        self.cursor = cursor.Cursor(90, 330, (0, 0, 0))

        clock = pygame.time.Clock()
        while True:
            clock.tick(30)
            self.update()
            self.draw(screen)
            pygame.display.update()
            self.key_handler()

    def update(self):
        self.cursor.update()

    def draw(self, screen):
        screen.blit(self.bg, (0, 0))

        screen.blit(self.title, (((320 - (self.title.get_width() / 2)), 100)))
        screen.blit(self.start, (((320 - (self.start.get_width() / 2)), 300)))
        screen.blit(self.image, (self.x, self.y))

        self.cursor.draw(screen)

    def key_handler(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[K_LEFT]:
            self.x -= self.speed
        if pressed_keys[K_RIGHT]:
            self.x += self.speed
        if pressed_keys[K_UP]:
            self.y -= self.speed
        if pressed_keys[K_DOWN]:
            self.y += self.speed

if __name__ == "__main__":
    Main()

pygame.key.get_pressed()は、呼び出されたときに押されているキーの一覧を取得できます。

もし↑キーが押されていれば、画像のy座標をspeed分だけマイナスする、というように処理を書き加えているだけです。

これで、ラビップルが画面中を縦横無尽に動くようになりましたが、まだ躍動感が足りませんね。

次回はラビップルにアニメのような動きをつけてみたいと思います。