今回はPythonistaのsceneライブラリを活用してアクションゲームのジャンプ処理を作成する方法を紹介します。
本記事の内容は以下の通りです。
・Pythonistaでキャラクターをジャンプさせる処理を考える
・Pythonistaでキャラクターをジャンプさせる方法の実装
目次
Pythonistaでキャラクターをジャンプさせる処理を考える
ジャンプ処理を実装するためには以下の3つについて考える必要があります。
・ジャンプを起こすタイミング
・上昇時と落下時の処理
・ユーザの操作方法
ジャンプを起こすタイミング
まずはジャンプを起こすタイミングを決めておきましょう。
基本的にジャンプはプレイヤーが意図した時にできると良いので、今回は画面をタップした時にジャンプさせることにします。
また、ジャンプ中などジャンプを受け付けないタイミングについても考慮しておきましょう。
上昇時と落下時の処理
ジャンプの処理は大きく分けると「上昇」と「落下」の2つの状態に分けることができます。
ジャンプを開始したら縦軸の上方向(+方向)に移動します。
一定の高さに達したら上昇処理を終了し落下に移行。
落下は縦軸の下方向(−方向)に移動します。
地面に着地したら落下処理終了です。
ユーザの操作方法
最後にユーザの操作について考えます。
どのような操作にすれば最もユーザが操作しやすいか考えるようにしましょう。
例えば今回実装するジャンプであれば、
・画面のどこをタップしてもジャンプ
・ジャンプボタンを設置してジャンプ
などの方法が考えられます。
これは一概にどっちがいいということはないです。
アクションがジャンプや移動くらいであれば、ボタンを設置してなくても良いと思います。
逆に攻撃とジャンプの両方のアクションを入れたい場合は、ボタンを設置した方が操作しやすそうですね。
長押しなどでアクションを切り分ける方法もありますが、操作ミスが増えるのでまずはボタンでアクションを切り替える仕様で作るのがおすすめです。
以下の実装ではボタンを追加する場合の例を紹介します。
Pythonistaでキャラクターをジャンプさせる方法の実装
ジャンプアクションを実現するために以下の処理を実装します。
・ジャンプ中の状態の仕様
・上昇時の処理
・落下時の処理
・ジャンプのUI
ジャンプ中の状態の仕様
以下の3つの状態を作成します。
・ready:ジャンプ操作を受け付ける状態
・up:ジャンプ中(上昇)
・down:ジャンプ中(落下)
状態が「ready」の時のみジャンプできるように実装します。
「up」または「down」の時はジャンプ操作を受けつけません。
その他攻撃中などジャンプができない瞬間を実現したいなら「wait(待ち)」などのステータスを作っておくと良いでしょう。
上昇時の処理
ジャンプ上昇中の処理はupdate()メソッドで監視して実行して徐々に上昇させます。
上昇の処理は以下の通り。
・状態が上昇中(up)ならキャラクターを上昇させる
・一定の高さに到達したら落下(down)に移行
コードにすると以下のようになります。処理はupdate()メソッド内に記述してください。
1 2 3 4 5 6 7 8 | # 上昇時の処理 if self.jump == 'up': max_height = 180 up_speed = 10 y = max(self.player_height, min(self.size.h, y + up_speed)) self.player.position = (x, y) if y > max_height + self.player_height: self.jump = 'down' |
ポジションを変えたい場合は「self.player.position」のy座標を変更します。
max_heightはジャンプの高さ、up_speedはジャンプのスピードの設定です。
落下時の処理
ジャンプで落下中の処理は上昇と同様update()メソッドで監視して徐々に落下させます。
落下の処理は以下の通り。
・状態が上昇中(down)ならキャラクターを落下させる
・地面に到着したらジャンプ終了(readyにする)
コードにすると以下のようになります。
1 2 3 4 5 6 7 | # 落下時の処理 if self.jump == 'down': down_speed = 10 y = max(self.player_height, min(self.size.h, y - down_speed)) self.player.position = (x, y) if y == self.player_height: self.jump = 'ready' |
ポジションを変えたい場合は「self.player.position」のy座標を変更します。
down_speedはジャンプのスピードの設定です。
ジャンプのUI
ジャンプボタンをタップした時の処理を実装する場合、「touch_began()」メソッドに実装します。
必要な処理は以下の通り。
・タップした位置がジャンプボタンで状態が「ready」ならジャンプ処理に移行
・効果音を鳴らす
・状態を「up」に変える
無音だと味気ないので効果音を追加しています。
コードの実装例は以下の通り。「touch_began()」
1 2 3 4 5 6 7 8 | # タップした位置の取得 touch_loc = self.point_from_scene(touch.location) # タップした位置がボタンならジャンプ if touch_loc in self.jump_button.frame: if self.jump == 'ready': # 効果を鳴らす play_effect('game:Boing_1') self.jump = 'up' |
実装例
上記コードをまとめると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # coding: utf-8 from scene import * from sound import * class Game (Scene): def setup(self): # バックグラウンド設定 self.background_color = '#004f82' ground = Node(parent=self) x = 0 # 地面の高さ self.base_height = 50 # 背景の設定 while x <= self.size.w + 64: tile = SpriteNode('plf:Ground_Planet', position=(x, self.base_height)) ground.add_child(tile) x += 64 # プレイヤーの初期設定 self.player_height = self.base_height + 32 self.player = SpriteNode('emj:Ghost') self.player.anchor_point = (0.5, 0) self.player.position = (self.size.w/2, self.player_height) self.add_child(self.player) # ジャンプボタンの初期設定 self.jump = 'ready' self.jump_button = SpriteNode('emj:Blue_Circle', position=(320,50)) self.add_child(self.jump_button) def update(self): g = gravity() x = self.player.position.x y = self.player.position.y # 左右の移動 if abs(g.x) > 0.05: max_speed = 40 x = max(0, min(self.size.w, x + g.x * max_speed)) self.player.position = (x, y) # 上昇時の処理 if self.jump == 'up': max_height = 180 up_speed = 10 y = max(self.player_height, min(self.size.h, y + up_speed)) self.player.position = (x, y) if y > max_height + self.player_height: self.jump = 'down' # 落下時の処理 if self.jump == 'down': down_speed = 10 y = max(self.player_height, min(self.size.h, y - down_speed)) self.player.position = (x, y) if y == self.player_height: self.jump = 'ready' def touch_began(self, touch): # タップした位置の取得 touch_loc = self.point_from_scene(touch.location) # タップした位置がボタンならジャンプ if touch_loc in self.jump_button.frame: if self.jump == 'ready': play_effect('game:Boing_1') self.jump = 'up' if __name__ == '__main__': run(Game(), PORTRAIT, show_fps=True) |
◆実行結果
Pythonista3 + sceneでアクションを研究中。
コインと動くキノコというどこかで見た取り合わせ。#Python#プログラミング pic.twitter.com/7sAClUxMqd— みやびの@miyabino.py (@miyabikno) December 14, 2019
※上記のコインとかキノコの処理は本記事だけでは作成できません。
「Pythonista+sceneで当たり判定を作成する方法」をお読みください。
以上、ジャンプアクションの実装方法でした。
Pythonistaまとめ>>Pythonistaの使い方まとめ