3次元のゲームエンジン Panda3D を使ってみる
Panda3D は,オープンソースのソフトウェア,3次元ゲーム,可視化,シミュレーションの機能を持つ.
【目次】
- 前準備
- Python3d を用いて画面を開く
- マウス操作
- シーンへの egg 形式ファイルの3次元モデルの読み込み
- 3次元モデルの配置
- キーボードイベントのイベントハンドラ
- マウスイベントのイベントハンドラ
- getX(), setX() などでオブジェクトを動かす
- オブジェクトを自動で動かす
- オブジェクトの速度
【サイト内の関連ページ】
1. 前準備
Python のインストール(Windows上)
注:既にPython(バージョン3.12を推奨)がインストール済みの場合は,この手順は不要である.
winget(Windowsパッケージマネージャー)を使用してインストールを行う
- Windowsで,コマンドプロンプトを管理者権限で起動する(例:Windowsキーを押し,「cmd」と入力し,「管理者として実行」を選択)
- winget(Windowsパッケージマネージャー)が利用可能か確認する:
winget --version
- Pythonのインストール(下のコマンドにより Python 3.12 がインストールされる).
- Python詳細ガイド:Pythonまとめ »
- テキストファイルの中身を次のように書く
テキストエディタを用いてファイルを作成する.* 参考のため,Visual Studio Code で Panda3d を使う手順を別のページで説明している.
from direct.showbase.ShowBase import ShowBase class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 何も無い、黒めの灰色の画面が表示されるので確認する.
結果を確認したら,右上の「x」をクリックして終了.
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 3次元モデルが表示されるので確認する.
- マウス操作
- 左ボタンを押しながらマウスを動かす: 視点移動(上下左右)
- 右ボタンを押しながらマウスを動かす: 視点移動(前後)
結果を確認したら,右上の「x」をクリックして終了.
- c:\Program Files\Python38\lib\site-packages\panda3d\models\environment.egg.pz
- c:\Program Files\Python38\lib\site-packages\panda3d\models\misc\rgbCube.egg.pz ※ misc の下
- c:\Program Files\Python38\lib\site-packages\panda3d\models\ を開くと、「.egg.pz」のファイルがあることを確認
これらは 3次元モデルのファイル
- 今度は、c:\Program Files\Python38\lib\site-packages\panda3d\models\misc\ を開くと、ここにも「.egg.pz」のファイルがあることを確認
- テキストファイルの中身を次のように書き替える
2つの3次元モデルのファイルを読み込むようにする
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube = self.loader.loadModel("models/misc/rgbCube") self.cube.reparentTo(self.render) self.cube.setScale(1, 1, 1) self.cube.setPos(0, 20, 0) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 2つの3次元モデル(竹林と立方体)が表示されるので確認する.
立方体は、画面中央に緑色で現れる
- マウス操作
- 左ボタンを押しながらマウスを動かす: 視点移動(上下左右)
- 右ボタンを押しながらマウスを動かす: 視点移動(前後)
結果を確認したら,右上の「x」をクリックして終了.
- プログラムでは「scene」,「cube1」, 「cube2」という名前のオブジェクトを作成
- setPos( <x値>, <y値>, <z値>) 既定のカメラから見たとき、x は左右、y は前奥, z は上下
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube1 = self.loader.loadModel("models/misc/rgbCube") self.cube1.reparentTo(self.render) self.cube1.setScale(1, 1, 1) self.cube1.setPos(0, 20, 0) self.cube2 = self.loader.loadModel("models/misc/rgbCube") self.cube2.reparentTo(self.render) self.cube2.setScale(1, 1, 1) self.cube2.setPos(5, 20, 0) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 立方体は 2つ表示されるので確認する.
- マウス操作
- 左ボタンを押しながらマウスを動かす: 視点移動(上下左右)
- 右ボタンを押しながらマウスを動かす: 視点移動(前後)
結果を確認したら,右上の「x」をクリックして終了.
- プログラムでは「scene」,「cube1」, 「cube2」という名前のオブジェクトを作成
- setScale( <スケール値> ) 拡大縮小
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube1 = self.loader.loadModel("models/misc/rgbCube") self.cube1.reparentTo(self.render) self.cube1.setScale(1, 1, 1) self.cube1.setPos(0, 20, 0) self.cube2 = self.loader.loadModel("models/misc/rgbCube") self.cube2.reparentTo(self.render) self.cube2.setScale(1, 1, 1) self.cube2.setPos(5, 20, 0) self.cube2.setScale(2.4) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 右側の立方体は 2.4 倍に拡大されるので確認する.
- マウス操作
- 左ボタンを押しながらマウスを動かす: 視点移動(上下左右)
- 右ボタンを押しながらマウスを動かす: 視点移動(前後)
結果を確認したら,右上の「x」をクリックして終了.
- プログラムでは「scene」,「cube1」, 「cube2」という名前のオブジェクトを作成
- setQuat( <クオータニオン> ) 回転
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube1 = self.loader.loadModel("models/misc/rgbCube") self.cube1.reparentTo(self.render) self.cube1.setScale(1, 1, 1) self.cube1.setPos(0, 20, 0) self.cube2 = self.loader.loadModel("models/misc/rgbCube") self.cube2.reparentTo(self.render) self.cube2.setScale(1, 1, 1) self.cube2.setPos(5, 20, 0) self.cube2.setQuat( Quat( 0, 1, 1, 1 ) ) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 右側の立方体は回転しているので確認する.
- マウス操作
- 左ボタンを押しながらマウスを動かす: 視点移動(上下左右)
- 右ボタンを押しながらマウスを動かす: 視点移動(前後)
結果を確認したら,右上の「x」をクリックして終了.
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube = self.loader.loadModel("models/misc/rgbCube") self.cube.reparentTo(self.render) self.cube.setScale(1, 1, 1) self.cube.setPos(0, 20, 0) self.cube.setQuat( Quat( 0, 1, 1, 1 ) ) self.accept( "a", self.a_key ) def a_key(self): self.cube.setScale(2) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 立方体が表示されるので確認する
- キーボードの「A」キーを押すと、大きな立方体に変わるので確認する
結果を確認したら,右上の「x」をクリックして終了.
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube = self.loader.loadModel("models/misc/rgbCube") self.cube.reparentTo(self.render) self.cube.setScale(1, 1, 1) self.cube.setPos(0, 20, 0) self.cube.setQuat( Quat( 0, 1, 1, 1 ) ) self.accept( "mouse1", self.mouse1 ) self.accept( "mouse3", self.mouse3 ) def mouse1(self): self.cube.setScale(2) def mouse3(self): self.cube.setScale(0.5) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 立方体が表示されるので確認する
- マウスの右ボタンをクリックすると、小さな立方体に変わるので確認する
- マウスの左ボタンをクリックすると、大きな立方体に変わるので確認する
結果を確認したら,右上の「x」をクリックして終了.
- getX(), getY(), getZ() : オブジェクトの場所を知る
- setX(), setY(), setZ() : オブジェクトの場所を変える
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube = self.loader.loadModel("models/misc/rgbCube") self.cube.reparentTo(self.render) self.cube.setScale(1, 1, 1) self.cube.setPos(0, 20, 0) self.cube.setQuat( Quat( 0, 1, 1, 1 ) ) self.accept( "arrow_up", self.up_key ) self.accept( "arrow_down", self.down_key ) self.accept( "arrow_right", self.right_key ) self.accept( "arrow_left", self.left_key ) def up_key(self): self.cube.setZ( self.cube.getZ() + 1 ) def down_key(self): self.cube.setZ( self.cube.getZ() - 1 ) def right_key(self): self.cube.setX( self.cube.getX() + 1 ) def left_key(self): self.cube.setX( self.cube.getX() - 1 ) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 立方体が表示されるので確認する
- キーボードの矢印キー(上、下、右、左)でオブジェクトが移動するので確認する.
結果を確認したら,右上の「x」をクリックして終了.
- self.taskMgr.add() : フレームごとに呼び出すメソッドの指定
- self.ball.setPos(0, 20, task.time * 0.2) 立方体の位置を少しずつ上へ
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat from direct.task import Task class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube = self.loader.loadModel("models/misc/rgbCube") self.cube.reparentTo(self.render) self.cube.setScale(1, 1, 1) self.cube.setPos(0, 20, 0) self.cube.setQuat( Quat( 0, 1, 1, 1 ) ) self.taskMgr.add(self.cubeMotionTask, "CubeMotionTask") def cubeMotionTask(self, task): self.cube.setPos(0, 20, task.time * 0.2) return Task.cont app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- オブジェクトが自動で移動するので確認する.
結果を確認したら,右上の「x」をクリックして終了.
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat from direct.task import Task class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 0) self.cube = self.loader.loadModel("models/misc/rgbCube") self.cube.reparentTo(self.render) self.cube.setScale(1, 1, 1) self.cube.setPos(0, 20, 0) self.cube.setQuat( Quat( 0, 1, 1, 1 ) ) self.previous_time = 0 self.x = 0 self.y = 20 self.z = 0 self.vx = 0 self.vy = 0 self.vz = 0 self.accept( "arrow_up", self.up_key ) self.accept( "arrow_down", self.down_key ) self.accept( "arrow_right", self.right_key ) self.accept( "arrow_left", self.left_key ) self.taskMgr.add(self.cubeMotionTask, "CubeMotionTask") def cubeMotionTask(self, task): self.x += self.vx * (task.time - self.previous_time) self.y += self.vy * (task.time - self.previous_time) self.z += self.vz * (task.time - self.previous_time) self.cube.setPos(self.x, self.y, self.z) self.previous_time = task.time return Task.cont def up_key(self): self.vz = self.vz + 1 def down_key(self): self.vz = self.vz - 1 def right_key(self): self.vx = self.vx + 1 def left_key(self): self.vx = self.vx - 1 app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 立方体が表示されるので確認する
- キーボードの矢印キー(上、下、右、左)でオブジェクトが移動するので確認する.
結果を確認したら,右上の「x」をクリックして終了.
- テキストファイルの中身を次のように書き替える
from direct.showbase.ShowBase import ShowBase from direct.showbase.Loader import Loader from panda3d.core import Quat from pandac.PandaModules import CollisionTraverser, CollisionHandlerPusher from pandac.PandaModules import CollisionNode, CollisionSphere class HelloWorld(ShowBase): def __init__(self): ShowBase.__init__(self) base.cTrav = CollisionTraverser() self.pusher = CollisionHandlerPusher() self.scene = self.loader.loadModel("models/environment") self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, -5) self.cube1 = self.loader.loadModel("models/misc/rgbCube") self.cube1.reparentTo(self.render) self.cube1.setScale(1, 1, 1) self.cube1.setPos(-6, 20, 0) self.cube1.setQuat( Quat( 0, 1, 1, 0 ) ) c = CollisionNode('Cube1') c.addSolid(CollisionSphere(0, 0, 0, 0.6)) cube1_c = self.cube1.attachNewNode(c) self.cube2 = self.loader.loadModel("models/misc/rgbCube") self.cube2.reparentTo(self.render) self.cube2.setScale(1, 1, 1) self.cube2.setPos(-3, 20, 0) self.cube2.setQuat( Quat( 0, 1, 1, 0.2 ) ) c = CollisionNode('Cube2') c.addSolid(CollisionSphere(0, 0, 0, 0.6)) cube2_c = self.cube2.attachNewNode(c) self.cube3 = self.loader.loadModel("models/misc/rgbCube") self.cube3.reparentTo(self.render) self.cube3.setScale(1, 1, 1) self.cube3.setPos(0, 20, 0) self.cube3.setQuat( Quat( 0, 1, 1, 0.4 ) ) c = CollisionNode('Cube3') c.addSolid(CollisionSphere(0, 0, 0, 0.6)) cube3_c = self.cube3.attachNewNode(c) self.cube4 = self.loader.loadModel("models/misc/rgbCube") self.cube4.reparentTo(self.render) self.cube4.setScale(1, 1, 1) self.cube4.setPos(3, 20, 0) self.cube4.setQuat( Quat( 0, 1, 1, 0.6 ) ) c = CollisionNode('Cube4') c.addSolid(CollisionSphere(0, 0, 0, 0.6)) cube4_c = self.cube4.attachNewNode(c) self.cube5 = self.loader.loadModel("models/misc/rgbCube") self.cube5.reparentTo(self.render) self.cube5.setScale(1, 1, 1) self.cube5.setPos(6, 20, 0) self.cube5.setQuat( Quat( 0, 1, 1, 0.8 ) ) c = CollisionNode('Cube5') c.addSolid(CollisionSphere(0, 0, 0, 0.6)) cube5_c = self.cube5.attachNewNode(c) self.player = self.loader.loadModel("models/misc/rgbCube") self.player.reparentTo(self.render) self.player.setScale(1, 1, 1) self.player.setPos(0, 15, 0) c = CollisionNode('Player') c.addSolid(CollisionSphere(0, 0, 0, 0.6)) player_c = self.player.attachNewNode(c) self.accept( "arrow_up", self.up_key ) self.accept( "arrow_down", self.down_key ) self.accept( "arrow_right", self.right_key ) self.accept( "arrow_left", self.left_key ) base.cTrav.addCollider(cube1_c, self.pusher) base.cTrav.addCollider(cube2_c, self.pusher) base.cTrav.addCollider(cube3_c, self.pusher) base.cTrav.addCollider(cube4_c, self.pusher) base.cTrav.addCollider(cube5_c, self.pusher) base.cTrav.addCollider(player_c, self.pusher) self.pusher.addCollider(cube1_c, self.cube1, base.drive.node()) self.pusher.addCollider(cube2_c, self.cube2, base.drive.node()) self.pusher.addCollider(cube3_c, self.cube3, base.drive.node()) self.pusher.addCollider(cube4_c, self.cube4, base.drive.node()) self.pusher.addCollider(cube5_c, self.cube5, base.drive.node()) self.pusher.addCollider(player_c, self.player, base.drive.node()) def up_key(self): self.player.setY( self.player.getY() + 1 ) def down_key(self): self.player.setY( self.player.getY() - 1 ) def right_key(self): self.player.setX( self.player.getX() + 1 ) def left_key(self): self.player.setX( self.player.getX() - 1 ) app = HelloWorld() app.run()
- テキストファイルを,保存する.
ファイル名は何でもよいが、日本語などの全角文字は避ける.拡張子は「.py」にする.
- Python プログラムの実行
cd <先ほど保存したディレクトリ> python hoge.py
- 矢印キーの操作によりオブジェクトを動かす.オブジェクトが他のオブジェクトに衝突すると動く.
【関連する外部サイト】
【サイト内の関連ページ】
2. Python3d を用いて画面を開く
演習問題:上の手順で画面を開きなさい
3. マウス操作
プログラムでは「scene」という名前のオブジェクトを作成
演習問題:上の手順で3次元モデルを表示しなさい.マウス操作も行いなさい.
4. シーンへの egg 形式ファイルの3次元モデルの読み込み
egg 形式ファイルの3次元モデルである次の2つのファイルを読み込み
演習問題:上の手順で3次元モデルを表示しなさい.マウス操作も行いなさい.
演習問題:次のように書き換えて、実行結果を確認する。今度は、真っ白の球が表示される
self.cube = self.loader.loadModel("models/misc/sphere")
self.cube.reparentTo(self.render)
self.cube.setScale(1, 1, 1)
self.cube.setPos(0, 20, 0)


