Created
January 24, 2020 10:12
-
-
Save kkent030315/a413484da860fc90e4920d3dcb43bcaf to your computer and use it in GitHub Desktop.
PyPixelBox Project Sample03
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#モジュールのインポート | |
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) | |
#後方 | |
self.batch.add(4, GL_QUADS, self.loaded_texture, ('v3f', (x+1, y, z+1, x+1, y, z, x+1, y+1, z, x+1, y+1, z+1,)), texture_coordinates) | |
#下面 | |
self.batch.add(4, GL_QUADS, self.loaded_texture, ('v3f', (x, y, z, x+1, y, z, x+1, y, z+1, x, y, z+1,)), texture_coordinates) | |
#上面 | |
self.batch.add(4, GL_QUADS, self.loaded_texture, ('v3f', (x, y+1, z+1, x+1, y+1, z+1, x+1, y+1, z, x, y+1, z,)), texture_coordinates) | |
#右側 | |
self.batch.add(4, GL_QUADS, self.loaded_texture, ('v3f', (x+1, y, z, x, y, z, x, y+1, z, x+1, y+1, z,)), texture_coordinates) | |
#左側 | |
self.batch.add(4, GL_QUADS, self.loaded_texture, ('v3f', (x, y, z+1, x+1, y, z+1, x+1, y+1, z+1, x, y+1, z+1,)), 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