Cocos2d で,オブジェクトの属性を乱数で変化させる

1. エグゼクティブサマリー

Cocos2d は2次元ゲームのフレームワーク.Python で動く.

このWebページでは,次の基本的なことを,見本プログラムで演習する.

本記事では,Python の random モジュールで乱数を生成し,Cocos2d のオブジェクト(文字列や線分)の位置・色・フォントサイズをマウスクリックのたびにランダムに変化させるプログラムを扱う.

関連する資料:Cocos2d の概要 [PDF], [パワーポイント]

関連する資料:ゲームエンジン[PDF], [パワーポイント]

関連する外部ページhttps://www.cocos.com/endoc.html

関連する外部ページhttps://github.com/los-cocos/cocos

謝辞

Cocos2d の作者に感謝します.

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:インストーラーによるインストール

  1. Python 公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする。
  2. ダウンロードしたインストーラーを実行する。
  3. 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから python コマンドを実行できない。
  4. 「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 -U cocos2d pyglet

Windows での cocos2d, pyglet のインストールの詳細は,別ページ »で説明している.

3. 実行のための準備とその確認手順(Windows 前提)

3.1 プログラムファイルの準備

第5章に掲載するソースコードをテキストエディタ(メモ帳,Windsurf 等)に貼り付け,以下のファイル名で保存する(文字コード:UTF-8).

3.2 実行コマンド

コマンドプロンプトでファイルの保存先ディレクトリに移動し,以下を実行する.

実行例:

python label_move.py

3.3 動作確認チェックリスト

確認項目期待される結果
乱数の基本確認(random_test.py)の実行0 以上 1 未満の乱数値が表示される
random.random() * 10 に変更して実行0 以上 10 未満の乱数値が表示される
文字列のランダム移動(label_move.py)の起動640×480 のウィンドウが開き,文字「A」が表示される
ウィンドウ内でマウスクリック(label_move.py)文字「A」がランダムな位置に移動する
線のランダム移動(line_move.py)の起動とマウスクリック線分が表示され,クリックのたびにランダムな位置に移動する
文字列の色のランダム変化(label_color.py)でマウスクリック文字「A」の位置と色が同時にランダムに変化する
フォントサイズのランダム変化(label_fontsize.py)でマウスクリック文字「A」の位置とフォントサイズが同時にランダムに変化する
各プログラムの終了ウィンドウ右上の「x」をクリックすると終了する

4. 概要・使い方・実行上の注意

4.1 乱数

「random.random()」 を「random.random() * 10」に変えると 0 以上 10 未満の乱数になる.

4.2 Cocos2d で文字列の描画,線の描画

Label クラスは,文字や文字列を扱うためのクラスである.次のような属性がある.

Line クラスは,線分を扱うためのクラスである.次のような属性がある.

* サブクラスを定義することで,属性は追加可能である.

4.3 マウスクリックで,文字列のランダム移動

プログラムを実行するとウィンドウが現れる.ウィンドウ内でマウスをクリックすると,オブジェクトがランダムな位置に移動する.何度かマウスをクリックすること.結果を確認したら,右上の「x」をクリックして終了する.

* 演習問題: 上の手順を行いなさい.

4.4 マウスクリックで,線のランダム移動

操作方法は 4.3 節と同様である.マウスをクリックすると線分がランダムな位置に移動する.

* 演習問題: 上の手順を行いなさい.

4.5 マウスクリックで,文字列の色のランダム変化

操作方法は 4.3 節と同様である.マウスをクリックすると,オブジェクトの位置と色が同時にランダムに変化する.

* 演習問題: 上の手順を行いなさい.

4.6 マウスクリックで,文字列のフォントサイズのランダム変化

操作方法は 4.3 節と同様である.マウスをクリックすると,文字「A」の位置とフォントサイズが同時にランダムに変化する.フォントサイズは 8 から 120 の範囲で変化する.

* 演習問題: 上の手順を行いなさい.

5. ソースコード

5.1 乱数の基本確認

