Skip to content

Instantly share code, notes, and snippets.

@kkent030315
Created January 24, 2020 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkent030315/2f19c8e9ed1b4e07b4f54b1657ecd6bf to your computer and use it in GitHub Desktop.
Save kkent030315/2f19c8e9ed1b4e07b4f54b1657ecd6bf to your computer and use it in GitHub Desktop.
PyPixelBox Project Sample02 Player
#モジュールのインポート
from pyglet.gl import *
#キーインプット
from pyglet.window import key
#プレイヤーの視野計算に使う
import math
#imgui
import imgui
from imgui.integrations.pyglet import PygletRenderer
#ワールドクラス
class World:
def __init__(self):
#Vertexを保管する場所
self.batch = pyglet.graphics.Batch()
#3次元ワールド座標を定義
x = 0
y = 0
z = -1
#テクスチャーをロード
self.loaded_texture = self.load_texture('texture.png')
texture_coordinates = ('t2f', (0, 0,
1, 0,
1, 1,
0, 1,))
#バッチ(Vertexリスト)に追加
self.batch.add(4, GL_QUADS, self.loaded_texture,
('v3f', (x, y, z,
x, y, z+1,
x, y+1, z+1,
x, y+1, z,)), texture_coordinates)
#描画を行う
def draw(self):
self.batch.draw()#バッチの中にあるVertexを全て描画
#テクスチャをロードする関数
def load_texture(self, path):
texture = pyglet.image.load(path).get_texture()#pygletのテクスチャローダーを使います
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
return pyglet.graphics.TextureGroup(texture)
#プレイヤークラス
class Player:
def __init__(self, position=(0, 0, 0), rotation=(0, 0)):
#現在位置
self.position = list(position)
#ローテーション
self.rotation = list(rotation)
#マウスが動いた時に情報を受け取る
def on_mouse_motion(self, dx, dy):
sensitivity = 0.2
self.rotation[0] += dy * sensitivity
self.rotation[1] -= dx * sensitivity
dx /= 8
dy /= 8
if self.rotation[0] > 90:
self.rotation[0] = 90
elif self.rotation[0] < -90:
self.rotation[0] = -90
def update(self, dt, keys):
s = dt * 10
rotation_y = -self.rotation[1] / 180 * math.pi
dx = s * math.sin(rotation_y)
dz = s * math.cos(rotation_y)
if keys[key.W]:
self.position[0] += dx
self.position[2] -= dz
if keys[key.S]:
self.position[0] -= dx
self.position[2] += dz
if keys[key.A]:
self.position[0] -= dz
self.position[2] -= dx
if keys[key.D]:
self.position[0] += dz
self.position[2] += dx
if keys[key.SPACE]:
self.position[1] += s
if keys[key.LSHIFT]:
self.position[1] -= s
#pyglet.window.Window を継承
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
#ワールドクラスの初期化
self.world = World()
#キーハンドラの初期化
self.keys = key.KeyStateHandler()
#キーハンドラを登録
self.push_handlers(self.keys)
#プレイヤーの初期化。初期位置/初期ローテーション
self.player = Player((0.5, 1.5, 1.5), (-30, 0))
#update関数のスケジューリング
pyglet.clock.schedule(self.update)
#imgui
imgui.create_context()
self.impl = PygletRenderer(self)
self.imgui_io = imgui.get_io()
#アップデート時に呼ばれるイベント
def update(self, dt):
#プレイヤーのアップデート
self.player.update(dt, self.keys)
#マウスを動かした時に呼ばれるイベント
def on_mouse_motion(self, x, y, dx, dy):
if self.mouse_lock:
#情報をPlayerクラスに渡す
self.player.on_mouse_motion(dx, dy)
#キーが押された時に呼ばれるイベント
def on_key_press(self, KEY, MOD):
#ESCが押された時に
if KEY == key.ESCAPE:
#マウスカーソルの確保状態を反転させる
self.mouse_lock = not self.mouse_lock
#カメラ視点をアップデート
def update_camera(self, position, rotation):
glPushMatrix()
glRotatef(-rotation[0], 1, 0, 0)
glRotatef(-rotation[1], 0, 1, 0)
glTranslatef(-position[0], -position[1], -position[2], )
def mouse_lock(self, enable):
#マウスをハイド(キャッチ)
self.set_exclusive_mouse(enable)
#マウスをキャッチしているかどうかのフラグ
self.mouse_grabbed = enable
mouse_grabbed = False
mouse_lock = property(lambda self: self.mouse_grabbed, mouse_lock)
def on_draw(self):
#スクリーンをクリア
self.clear()
#imgui
imgui.new_frame()
imgui.set_next_window_position(-1, -1, 1) # 1=cond_always
imgui.begin("Debug", False, 64) # 64=alwaysAutoResize
imgui.text_colored("FPS: " + str(int(self.imgui_io.framerate)), 0.2, 1., 0.)
imgui.text("player_position: " + str(self.player.position))
imgui.text("player_rotation: " + str(self.player.rotation))
imgui.end()
imgui.end_frame()
imgui.render()
self.impl.render(imgui.get_draw_data())
#ワールドは3次元なので、3D描画モードに設定
self.render_mode_3d()
#カメラ視点のアップデート
self.update_camera(self.player.position, self.player.rotation)
#ワールドを描画
self.world.draw()
glPopMatrix()
def render_mode_3d(self):
self.render_mode_projection()
#視野を設定
gluPerspective(70, self.width / self.height, 0.05, 1000)
self.render_mode_modelview()
def render_mode_2d(self):
self.render_mode_projection()
#描画領域 0からwindow_width、 0からwindow_height
gluOrtho2D(0, self.width, 0, self.height)
self.render_mode_modelview()
def render_mode_projection(self):
glMatrixMode(GL_PROJECTION)#投影変換モード
glLoadIdentity()#変換処理の累積を消去
def render_mode_modelview(self):
glMatrixMode(GL_MODELVIEW)#モデリング変換モード(視野変換)
glLoadIdentity()#変換処理の累積を消去
if __name__ == '__main__':
window = Window(width=1280, height=720, caption='PyPixelBox', resizable=True)
glClearColor(0.5, 0.7, 1, 1)#クリア時の色を空色に設定
pyglet.app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment