0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pygameを使って RPGを作る(3. キャラクター配置と移動)

Last updated at Posted at 2024-12-31

概要

本記事はキャラクターを配置と移動を実現する

配置については、前回のSurfaceにイメージ画像を読み込ませたオブジェクトを代入するだけで実現できる。
今回はキーボードリスナーを追加し、キャラクターをキーボードで動かすようにする

使い方の例

https://www.pygame.org/docs/ref/image.html#pygame.image.load
公式だとloadしたイメージがSurfaceになっている。
load(filename) -> Surface

# surface
IMAGE_PATH = '../img/F1.png'
self.test_surface = pg.image.load(IMAGE_PATH)
# fillはコメントアウトしておく。
# self.test_surface.fill(RED)

キャラクター操作

配置したキャラクターをキーボード操作で動かせるようにする

  1. キャラクターをゆくゆく育てるため、Playerクラスを作成する

player.py

from settings import * 
import pygame as pg

class Player:
    def __init__(self):
        self.surface = pg.image.load(IMAGE_PATH)

main.py

import pygame as pg
from settings import *

from player import Player

class game:
    def __init__(self):
        pg.init()

        # screen
        self.display_surface = pg.display.set_mode((WIDTH, HEIGHT))
        # title
        pg.display.set_caption(TITLE)
        # clock
        self.clock = pg.time.Clock()
        self.running = True

        # Playerクラスのインスタンス宣言
        self.player = Player()

    def run(self):
        """ゲームループ"""
        dt = self.clock.tick(FPS) / 1000

        dx = 0
        direction = 1
        while self.running:
            # イベント処理
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    self.running = False

            # draw
            self.display_surface.fill(BLUE)

            # playerの表示    
            self.display_surface.blit(self.player.surface,(100, 100))

            pg.display.update()

        pg.quit()

if __name__ == "__main__":
    new_game = game()
    new_game.run()

メインクラスでインスタンスと表示は以下のようにメインクラスを変更する

# Playerクラスのインスタンス宣言
self.player = Player()
# 中略
# playerの表示    
self.display_surface.blit(self.player.surface,(100, 100))

2.キーボードイベントリスナーを作成する
Playerクラスにinputメソッドを実装

def input(self):
    # キーボード押されているかをキャッチしてくれる(キーボードイベントリスナー)
    keys = pg.key.get_pressed()
    if keys[pg.K_LEFT]:
        print('左矢印が押されました')
    elif keys[pg.K_RIGHT]:
        print('右矢印が押されました')

メインクラスで、メソッドをコールする

# Playerクラスのインスタンス宣言
self.player = Player()
# 中略
# playerの表示    
self.display_surface.blit(self.player.surface,(100, 100))
# キーボードイベントリスナー
self.player.input()

これでキーボードイベントが押されたら、メッセージ表示される

※キーボードイベント判定はPlayerクラスでやるのが肝心な所。

上記の実装だとキーボード一回押したら、FPS処理速度が速いため、何回も同じメッセージが表示されるので、あまりよくない。

次のようにしておくと解消されます。

class Player:
    def __init__(self):
        self.surface = pg.image.load(IMAGE_PATH)
        # フラグを追加
        self.push_flag = False

    def input(self):
        # キーボード押されているかをキャッチしてくれる(キーボードイベントリスナー)
        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT] and not self.push_flag:
            print('左矢印が押されました')
            self.push_flag = True
        elif keys[pg.K_RIGHT] and not self.push_flag:
            print('右矢印が押されました')
            self.push_flag = True
        # キーが押されていない場合にフラグをリセット
        elif not (keys[pg.K_LEFT] or keys[pg.K_RIGHT]):
            self.push_flag = False

3.キャラクターを動かすためには、メインクラスとPlayerクラスの間に、Playerの位置のやり取りするインターフェースが必要になるため、Playerクラスに位置を追加する

class Player:
    def __init__(self, pos):
        self.surface = pg.image.load(IMAGE_PATH)
        # フラグを追加
        self.push_flag = False
        # 位置
        self.pos = pos

メインクラス:

# Playerクラスのインスタンス宣言
self.player = Player([100,100])

# 中略
# playerの表示    
self.display_surface.blit(self.player.surface,self.player.pos)

4.あとはキーボードリスナーに位置を変更するだけ

from settings import * 
import pygame as pg

class Player:
    def __init__(self, pos):
        self.surface = pg.image.load(IMAGE_PATH)
        # フラグを追加
        self.push_flag = False
        # 位置
        self.pos = pos
        
    def input(self):
        # print(f'pos:{self.pos}')
        # キーボード押されているかをキャッチしてくれる(キーボードイベントリスナー)
        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT] and not self.push_flag:
            print('左矢印が押されました')
            self.pos[0] -= 10
            self.push_flag = True
        elif keys[pg.K_RIGHT] and not self.push_flag:
            print('右矢印が押されました')
            self.push_flag = True
            self.pos[0] += 10
        # キーが押されていない場合にフラグをリセット
        elif not (keys[pg.K_LEFT] or keys[pg.K_RIGHT]):
            self.push_flag = False

ゲーム画面
image.png

$ python base_main.py 
pygame-ce 2.5.2 (SDL 2.30.8, Python 3.12.2)
右矢印が押されました
左矢印が押されました
右矢印が押されました
右矢印が押されました
右矢印が押されました
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?