5. 3次元モデルの配置
位置を変えて配置
演習問題:上の手順で2つの立方体を表示しなさい.マウス操作も行いなさい.
setScale() で拡大縮小
演習問題:上の手順で2つの立方体を表示しなさい.マウス操作も行いなさい.
演習問題の2:倍率の違う 5つの立方体を表示する次のプログラムを実行し、結果を確認する
from direct.showbase.ShowBase import ShowBase
from direct.showbase.Loader import Loader
class HelloWorld(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.scene = self.loader.loadModel("models/environment")
self.scene.reparentTo(self.render)
self.scene.setScale(1, 1, 1)
self.scene.setPos(0, 0, 0)
self.cube1 = self.loader.loadModel("models/misc/rgbCube")
self.cube1.reparentTo(self.render)
self.cube1.setScale(1, 1, 1)
self.cube1.setPos(-6, 20, 0)
self.cube1.setScale(0.2)
self.cube1 = self.loader.loadModel("models/misc/rgbCube")
self.cube1.reparentTo(self.render)
self.cube1.setScale(1, 1, 1)
self.cube1.setPos(-3, 20, 0)
self.cube1.setScale(0.6)
self.cube1 = self.loader.loadModel("models/misc/rgbCube")
self.cube1.reparentTo(self.render)
self.cube1.setScale(1, 1, 1)
self.cube1.setPos(0, 20, 0)
self.cube1.setScale(1.0)
self.cube1 = self.loader.loadModel("models/misc/rgbCube")
self.cube1.reparentTo(self.render)
self.cube1.setScale(1, 1, 1)
self.cube1.setPos(3, 20, 0)
self.cube1.setScale(1.4)
self.cube1 = self.loader.loadModel("models/misc/rgbCube")
self.cube1.reparentTo(self.render)
self.cube1.setScale(1, 1, 1)
self.cube1.setPos(6, 20, 0)
self.cube1.setScale(1.8)
app = HelloWorld()
app.run()


setQuat() で回転
egg 形式ファイルの3次元モデルである c:\Program Files\Python38\lib\site-packages\panda3d\models\misc\rgbCube.egg も読み込む
演習問題:上の手順で2つの立方体を表示しなさい.マウス操作も行いなさい.
演習問題の2:setQuat に設定した値の違う 5つの立方体を表示する次のプログラムを実行し、結果を確認する
from direct.showbase.ShowBase import ShowBase
from direct.showbase.Loader import Loader
from panda3d.core import Quat
class HelloWorld(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.scene = self.loader.loadModel("models/environment")
self.scene.reparentTo(self.render)
self.scene.setScale(1, 1, 1)
self.scene.setPos(0, 0, 0)
self.cube1 = self.loader.loadModel("models/misc/rgbCube")
self.cube1.reparentTo(self.render)
self.cube1.setScale(1, 1, 1)
self.cube1.setPos(-6, 20, 0)
self.cube1.setQuat( Quat( 0, 1, 1, 0 ) )
self.cube2 = self.loader.loadModel("models/misc/rgbCube")
self.cube2.reparentTo(self.render)
self.cube2.setScale(1, 1, 1)
self.cube2.setPos(-3, 20, 0)
self.cube2.setQuat( Quat( 0, 1, 1, 0.2 ) )
self.cube3 = self.loader.loadModel("models/misc/rgbCube")
self.cube3.reparentTo(self.render)
self.cube3.setScale(1, 1, 1)
self.cube3.setPos(0, 20, 0)
self.cube3.setQuat( Quat( 0, 1, 1, 0.4 ) )
self.cube4 = self.loader.loadModel("models/misc/rgbCube")
self.cube4.reparentTo(self.render)
self.cube4.setScale(1, 1, 1)
self.cube4.setPos(3, 20, 0)
self.cube4.setQuat( Quat( 0, 1, 1, 0.6 ) )
self.cube5 = self.loader.loadModel("models/misc/rgbCube")
self.cube5.reparentTo(self.render)
self.cube5.setScale(1, 1, 1)
self.cube5.setPos(6, 20, 0)
self.cube5.setQuat( Quat( 0, 1, 1, 0.8 ) )
app = HelloWorld()
app.run()


キーボードイベントのイベントハンドラ
キーコードの種類 "A", "space", "enter", "arrow_left", "arrow_up", "arrow_down", "arrow_right" など
演習問題:上の手順で立方体を表示しなさい.キーボードの「A」キーを押す操作も行いなさい.
演習問題の2: スペースキーに反応するように、プログラムを次のように書き換えて実行しなさい
self.accept( "space", self.space_key )
def space_key(self):
self.cube.setScale(5)


マウスイベントのイベントハンドラ
マウスボタンのコード "mouse1", "mouse2", "mouse3"
演習問題:上の手順で立方体を表示しなさい.右と左のマウスボタンを押す操作も行いなさい.
getX(), setX() などでオブジェクトを動かす
演習問題:上の手順で立方体を表示しなさい. キーボードの矢印キー(上、下、右、左)でオブジェクトが移動するので確認する
オブジェクトを自動で動かす
演習問題:上の手順で立方体を表示しなさい. 動くことを確認する
オブジェクトの速度
演習問題:上の手順で立方体を表示しなさい. キーボードの矢印キー(上、下、右、左)でオブジェクトが移動するので確認する