Cocos2d のイベント,キーコード,イベントハンドラ,アクション
1. エグゼクティブサマリー
Cocos2d は2次元ゲームのフレームワークである.Python で動作する. (Cocos2d から派生した Cocos2d-x は iOS や Android でも動き,普及している.)
このページでは,次の事項を見本プログラムで演習する.
- Cocos2d のイベント
- Cocos2d でのキーコード
- Cocos2d でのイベントハンドラ
- Cocos2d のアクション
関連する資料:Cocos2d の概要 [PDF], [パワーポイント]
関連する資料:ゲームエンジン[PDF], [パワーポイント]
【関連する外部ページ】 https://www.cocos.com/endoc.html
謝辞:Cocos2d の作者に感謝します.https://github.com/liamrahav/cocos2d-python-tutorials/blob/master/basics/ で公開されているサンプルプログラムを参考にした.
2. 前準備(必要ソフトウェアの入手)
ここでは、最低限の事前準備について説明する。機械学習や深層学習を行う場合は、NVIDIA CUDA、Visual Studio、Cursorなどを追加でインストールすると便利である。これらについては別ページ https://www.kkaneko.jp/cc/dev/aiassist.htmlで詳しく解説しているので、必要に応じて参照してください。
Python 3.12 のインストール(Windows 上) [クリックして展開]
以下のいずれかの方法で Python 3.12 をインストールする。Python がインストール済みの場合、この手順は不要である。
方法1:winget によるインストール
管理者権限のコマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。
winget install --scope machine --id Python.Python.3.12 -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_pip=1 Include_test=0 Include_launcher=1 InstallLauncherAllUsers=1"
--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。
方法2:インストーラーによるインストール
- Python 公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする。
- ダウンロードしたインストーラーを実行する。
- 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから
pythonコマンドを実行できない。 - 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。
インストールの確認
コマンドプロンプトで以下を実行する。
python --version
バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。
AIエディタ Windsurf のインストール(Windows 上) [クリックして展開]
Pythonプログラムの編集・実行には、AIエディタの利用を推奨する。ここでは、Windsurfのインストールを説明する。Windsurf がインストール済みの場合、この手順は不要である。
管理者権限のコマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。
winget install --scope machine --id Codeium.Windsurf -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --custom "/SP- /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /DIR=""C:\Program Files\Windsurf"" /MERGETASKS=!runcode,addtopath,associatewithfiles,!desktopicon"
powershell -Command "$env:Path=[System.Environment]::GetEnvironmentVariable('Path','Machine')+';'+[System.Environment]::GetEnvironmentVariable('Path','User'); windsurf --install-extension MS-CEINTL.vscode-language-pack-ja --force; windsurf --install-extension ms-python.python --force; windsurf --install-extension Codeium.windsurfPyright --force"
--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。
【関連する外部ページ】
Windsurf の公式ページ: https://windsurf.com/
cocos2d, pyglet のインストール [クリックして展開]
管理者権限のコマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。
pip install cocos2d pyglet
3. 実行のための準備とその確認手順(Windows 前提)
3.1 プログラムファイルの準備
第5章に掲載するソースコードをテキストエディタ(メモ帳,Windsurf 等)に貼り付け,それぞれ以下のファイル名で保存する(文字コード:UTF-8).
- マウス操作の見本プログラム:
mouse_click.py - キーボード操作の見本プログラム:
keyboard_move.py - 移動アクションの見本プログラム:
action_move.py - ジャンプアクションの見本プログラム:
action_jump.py
3.2 実行コマンド
コマンドプロンプトでファイルの保存先ディレクトリに移動し,以下を実行する.
python mouse_click.py
python keyboard_move.py
python action_move.py
python action_jump.py
3.3 動作確認チェックリスト
| 確認項目 | 期待される結果 |
|---|---|
| プログラム起動時 | 640×480 のウインドウが表示され,左下付近に「Hello,World!」のラベルが表示される |
| mouse_click.py:画面内をクリック | クリックした座標にラベルが移動する |
| keyboard_move.py:画面内をクリック後,矢印キーを押す | 矢印キーの方向にラベルが10画素ずつ移動する |
| action_move.py:画面内をクリック後,スペースキーを押す | ラベルが2秒かけて右に200画素,上に100画素移動する(MoveBy) |
| action_move.py:R キーを押す | ラベルが2秒かけて360度回転する(RotateBy) |
| action_jump.py:画面内をクリック後,スペースキーを押す | ラベルが5秒かけて5回ジャンプしながら右に300画素,上に100画素移動する(JumpBy) |
| action_jump.py:S キーを押す | ラベルが1秒かけて2倍に拡大する(ScaleBy) |
| ウインドウ右上の「x」をクリック | プログラムが終了する |
4. 概要・使い方・実行上の注意
イベント,キーコード,イベントハンドラ
- イベント: ユーザの入力(キーボード操作,マウス操作,ウインドウ操作など)によって発生するものや,プログラム作成者が独自に定義するイベントがある.
Cocos2d でのイベント
- on_key_press キーが押された
- on_key_release キーが離された
- on_mouse_motion マウスが動いた
- on_mouse_drag マウスのドラッグ
- on_mouse_press マウスのボタンが押された
- on_resize ウインドウのサイズ変更 など
- キーコード
キーコードとは,キーボードの各キーに割り当てられたコード(符号)である.
pyglet でのキーコード
- key.A, key.B, key.C, ... アルファベット
- key._1, key._2, key._3, ... 数字
- key.ENTER Enter キー
- key.SPACE スペースキー
- key.LEFT, key.RIGHT, key.UP, key.DOWN 矢印キー
- key.F1, key.F2, key.F3, ... ファンクションキー
詳しくは https://pyglet.readthedocs.io/en/latest/programming_guide/keyboard.html?highlight=keyboard - イベントハンドラ: イベントハンドラとは,
特定のイベントが発生したときに実行されるプログラムである.
def on_key_press(self, symbol, modifiers): if symbol == key.RIGHT: self.label.x += 10
マウス操作
- イベント: on_mouse_press (マウスのボタンが押された)
- イベントハンドラ: オブジェクトの x, y 値を変える
def on_mouse_press(self, x, y, buttons, modifiers): self.label.x = x self.label.y = y
- Python プログラムの実行
- 画面が現れるので確認する.
- 画面内をクリックすると,オブジェクトが移動する.
- 結果を確認したら,右上の「x」をクリックして終了する.
* 演習問題: 上の手順を行いなさい.
* 演習問題: 「Hello,World!」を別のものに変えて変化を見なさい. 画面内をクリックすること. 結果を確認したら,右上の「x」をクリックして終了すること.
キーボード操作
- イベント: on_key_press (キーが押された)
- イベントハンドラ: オブジェクトの x, y 値を変える
- Python プログラムの実行
- 画面が現れるので確認する.
- 画面内を1回クリックしたあと,キーボードの矢印キーをいろいろ連打する.(矢印キーは4つある)
- 結果を確認したら,右上の「x」をクリックして終了する.
* 演習問題: 上の手順を行いなさい.
* 演習問題: 「+= 10」, 「-= 10」 の「10」を別の数値に変えて変化を見なさい.全部で4か所ある. 結果を確認したら,右上の「x」をクリックして終了すること.
アクション
- アクション: アクションとは,オブジェクトの属性を変化させる操作である.
- Cocos2d でのオブジェクトの属性
位置,大きさ,見える/見えない,透明度など
- Cocos2dのアクションの種類:
- 即時 (InstantAction) ・・・ すぐに変化
- インターバル (IntervalAction) ・・・ 一定の時間をかけて変化
- その他 (Action) ・・・ 時間をかけて変化するが,所要時間が前もって分からない
- Cocos2d のアクションの例
- 位置 (position): MoveBy, MoveTo, JumpBy, JumpTo, Bezier, Place
- 大きさ (scale): ScaleBy, ScaleTo
- 向き (rotation): RotateBy, RotateTo
- 見える/見えない (visible): Show, Hide, Blink, ToggleVisibility
- 透明 (opacity): FadeIn, FadeOut, FadeTo
- 待ち (time related: do nothing along a duration): Delay, RandomDelay
- flow control: CallFunc, CallFuncS
- grid helpers: StopGrid, ReuseGrid
- カメラ関係 (camera related): OrbitCamera
【関連する外部ページ】 https://www.cocos.com/endoc/api/cocos.actions.interval_actions.html
移動(MoveBy, MoveTo)
- イベント: on_key_press (キーが押された)
- イベントハンドラ: MoveBy や MoveTo で移動
- Python プログラムの実行
- 画面が現れるので確認する.
- 「key.SPACE」はスペースキーを表す.「key.R」で R キーを押すと,オブジェクトが2秒かけて360度回転する.
画面内を1回クリックしたあと,スペースキーやR キーをゆっくり何度か押しなさい.
- 結果を確認したら,右上の「x」をクリックして終了する.
* 演習問題: 上の手順を行いなさい.
* 演習問題: 「MoveBy((200, 100), 2)」のところを,下のように変えて変化を見なさい.
スペースキーを押して1度移動したら,何度スペースキーを押しても動かないことを確認する. 結果を確認したら,右上の「x」をクリックして終了すること.
MoveTo((300, 400), duration=5) ・・・ 5秒かけて,(300, 400)の場所に移動する.
* 演習問題: 次を追加しなさい.
字下げにも注意すること.下の図の通り,字下げしなさい.
画面内でクリックすると,オブジェクトが動くので確認すること. 結果を確認したら,右上の「x」をクリックして終了すること.
def on_mouse_press(self, x, y, buttons, modifiers):
self.myactor.do(cocos.actions.MoveTo((x, y), 2))
ジャンプ(JumpBy, JumpTo)
- イベント: on_key_press (キーが押された)
- イベントハンドラ: JumpBy や JumpTo でジャンプ
- Python プログラムの実行
- 画面が現れるので確認する.
- 「key.SPACE」はスペースキーを表す.「key.S」で S キーを押すと,オブジェクトが1秒かけて2倍に拡大する.
画面内を1回クリックしたあと,スペースキーやS キーをゆっくり何度か押しなさい.
JumpBy((300, 100), 100, 5, duration=5) ・・・ 5秒かけて,右に300画素,上に100画素ジャンプする.ジャンプの回数は5回で,100画素分の高さである.
- 結果を確認したら,右上の「x」をクリックして終了する.
* 演習問題: 上の手順を行いなさい.
* 演習問題: 「JumpBy((320,0), 100, 5, duration=5)」のところを,下のように変えて変化を見なさい.
スペースキーを押して1度移動したら,何度スペースキーを押しても動かないことを確認する. 結果を確認したら,右上の「x」をクリックして終了すること.
JumpTo((100,100), 100, 5, duration=5) ・・・ 5秒かけて,(100,100)の場所にジャンプする.
* 演習問題: 次を追加しなさい.
字下げにも注意すること.下の図の通り,字下げしなさい.
画面内でクリックすると,オブジェクトが動くので確認すること. 結果を確認したら,右上の「x」をクリックして終了すること.
def on_mouse_press(self, x, y, buttons, modifiers):
self.myactor.do(cocos.actions.JumpTo((x, y), 100, 5, duration=5))
5. ソースコード
マウス操作(mouse_click.py)
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director
from pyglet.window import key
class MyActor(cocos.text.Label):
def __init__(self, text, x, y, size, rgba):
super(MyActor, self).__init__(
text, font_name="Times New Roman", font_size=size,
anchor_x='center', anchor_y='center', color=rgba)
self.position = cocos.euclid.Vector2(x, y)
class Layer00(Layer):
is_event_handler = True
def __init__(self):
super(Layer00, self).__init__()
self.myactor = MyActor("Hello,World!", 0, 0, 32, (0, 200, 255, 255))
self.add(self.myactor)
def on_mouse_press(self, x, y, buttons, modifiers):
self.myactor.x = x
self.myactor.y = y
director.init(width=640, height=480)
director.run(scene.Scene(Layer00()))
キーボード操作(keyboard_move.py)
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director
from pyglet.window import key
class MyActor(cocos.text.Label):
def __init__(self, text, x, y, size, rgba):
super(MyActor, self).__init__(
text, font_name="Times New Roman", font_size=size,
anchor_x='center', anchor_y='center', color=rgba)
self.position = cocos.euclid.Vector2(x, y)
class Layer00(Layer):
is_event_handler = True
def __init__(self):
super(Layer00, self).__init__()
self.myactor = MyActor("Hello,World!", 0, 0, 32, (0, 200, 255, 255))
self.add(self.myactor)
def on_key_press(self, symbol, modifiers):
if symbol == key.RIGHT:
self.myactor.x += 10
elif symbol == key.LEFT:
self.myactor.x -= 10
elif symbol == key.UP:
self.myactor.y += 10
elif symbol == key.DOWN:
self.myactor.y -= 10
director.init(width=640, height=480)
director.run(scene.Scene(Layer00()))
移動アクション(action_move.py)
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director
from pyglet.window import key
class MyActor(cocos.text.Label):
def __init__(self, text, x, y, size, rgba):
super(MyActor, self).__init__(
text, font_name="Times New Roman", font_size=size,
anchor_x='center', anchor_y='center', color=rgba)
self.position = cocos.euclid.Vector2(x, y)
class Layer00(Layer):
is_event_handler = True
def __init__(self):
super(Layer00, self).__init__()
self.myactor = MyActor("Hello,World!", 0, 0, 32, (0, 200, 255, 255))
self.add(self.myactor)
def on_key_press(self, symbol, modifiers):
if symbol == key.RIGHT:
self.myactor.x += 10
elif symbol == key.LEFT:
self.myactor.x -= 10
elif symbol == key.UP:
self.myactor.y += 10
elif symbol == key.DOWN:
self.myactor.y -= 10
elif symbol == key.SPACE:
self.myactor.do(cocos.actions.MoveBy((200, 100), 2))
elif symbol == key.R:
self.myactor.do(cocos.actions.RotateBy(360, 2))
director.init(width=640, height=480)
director.run(scene.Scene(Layer00()))
ジャンプアクション(action_jump.py)
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director
from pyglet.window import key
class MyActor(cocos.text.Label):
def __init__(self, text, x, y, size, rgba):
super(MyActor, self).__init__(
text, font_name="Times New Roman", font_size=size,
anchor_x='center', anchor_y='center', color=rgba)
self.position = cocos.euclid.Vector2(x, y)
class Layer00(Layer):
is_event_handler = True
def __init__(self):
super(Layer00, self).__init__()
self.myactor = MyActor("Hello,World!", 0, 0, 32, (0, 200, 255, 255))
self.add(self.myactor)
def on_key_press(self, symbol, modifiers):
if symbol == key.RIGHT:
self.myactor.x += 10
elif symbol == key.LEFT:
self.myactor.x -= 10
elif symbol == key.UP:
self.myactor.y += 10
elif symbol == key.DOWN:
self.myactor.y -= 10
elif symbol == key.SPACE:
self.myactor.do(cocos.actions.JumpBy((300, 100), 100, 5, duration=5))
elif symbol == key.S:
self.myactor.do(cocos.actions.ScaleBy(2, duration=1))
director.init(width=640, height=480)
director.run(scene.Scene(Layer00()))
6. まとめ
イベント
イベントとは,ユーザの入力(キーボード操作,マウス操作,ウインドウ操作など)によって発生するものである.Cocos2d では on_key_press,on_mouse_press,on_mouse_motion などのイベントが用意されている.
キーコード
キーコードとは,キーボードの各キーに割り当てられたコード(符号)である.pyglet では key.RIGHT,key.SPACE,key.A などの定数として定義されている.
イベントハンドラ
イベントハンドラとは,特定のイベントが発生したときに実行されるプログラムである.Layer クラスに is_event_handler = True を設定し,on_key_press や on_mouse_press などのメソッドを定義することで実装する.
アクション
アクションとは,オブジェクトの属性を変化させる操作である.即時(InstantAction),インターバル(IntervalAction),その他(Action)の3種類がある.MoveBy,MoveTo,JumpBy,JumpTo,RotateBy,ScaleBy などが代表的である.
do メソッド
オブジェクトにアクションを実行するには do メソッドを使用する.self.myactor.do(cocos.actions.MoveBy((200, 100), 2)) のように記述することで,移動や回転などのアクションを適用できる.