import random
random.seed()

print( random.random() )

* 演習問題: 上の手順を行いなさい.

* 演習問題: 「random.random()」 を「random.random() * 10」に変えると 0 以上 10 未満の乱数になることを確認したい.

次のように実行し,結果を確認する.

5.2 マウスクリックで,文字列のランダム移動

import random
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director

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 = (x, y)

class Layer00(Layer):
    is_event_handler = True
    def __init__(self):
        super(Layer00, self).__init__()
        self.myactor = MyActor("A", 0, 0, 32, (0, 200, 255, 255))
        self.add(self.myactor)
    def on_mouse_press(self, x, y, buttons, modifiers):
        self.myactor.x = random.random() * 640
        self.myactor.y = random.random() * 480

director.init(width=640, height=480)
director.run( scene.Scene( Layer00() ) )

5.3 マウスクリックで,線のランダム移動

import random
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director

class MyActor(cocos.draw.Line):
    def __init__(self, x1, y1, x2, y2, rgba):
        super(MyActor, self).__init__( (x1, y1), (x2, y2), rgba )

class Layer00(Layer):
    is_event_handler = True
    def __init__(self):
        super(Layer00, self).__init__()
        self.myactor = MyActor(0, 0, 100, 100, (255, 255, 230, 255))
        self.add(self.myactor)
    def on_mouse_press(self, x, y, buttons, modifiers):
        self.myactor.x = random.random() * 640
        self.myactor.y = random.random() * 480

director.init(width=640, height=480)
director.run( scene.Scene( Layer00() ) )

5.4 マウスクリックで,文字列の色のランダム変化

import random
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director

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 = (x, y)

class Layer00(Layer):
    is_event_handler = True
    def __init__(self):
        super(Layer00, self).__init__()
        self.myactor = MyActor("A", 0, 0, 32, (0, 200, 255, 255))
        self.add(self.myactor)
    def on_mouse_press(self, x, y, buttons, modifiers):
        self.myactor.element.color = ( random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) )
        self.myactor.x = random.random() * 640
        self.myactor.y = random.random() * 480

director.init(width=640, height=480)
director.run( scene.Scene( Layer00() ) )

5.5 マウスクリックで,文字列のフォントサイズのランダム変化

import random
import cocos
from cocos import scene
from cocos.layer import Layer
from cocos.director import director

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 = (x, y)

class Layer00(Layer):
    is_event_handler = True
    def __init__(self):
        super(Layer00, self).__init__()
        self.myactor = MyActor("A", 320, 240, 32, (0, 200, 255, 255))
        self.add(self.myactor)
    def on_mouse_press(self, x, y, buttons, modifiers):
        self.myactor.element.font_size = random.randint(8, 120)
        self.myactor.x = random.random() * 640
        self.myactor.y = random.random() * 480

director.init(width=640, height=480)
director.run( scene.Scene( Layer00() ) )

6. まとめ

6.1 乱数の生成

random.seed() で初期値をタイマーから設定し,random.random() で 0 以上 1 未満の乱数を得る.random.random() * 10 とすれば 0 以上 10 未満の乱数になる.

6.2 イベントハンドラによる属性の変更

Layer クラスで is_event_handler = True と設定し,on_mouse_press メソッドを定義することで,マウスクリック時にオブジェクトの属性値を変更できる.

6.3 位置属性 x, y の乱数による変化

オブジェクトの x, y 値を random.random() * 640,random.random() * 480 で変えることで,クリックのたびに登場物がランダムな位置に移動する.

6.4 色属性 element.color の乱数による変化

Label の element.color に RGBA タプルを設定することで文字列の色を変更できる.各成分を random.randint(0, 255) で生成し,クリックのたびに色をランダムに変化させる.

6.5 フォントサイズ属性 element.font_size の乱数による変化

Label の element.font_size に整数値を設定することでフォントサイズを変更できる.random.randint(8, 120) で値を生成し,クリックのたびにサイズをランダムに変化させる.