示例#1
0
    def make_editor_gui(self):     # called by main after setting up camera and application.development_mode
        from ursina import camera, Text, Button, ButtonList, Func, Tooltip
        import time

        self.editor_ui = Entity(parent=camera.ui, eternal=True, enabled=bool(application.development_mode))
        self.exit_button = Button(parent=self.editor_ui, eternal=True, ignore_paused=True, origin=(.5, .5),
            position=self.top_right, z=-999, scale=(.05, .025), color=color.red.tint(-.2), text='x', on_click=application.quit)
        self.exit_button.enabled = self.borderless


        def _exit_button_input(key):
            from ursina import held_keys, mouse
            if held_keys['shift'] and key == 'q' and not mouse.right:
                self.exit_button.on_click()
        self.exit_button.input = _exit_button_input

        self.fps_counter = Text(parent=self.editor_ui, eternal=True, position=(.5*self.aspect_ratio, .47, -999), origin=(.8,.5), text='60', ignore=False, i=0)

        def _fps_counter_update():
            if self.fps_counter.i > 60:
                self.fps_counter.text = str(int(1//time.dt))
                self.fps_counter.i = 0
            self.fps_counter.i += 1
        self.fps_counter.update = _fps_counter_update


        import webbrowser
        self.cog_menu = ButtonList({
            # 'Build' : Func(print, ' '),
            'API Reference' : Func(webbrowser.open, 'https://www.ursinaengine.org/cheat_sheet_dark.html'),
            'Asset Store' : Func(webbrowser.open, 'https://itch.io/tools/tag-ursina'),
            # 'Open Scene Editor' : Func(print, ' '),
            'Change Render Mode <gray>[F10]<default>' : self.next_render_mode,
            'Reset Render Mode <gray>[F9]<default>' : Func(setattr, self, 'render_mode', 'default'),
            'Reload Models <gray>[F7]<default>' : application.hot_reloader.reload_models,
            'Reload Textures <gray>[F6]<default>' : application.hot_reloader.reload_textures,
            'Reload Code <gray>[F5]<default>' : application.hot_reloader.reload_code,
        },
            width=.35,
            x=.62,
            enabled=False,
            eternal=True
        )
        self.cog_menu.on_click = Func(setattr, self.cog_menu, 'enabled', False)
        self.cog_menu.y = -.5 + self.cog_menu.scale_y
        self.cog_menu.scale *= .75
        self.cog_menu.text_entity.x += .025
        self.cog_menu.highlight.color = color.azure
        self.cog_button = Button(parent=self.editor_ui, eternal=True, model='circle', scale=.015, origin=(1,-1), position=self.bottom_right)
        info_text ='''This menu is not enabled in builds <gray>(unless you set application.development to be not False).'''
        self.cog_menu.info = Button(parent=self.cog_menu, model='quad', text='<gray>?', scale=.1, x=1, y=.01, origin=(.5,-.5), tooltip=Tooltip(info_text, scale=.75, origin=(-.5,-.5)))
        self.cog_menu.info.text_entity.scale *= .75
        def _toggle_cog_menu():
            self.cog_menu.enabled = not self.cog_menu.enabled
        self.cog_button.on_click = _toggle_cog_menu
示例#2
0
    def layout(self):
        [destroy(c) for c in self.buttons]
        self.buttons = []
        spacing = .05
        longest_word = max(self.options, key=len) + '__'  # padding
        width = Text.get_width(longest_word) / Text.size / 2

        for e in self.options:
            b = Button(parent=self, text=e, name=e, scale_x=width, scale_y=.9)
            b.value = e
            b.highlight_scale = 1
            b.pressed_scale = 1
            self.buttons.append(b)

        grid_layout(self.buttons, spacing=(0.025, 0, 0), origin=(-.5, .5, 0))
示例#3
0
 def __init__(self, gameController):
     super().__init__(
         title='Menu',
         content=(
             Button(text='Restart',
                    color=color.azure,
                    on_click=self.restart),
             Button(text='Exit',
                    color=color.azure,
                    on_click=application.quit),
         ),
     )
     self.hardRestart = False
     self.gameController = gameController
     self.ec = EditorCamera(rotation_smoothing=2,
                            enabled=False,
                            rotation=(30, 30, 0))
     self.ec.enabled = False
     self.cur = Cursor()
     self.cur.disable()
     self.hide()
示例#4
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self.phoneme_store = None
     self.voxels = []
     self.correct = False
     self.started = False
     self.update_counter = None
     self.score = 0
     self.difficulty = 3     # lower difficulty is harder
     self.help_text = Text(
         '',
         parent=camera.ui,
         x=-.6,
         y=.35,
         enabled=False
     )
     self.score_text = Text(
         '',
         parent=camera.ui,
         x=.5,
         y=.35,
         enabled=False
     )
     self.player = None
     self.ground = Entity(model='plane', scale=(100, 1, 100), y=-1, color=color.yellow.tint(-.2), texture='white_cube',
                          texture_scale=(100, 100), collider='box', enabled=False)
     self.sky = Entity(model='sphere', texture='sky2.jpg', scale=10000, double_sided=True, color=color.white, enabled=False)
     self.rotated_y = 30
     self.next_block = Entity(parent=camera.ui, rotation=Vec3(10, 30, 30), model='cube', scale=.1, x=.7, y=.2, texture='index')
     self.give_up_button = Button(parent=scene, text='give up', double_sided=True, x=-1, z=ARENA_DEPTH, y=3, on_click=self.give_up, enabled=False, scale_x=2)
     self.reset_text = Text(
         'Press ESC to change words and/or start again.',
         parent=scene,
         x=0, z=ARENA_DEPTH, y=2,
         double_sided=True,
         enabled=False,
         scale=15
     )
示例#5
0
    def __init__(self, title='', content=[], **kwargs):
        super().__init__(origin=(-0,.5), scale=(.5, Text.size*2), color=color.black)

        self.content = content
        self.text = title
        self.popup = False
        self._prev_input_field = None
        self._original_scale = self.scale

        for key, value in kwargs.items():
            setattr(self, key ,value)

        if self.text_entity:
            self.text_entity.world_scale_y = 1

        self.panel = Entity(parent=self, model='quad', origin=(0,.5), z=.1, color=self.color.tint(.1), collider='box')

        if self.popup:
            self.lock = Vec3(1,1,1)
            self.bg = Button(parent=self, z=1, scale=(999, 999), color=color.black66, highlight_color=color.black66, pressed_color=color.black66)
            self.bg.on_click = self.close

        self.layout()
示例#6
0
class MainGame(Entity):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.phoneme_store = None
        self.voxels = []
        self.correct = False
        self.started = False
        self.update_counter = None
        self.score = 0
        self.difficulty = 3     # lower difficulty is harder
        self.help_text = Text(
            '',
            parent=camera.ui,
            x=-.6,
            y=.35,
            enabled=False
        )
        self.score_text = Text(
            '',
            parent=camera.ui,
            x=.5,
            y=.35,
            enabled=False
        )
        self.player = None
        self.ground = Entity(model='plane', scale=(100, 1, 100), y=-1, color=color.yellow.tint(-.2), texture='white_cube',
                             texture_scale=(100, 100), collider='box', enabled=False)
        self.sky = Entity(model='sphere', texture='sky2.jpg', scale=10000, double_sided=True, color=color.white, enabled=False)
        self.rotated_y = 30
        self.next_block = Entity(parent=camera.ui, rotation=Vec3(10, 30, 30), model='cube', scale=.1, x=.7, y=.2, texture='index')
        self.give_up_button = Button(parent=scene, text='give up', double_sided=True, x=-1, z=ARENA_DEPTH, y=3, on_click=self.give_up, enabled=False, scale_x=2)
        self.reset_text = Text(
            'Press ESC to change words and/or start again.',
            parent=scene,
            x=0, z=ARENA_DEPTH, y=2,
            double_sided=True,
            enabled=False,
            scale=15
        )

    def create_clouds(self):
        self.sky.enable()
        for i in range(20):
            cloud = Entity(parent=scene, model='cube', texture='index', scale_x=random.randint(2, ARENA_DEPTH), scale_y=random.randint(1, 6), scale_z=random.randint(2, ARENA_DEPTH), color=color.white, position=Vec3(random.randint(-50, ARENA_DEPTH+50), random.randint(10, 50), random.randint(-50, ARENA_DEPTH+50)))
            self.voxels.append(cloud)

    def give_up(self):
        self.score -= 1
        if self.phoneme_store.words:
            self.build()
        else:
            self.end_game()

    def end_game(self):
        self.destroy_all()
        self.build_platform()
        self.correct = False
        self.update_counter = None
        self.update_score()
        if self.score > 0:
            self.help_text.text = f'GAME OVER! YOU WIN!\nYour score: {self.score}'
        else:
            self.help_text.text = f'GAME OVER! YOU LOSE!\nYour score: {self.score}'

    def reset(self):
        pass

    def build(self):
        self.started = True
        word = self.phoneme_store.get_new_word()
        self.update_counter = 0
        if self.give_up_button.enabled:
            self.give_up_button.disable()
        if self.reset_text.enabled:
            self.reset_text.disable()
        if word is not None:
            if self.phoneme_store.pron() is not None:
                self.help_text.text = f'The word is: "{self.phoneme_store.word}"\nLeft click in the green area to lay a phoneme,\nright click to pick one up.'
                self.help_text.enable()
                self.score_text.text = f'Score: {self.score}'
                self.score_text.enable()
                if self.voxels:
                    self.destroy_all()
                    self.help_text.text = self.phoneme_store.word
                    self.correct = False
                for z in range(ARENA_DEPTH + 1):
                    voxel_side_wall = Voxel(self.phoneme_store, self, position=(-1, 1, z))
                    voxel_other_side_wall = Voxel(self.phoneme_store, self, position=(len(self.phoneme_store.phonemes), 1, z))
                    self.voxels.append(voxel_side_wall)
                    self.voxels.append(voxel_other_side_wall)
                    for x in range(len(self.phoneme_store.phonemes)):
                        voxel = Voxel(self.phoneme_store, self, position=(x, 0, z))
                        voxel_wall = Voxel(self.phoneme_store, self, position=(x, 1, -1))
                        self.voxels.append(voxel)
                        self.voxels.append(voxel_wall)
                        if voxel.position[2] == ARENA_DEPTH:
                            voxel.color = color.lime
                            voxel.texture = 'white_cube'
                invoke(self.create_clouds, delay=0.1)
                if self.player:
                    self.player.y = 0
                    self.player.x = len(self.phoneme_store.phonemes) // 2
                    self.player.z = 1
                else:
                    self.generate_player()
            else:
                return self.build()
        else:
            self.end_game()


    def build_platform(self):

        self.ground.enable()
        self.update_counter = None
        self.reset_text.enable()
        self.give_up_button.disable()
        self.create_clouds()
        self.started = False

    def update_score(self):
        self.score_text.text = f'Score: {self.score}'

    def destroy_all(self):
        for v in self.voxels:
            destroy(v)
        self.voxels = []

    def generate_player(self):
        self.player = FirstPersonController(enabled=True)
        self.player.speed += 2
        self.player.mouse_sensitivity = Vec2(50, 50)
        self.player.jump_duration = .3
        self.player.gravity *= .8
        self.player.y = 0
        self.player.x = len(self.phoneme_store.phonemes) // 2
        self.player.z = 1

    def spin_block(self):
        self.rotated_y -= 1
        self.next_block.rotation = Vec3(10, self.rotated_y, 30)
示例#7
0
文件: window.py 项目: re-mc/ursina
class Window(WindowProperties):
    def __init__(self):
        super().__init__()
        loadPrcFileData('', 'window-title ursina')
        loadPrcFileData('', 'notify-level-util error')
        loadPrcFileData('', 'textures-auto-power-2 #t')
        loadPrcFileData('', 'load-file-type p3assimp')
        # loadPrcFileData('', 'allow-portal-cull #t')
        # loadPrcFileData("", "framebuffer-multisample 1")
        # loadPrcFileData('', 'multisamples 2')
        # loadPrcFileData('', 'textures-power-2 none')

        # loadPrcFileData('', 'cursor-filename mycursor.ico')
        # loadPrcFileData('', 'threading-model Cull/Draw')
        loadPrcFileData('', 'coordinate-system y-up-left')

        # fallback to one of these if opengl is not supported
        loadPrcFileData('', 'aux-display pandadx9')
        loadPrcFileData('', 'aux-display pandadx8')
        loadPrcFileData('', 'aux-display tinydisplay')

        self.setForeground(True)
        self.vsync = True  # can't be set during play
        self.show_ursina_splash = False

        self.title = application.asset_folder.name
        if os.name == 'nt':  # windows
            import ctypes
            user32 = ctypes.windll.user32
            user32.SetProcessDPIAware()
            self.screen_resolution = (user32.GetSystemMetrics(0),
                                      user32.GetSystemMetrics(1))

        else:
            try:
                from screeninfo import get_monitors
                self.screen_resolution = (get_monitors()[0].width,
                                          get_monitors()[0].height)
                print('OS:', os.name)
            except:
                print('using default sceen resolution.', 'OS:', os.name)
                self.screen_resolution = Vec2(1366, 768)

        print('screen resolution:', self.screen_resolution)
        self.fullscreen_size = Vec2(self.screen_resolution[0] + 1,
                                    self.screen_resolution[1] + 1)
        self.windowed_size = self.fullscreen_size / 1.25
        self.windowed_position = None  # gets set when entering fullscreen so position will be correct when going back to windowed mode
        self.size = self.windowed_size
        self.borderless = True

        self.top = Vec2(0, .5)
        self.bottom = Vec2(0, -.5)
        self.center = Vec2(0, 0)

    def late_init(self):
        self.center_on_screen()
        if not application.development_mode:
            self.fullscreen = True

        self.cursor = True
        self.color = color.dark_gray
        self.render_modes = ('default', 'wireframe', 'colliders', 'normals')
        self.render_mode = 'default'
        self.editor_ui = None

        from ursina import invoke
        invoke(base.accept,
               'aspectRatioChanged',
               self.update_aspect_ratio,
               delay=1 / 60)

    @property
    def left(self):
        return Vec2(-self.aspect_ratio / 2, 0)

    @property
    def right(self):
        return Vec2(self.aspect_ratio / 2, 0)

    @property
    def top_left(self):
        return Vec2(-self.aspect_ratio / 2, .5)

    @property
    def top_right(self):
        return Vec2(self.aspect_ratio / 2, .5)

    @property
    def bottom_left(self):
        return Vec2(-self.aspect_ratio / 2, -.5)

    @property
    def bottom_right(self):
        return Vec2(self.aspect_ratio / 2, -.5)

    def center_on_screen(self):
        print('size;', self.size)
        self.position = Vec2(
            int((self.screen_resolution[0] - self.size[0]) / 2),
            int((self.screen_resolution[1] - self.size[1]) / 2))

    def make_editor_gui(
        self
    ):  # called by main after setting up camera and application.development_mode
        from ursina import camera, Text, Button, ButtonList, Func, Tooltip
        import time

        self.editor_ui = Entity(parent=camera.ui,
                                eternal=True,
                                enabled=bool(application.development_mode))
        self.exit_button = Button(parent=self.editor_ui,
                                  eternal=True,
                                  origin=(.5, .5),
                                  position=self.top_right,
                                  z=-999,
                                  scale=(.05, .025),
                                  color=color.red.tint(-.2),
                                  text='x',
                                  on_click=application.quit)
        self.exit_button.enabled = self.borderless

        def _exit_button_input(key):
            from ursina import held_keys, mouse
            if held_keys['shift'] and key == 'q' and not mouse.right:
                self.exit_button.on_click()

        self.exit_button.input = _exit_button_input

        self.fps_counter = Text(parent=self.editor_ui,
                                eternal=True,
                                position=(.5 * self.aspect_ratio, .47, -999),
                                origin=(.8, .5),
                                text='60',
                                ignore=False,
                                i=0)

        def _fps_counter_update():
            if self.fps_counter.i > 60:
                self.fps_counter.text = str(int(1 // time.dt))
                self.fps_counter.i = 0
            self.fps_counter.i += 1

        self.fps_counter.update = _fps_counter_update

        import webbrowser
        self.cog_menu = ButtonList(
            {
                # 'Build' : Func(print, ' '),
                'API Reference':
                Func(webbrowser.open,
                     'https://www.ursinaengine.org/cheat_sheet_dark.html'),
                'Asset Store':
                Func(webbrowser.open, 'https://itch.io/tools/tag-ursina'),
                # 'Open Scene Editor' : Func(print, ' '),
                'Change Render Mode <gray>[F10]<default>':
                self.next_render_mode,
                'Reset Render Mode <gray>[F9]<default>':
                Func(setattr, self, 'render_mode', 'default'),
                'Reload Models <gray>[F7]<default>':
                application.hot_reloader.reload_models,
                'Reload Textures <gray>[F6]<default>':
                application.hot_reloader.reload_textures,
                'Reload Code <gray>[F5]<default>':
                application.hot_reloader.reload_code,
            },
            width=.35,
            x=.62,
            enabled=False,
            eternal=True)
        self.cog_menu.on_click = Func(setattr, self.cog_menu, 'enabled', False)
        self.cog_menu.y = -.5 + self.cog_menu.scale_y
        self.cog_menu.scale *= .75
        self.cog_menu.text_entity.x += .025
        self.cog_menu.highlight.color = color.azure
        self.cog_button = Button(parent=self.editor_ui,
                                 eternal=True,
                                 model='circle',
                                 scale=.015,
                                 origin=(1, -1),
                                 position=self.bottom_right)
        info_text = '''This menu is not enabled in builds <gray>(unless you set application.development to be not False).'''
        self.cog_menu.info = Button(parent=self.cog_menu,
                                    model='quad',
                                    text='<gray>?',
                                    scale=.1,
                                    x=1,
                                    y=.01,
                                    origin=(.5, -.5),
                                    tooltip=Tooltip(info_text,
                                                    scale=.75,
                                                    origin=(-.5, -.5)))
        self.cog_menu.info.text_entity.scale *= .75

        def _toggle_cog_menu():
            self.cog_menu.enabled = not self.cog_menu.enabled

        self.cog_button.on_click = _toggle_cog_menu
        # print('-----------', time.time() - t) # 0.04

    def update_aspect_ratio(self):
        prev_aspect = self.aspect_ratio
        self.size = base.win.get_size()
        print('changed aspect ratio:', round(prev_aspect, 3), '->',
              round(self.aspect_ratio, 3))

        from ursina import camera, window, application
        camera.ui_lens.set_film_size(camera.ui_size * .5 * self.aspect_ratio,
                                     camera.ui_size * .5)
        for e in [e for e in scene.entities if e.parent == camera.ui
                  ] + self.editor_ui.children:
            e.x /= prev_aspect / self.aspect_ratio

        if camera.orthographic:
            camera.orthographic_lens.set_film_size(
                camera.fov * window.aspect_ratio, camera.fov)
            application.base.cam.node().set_lens(camera.orthographic_lens)

    @property
    def position(self):
        return self._position

    @position.setter
    def position(self, value):
        # print('set window position:', value)
        self._position = value
        self.setOrigin(int(value[0]), int(value[1]))
        base.win.request_properties(self)

    @property
    def size(self):
        return Vec2(self.get_size()[0], self.get_size()[1])

    @size.setter
    def size(self, value):
        self.set_size(int(value[0]), int(value[1]))
        self.aspect_ratio = value[0] / value[1]
        from ursina import camera
        camera.set_shader_input('window_size', value)

    @property
    def render_mode(self):
        return self._render_mode

    @render_mode.setter
    def render_mode(self, value):
        self._render_mode = value
        print('render mode:', value)
        base.wireframeOff()

        # disable collision display mode
        if hasattr(self, 'original_colors'):
            for i, e in enumerate(
                [e for e in scene.entities if hasattr(e, 'color')]):
                e.color = self.original_colors[i]
                if e.collider:
                    e.collider.visible = False

        for e in [e for e in scene.entities if e.model and e.alpha]:
            e.setShaderAuto()

        if value == 'wireframe':
            base.wireframeOn()

        if value == 'colliders':
            self.original_colors = [
                e.color for e in scene.entities if hasattr(e, 'color')
            ]
            for e in scene.entities:
                e.color = color.clear
                if e.collider:
                    # e.visible = False
                    e.collider.visible = True

        if value == 'normals':
            from ursina.shaders import normals_shader
            for e in [e for e in scene.entities if e.model and e.alpha]:
                e.shader = normals_shader
                e.set_shader_input('transform_matrix',
                                   e.getNetTransform().getMat())

    def next_render_mode(self):
        i = self.render_modes.index(self.render_mode) + 1
        if i >= len(self.render_modes):
            i = 0

        self.render_mode = self.render_modes[i]

    @property
    def icon(self):
        return self._icon

    @icon.setter
    def icon(self, value):
        self._icon = value
        self.setIconFilename(value)

    def __setattr__(self, name, value):
        try:
            super().__setattr__(name, value)
        except:
            pass

        if name == 'fullscreen':
            try:
                if value == True:
                    self.windowed_position = self.position
                    self.windowed_size = self.size
                    self.size = self.fullscreen_size
                    self.center_on_screen()
                else:
                    self.size = self.windowed_size
                    if self.windowed_position is not None:
                        self.position = self.windowed_position
                    else:
                        self.center_on_screen()

                object.__setattr__(self, name, value)
                return
            except:
                print('failed to set fullscreen', value)
                pass

        if name == 'borderless':
            self.setUndecorated(value)
            if hasattr(self, 'exit_button'):
                self.exit_button.enabled = not value
            try:
                application.base.win.request_properties(self)
            except:
                pass
            object.__setattr__(self, name, value)

        if name == 'color':
            application.base.camNode.get_display_region(
                0).get_window().set_clear_color(value)

        if name == 'vsync':
            if value == True:
                loadPrcFileData('', 'sync-video True')
            else:
                loadPrcFileData('', 'sync-video False')
                print('set vsync to false')
            object.__setattr__(self, name, value)
示例#8
0
class Window(WindowProperties):
    def __init__(self):
        super().__init__()
        loadPrcFileData('', 'window-title ursina')
        loadPrcFileData('', 'notify-level-util error')
        loadPrcFileData('', 'textures-auto-power-2 #t')
        loadPrcFileData('', 'load-file-type p3assimp')
        # loadPrcFileData('', 'allow-portal-cull #t')
        # loadPrcFileData("", "framebuffer-multisample 1")
        # loadPrcFileData('', 'multisamples 2')
        # loadPrcFileData('', 'textures-power-2 none')
        # loadPrcFileData('', 'threading-model Cull/Draw')
        loadPrcFileData('', 'coordinate-system y-up-left')

        # fallback to one of these if opengl is not supported
        loadPrcFileData('', 'aux-display pandadx9')
        loadPrcFileData('', 'aux-display pandadx8')
        loadPrcFileData('', 'aux-display tinydisplay')

        self.vsync = True  # can't be set during play
        self.show_ursina_splash = False

        self.title = application.asset_folder.name
        self.borderless = True
        # self.icon = 'textures/ursina.ico'
        os_name = platform.system()

        try:
            if os_name == 'Windows':  # windows
                import ctypes
                user32 = ctypes.windll.user32
                user32.SetProcessDPIAware()
                self.screen_resolution = (user32.GetSystemMetrics(0),
                                          user32.GetSystemMetrics(1))

            elif os_name == 'Linux':
                import Xlib
                import Xlib.display
                resolution = Xlib.display.Display().screen().root.get_geometry(
                )
                self.screen_resolution = Vec2(resolution.width,
                                              resolution.height)

            elif os_name == 'Darwin':  # mac
                from AppKit import NSScreen
                size = NSScreen.mainScreen().frame().size
                self.screen_resolution = [size.width, size.height]
        except:
            from screeninfo import get_monitors
            self.screen_resolution = [
                get_monitors()[0].width,
                get_monitors()[0].height
            ]

        self.fullscreen_size = Vec2(*self.screen_resolution)
        self.windowed_size = self.fullscreen_size / 1.25
        self.windowed_position = None  # gets set when entering fullscreen so position will be correct when going back to windowed mode
        self.forced_aspect_ratio = None  # example: window.forced_aspect_ratio = 16/9
        self.size = self.windowed_size
        self.always_on_top = False

        self.top = Vec2(0, .5)
        self.bottom = Vec2(0, -.5)
        self.center = Vec2(0, 0)

    def late_init(self):
        self.center_on_screen()
        if not application.development_mode:
            self.fullscreen = True

        self.color = color.dark_gray
        self.render_modes = ('default', 'wireframe', 'colliders', 'normals')
        self.render_mode = 'default'
        self.editor_ui = None

        base.accept('aspectRatioChanged', self.update_aspect_ratio)
        if self.always_on_top:
            self.setZOrder(WindowProperties.Z_top)

    @property
    def left(self):
        return Vec2(-self.aspect_ratio / 2, 0)

    @property
    def right(self):
        return Vec2(self.aspect_ratio / 2, 0)

    @property
    def top_left(self):
        return Vec2(-self.aspect_ratio / 2, .5)

    @property
    def top_right(self):
        return Vec2(self.aspect_ratio / 2, .5)

    @property
    def bottom_left(self):
        return Vec2(-self.aspect_ratio / 2, -.5)

    @property
    def bottom_right(self):
        return Vec2(self.aspect_ratio / 2, -.5)

    def center_on_screen(self):
        self.position = Vec2(
            int((self.screen_resolution[0] - self.size[0]) / 2),
            int((self.screen_resolution[1] - self.size[1]) / 2))

    def make_editor_gui(
        self
    ):  # called by main after setting up camera and application.development_mode
        from ursina import camera, Entity, Text, Button, ButtonList, Func, Tooltip, held_keys, mouse
        import time

        self.editor_ui = Entity(parent=camera.ui,
                                eternal=True,
                                enabled=bool(application.development_mode))
        self.exit_button = Button(parent=self.editor_ui,
                                  eternal=True,
                                  ignore_paused=True,
                                  origin=(.5, .5),
                                  enabled=self.borderless,
                                  position=self.top_right,
                                  z=-999,
                                  scale=(.05, .025),
                                  color=color.red.tint(-.2),
                                  text='x',
                                  on_click=application.quit,
                                  name='exit_button')

        def _exit_button_input(key):
            if held_keys['shift'] and key == 'q' and not mouse.right:
                self.exit_button.on_click()

        self.exit_button.input = _exit_button_input

        self.fps_counter = Text(
            parent=self.editor_ui,
            eternal=True,
            origin=(.8, .5),
            text='60',
            ignore=False,
            i=0,
            position=(.5 * self.aspect_ratio,
                      .47 + (.02 * (not self.exit_button.enabled)), -999))

        def _fps_counter_update():
            if self.fps_counter.i > 60:
                self.fps_counter.text = str(int(1 // time.dt))
                self.fps_counter.i = 0
            self.fps_counter.i += 1

        self.fps_counter.update = _fps_counter_update

        import webbrowser
        self.cog_menu = ButtonList(
            {
                # 'Build' : Func(print, ' '),
                'API Reference':
                Func(webbrowser.open,
                     'https://www.ursinaengine.org/cheat_sheet_dark.html'),
                # 'Asset Store' : Func(webbrowser.open, 'https://itch.io/tools/tag-ursina'),
                'ursfx (Sound Effect Maker)':
                lambda: exec(
                    'from ursina.prefabs import ursfx; ursfx.gui.enabled = True'
                ),
                # 'Open Scene Editor' : Func(print, ' '),
                'Change Render Mode <gray>[F10]<default>':
                self.next_render_mode,
                'Reset Render Mode <gray>[F9]<default>':
                Func(setattr, self, 'render_mode', 'default'),
                'Reload Models <gray>[F7]<default>':
                application.hot_reloader.reload_models,
                'Reload Textures <gray>[F6]<default>':
                application.hot_reloader.reload_textures,
                'Reload Code <gray>[F5]<default>':
                application.hot_reloader.reload_code,
            },
            width=.35,
            x=.62,
            enabled=False,
            eternal=True,
            name='cog_menu',
        )
        self.cog_menu.on_click = Func(setattr, self.cog_menu, 'enabled', False)
        self.cog_menu.y = -.5 + self.cog_menu.scale_y
        self.cog_menu.scale *= .75
        self.cog_menu.text_entity.x += .025
        self.cog_menu.highlight.color = color.azure
        self.cog_button = Button(parent=self.editor_ui,
                                 eternal=True,
                                 model='quad',
                                 texture='cog',
                                 scale=.015,
                                 origin=(1, -1),
                                 position=self.bottom_right,
                                 name='cog_button')
        info_text = '''This menu is not enabled in builds <gray>(unless you set application.development_mode to be not False).'''
        self.cog_menu.info = Button(parent=self.cog_menu,
                                    model='quad',
                                    text='<gray>?',
                                    scale=.1,
                                    x=1,
                                    y=.01,
                                    origin=(.5, -.5),
                                    tooltip=Tooltip(info_text,
                                                    scale=.75,
                                                    origin=(-.5, -.5),
                                                    eternal=True),
                                    eternal=True,
                                    name='cog_menu_info')
        self.cog_menu.info.text_entity.scale *= .75

        def _toggle_cog_menu():
            self.cog_menu.enabled = not self.cog_menu.enabled

        self.cog_button.on_click = _toggle_cog_menu
        # print('-----------', time.time() - t) # 0.04

    def update_aspect_ratio(self):
        prev_aspect = self.aspect_ratio
        self.aspect_ratio = self.size[0] / self.size[1]

        from ursina import camera, window, application
        value = [int(e) for e in base.win.getSize()]
        camera.set_shader_input('window_size', value)

        print_info('changed aspect ratio:', round(prev_aspect, 3), '->',
                   round(self.aspect_ratio, 3))

        camera.ui_lens.set_film_size(camera.ui_size * .5 * self.aspect_ratio,
                                     camera.ui_size * .5)
        for e in [e for e in scene.entities if e.parent == camera.ui
                  ] + self.editor_ui.children:
            e.x /= prev_aspect / self.aspect_ratio

        if camera.orthographic:
            camera.orthographic_lens.set_film_size(
                camera.fov * window.aspect_ratio, camera.fov)
            application.base.cam.node().set_lens(camera.orthographic_lens)

    @property
    def position(self):
        return self._position

    @position.setter
    def position(self, value):
        # print('set window position:', value)
        self._position = value
        self.setOrigin(int(value[0]), int(value[1]))
        base.win.request_properties(self)

    @property
    def size(self):
        if not self.borderless:
            return Vec2(*base.win.getSize())
        return self._size

    @size.setter
    def size(self, value):
        if hasattr(self, '_forced_aspect_ratio') and self.forced_aspect_ratio:
            value = (value[1] * self.forced_aspect_ratio, value[1])

        self._size = value
        self.setSize(int(value[0]), int(value[1]))
        self.aspect_ratio = value[0] / value[1]
        from ursina import camera
        camera.set_shader_input('window_size', value)
        base.win.request_properties(self)

    @property
    def forced_aspect_ratio(self):
        if not hasattr(self, '_forced_aspect_ratio'):
            return None
        return self._forced_aspect_ratio

    @forced_aspect_ratio.setter
    def forced_aspect_ratio(self, value):
        if not value:
            return

        print('ttoooo', value)
        self._forced_aspect_ratio = value
        self.size = self.size

    @property
    def render_mode(self):
        return self._render_mode

    @render_mode.setter
    def render_mode(self, value):
        self._render_mode = value
        # print('render mode:', value)
        base.wireframeOff()

        # disable collision display mode
        if hasattr(self, 'original_colors'):
            for i, e in enumerate(
                [e for e in scene.entities if hasattr(e, 'color')]):
                e.color = self.original_colors[i]
                if e.collider:
                    e.collider.visible = False

        for e in [e for e in scene.entities if e.model and e.alpha]:
            e.setShaderAuto()

        if value == 'wireframe':
            base.wireframeOn()

        elif value == 'colliders':
            self.original_colors = [
                e.color for e in scene.entities if hasattr(e, 'color')
            ]
            for e in scene.entities:
                e.color = color.clear
                if e.collider:
                    # e.visible = False
                    e.collider.visible = True

        elif value == 'normals':
            from ursina.shaders import normals_shader
            for e in [e for e in scene.entities if e.model and e.alpha]:
                e.shader = normals_shader
                e.set_shader_input('transform_matrix',
                                   e.getNetTransform().getMat())

    def next_render_mode(self):
        i = self.render_modes.index(self.render_mode) + 1
        if i >= len(self.render_modes):
            i = 0

        self.render_mode = self.render_modes[i]

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, value):
        self._title = value
        loadPrcFileData('', f'window-title {value}')

    @property
    def icon(self):
        return self._icon

    @icon.setter
    def icon(self, value):
        self._icon = value
        self.setIconFilename(value)

    def __setattr__(self, name, value):
        try:
            super().__setattr__(name, value)
        except:
            pass

        if name == 'fullscreen':
            try:
                if value == True:
                    self.windowed_position = self.position
                    self.windowed_size = self.size
                    self.size = self.fullscreen_size
                    self.center_on_screen()
                else:
                    self.size = self.windowed_size
                    if self.windowed_position is not None:
                        self.position = self.windowed_position
                    else:
                        self.center_on_screen()

                self.setFullscreen(value)
                object.__setattr__(self, name, value)
                return
            except:
                print_warning('failed to set fullscreen', value)
                pass

        if name == 'borderless':
            self.setUndecorated(value)
            if hasattr(self, 'exit_button'):
                self.exit_button.enabled = not value
            try:
                application.base.win.request_properties(self)
            except:
                pass
            object.__setattr__(self, name, value)

        if name == 'color':
            application.base.camNode.get_display_region(
                0).get_window().set_clear_color(value)

        if name == 'vsync':
            if not application.base:  # set vsync/framerate before window opened
                if value == True or value == False:
                    loadPrcFileData('', f'sync-video {value}')
                elif isinstance(value, int):
                    loadPrcFileData('', 'clock-mode limited')
                    loadPrcFileData('', f'clock-frame-rate {value}')
            else:
                from panda3d.core import ClockObject  # set vsync/framerate in runtime
                if value == True:
                    globalClock.setMode(ClockObject.MNormal)
                elif value == False:
                    print_warning(
                        'error: disabling vsync during runtime is not yet implemented'
                    )

                elif isinstance(value, (int, float, complex)):
                    globalClock.setMode(ClockObject.MLimited)
                    globalClock.setFrameRate(int(value))

            object.__setattr__(self, name, value)
示例#9
0
class Window(WindowProperties):

    def __init__(self):
        super().__init__()
        loadPrcFileData('', 'window-title ursina')
        loadPrcFileData('', 'notify-level-util error')
        loadPrcFileData('', 'textures-auto-power-2 #t')
        loadPrcFileData('', 'load-file-type p3assimp')
        loadPrcFileData("", "framebuffer-multisample 1")
        # loadPrcFileData('', 'framebuffer-multisample 1')
        loadPrcFileData('', 'multisamples 2')
        # loadPrcFileData('', 'textures-power-2 none')

        # loadPrcFileData('', 'cursor-filename mycursor.ico')
        # loadPrcFileData('', 'threading-model Cull/Draw')
        loadPrcFileData('', 'coordinate-system y-up-left')
        self.setForeground(True)
        self.vsync = True   # can't be set during play
        self.show_ursina_splash = False

        self.title = application.asset_folder.name
        try:
            self.screen_resolution = (get_monitors()[0].width, get_monitors()[0].height)
        except:
            print('using default sceen resolution.', 'OS:', os.name)
            self.screen_resolution = Vec2(1366, 768)

        print('screen resolution:', self.screen_resolution)
        self.fullscreen_size = Vec2(self.screen_resolution[0]+1, self.screen_resolution[1]+1)
        self.windowed_size = self.fullscreen_size / 1.25
        self.windowed_position = None   # gets set when entering fullscreen so position will be correct when going back to windowed mode
        self.size = self.windowed_size
        self.borderless = True


    def late_init(self):
        self.position = Vec2(0,0)
        self.top = Vec2(0, .5)
        self.bottom = Vec2(0, .5)
        self.center = Vec2(0, 0)
        self.fullscreen = False

        self.cursor = True

        self.color = color.dark_gray
        self.render_modes = (
            'default',
            'wireframe',
            'colliders',
            'normals',
            )
        self.render_mode = 'default'
        self.editor_ui = None


    @property
    def left(self):
        return Vec2(-self.aspect_ratio/2, 0)
    @property
    def right(self):
        return Vec2(self.aspect_ratio/2, 0)
    @property
    def top_left(self):
        return Vec2(-self.aspect_ratio/2, .5)
    @property
    def top_right(self):
        return Vec2(self.aspect_ratio/2, .5)
    @property
    def bottom_left(self):
        return Vec2(-self.aspect_ratio/2, -.5)
    @property
    def bottom_right(self):
        return Vec2(self.aspect_ratio/2, -.5)


    def center_on_screen(self):
        self.position = Vec2(
            int((self.screen_resolution[0] - self.size[0]) / 2),
            int((self.screen_resolution[1] - self.size[1]) / 2)
            )

    def make_editor_gui(self):     # called by main after setting up camera and application.development_mode
        from ursina import camera, Text, Button, ButtonList, Func
        import time

        self.editor_ui = Entity(parent=camera.ui, eternal=True, enabled=bool(application.development_mode))
        self.exit_button = Button(parent=self.editor_ui, eternal=True, origin=(.5, .5), position=self.top_right, z=-999, scale=(.05, .025), color=color.red.tint(-.2), text='x', on_click=application.quit)

        def _exit_button_input(key):
            from ursina import held_keys, mouse
            if held_keys['shift'] and key == 'q' and not mouse.right:
                self.exit_button.on_click()
        self.exit_button.input = _exit_button_input

        self.fps_counter = Text(parent=self.editor_ui, eternal=True, position=(.5*self.aspect_ratio, .47, -999), origin=(.8,.5), text='60', ignore=False, i=0)

        def _fps_counter_update():
            if self.fps_counter.i > 60:
                self.fps_counter.text = str(int(1//time.dt))
                self.fps_counter.i = 0
            self.fps_counter.i += 1
        self.fps_counter.update = _fps_counter_update


        import webbrowser
        self.cog_menu = ButtonList({
            # 'Build' : Func(print, ' '),
            'Asset Store' : Func(webbrowser.open, "https://itch.io/tools/tag-ursina"),
            # 'Open Scene Editor' : Func(print, ' '),
            'Change Render Mode <gray>[F10]<default>' : self.next_render_mode,
            'Reset Render Mode <gray>[F9]<default>' : Func(setattr, self, 'render_mode', 'default'),
            'Reload Models <gray>[F7]<default>' : application.hot_reloader.reload_models,
            'Reload Textures <gray>[F6]<default>' : application.hot_reloader.reload_textures,
            'Reload Code <gray>[F5]<default>' : application.hot_reloader.reload_code,
        },
            width=.35,
            x=.62,
            enabled=False,
            eternal=True
        )
        self.cog_menu.on_click = Func(setattr, self.cog_menu, 'enabled', False)
        self.cog_menu.y = -.5 + self.cog_menu.scale_y
        self.cog_menu.scale *= .75
        self.cog_menu.text_entity.x += .025
        self.cog_menu.highlight.color = color.azure
        self.cog_button = Button(parent=self.editor_ui, eternal=True, model='circle', scale=.015, origin=(1,-1), position=self.bottom_right)
        def _toggle_cog_menu():
            self.cog_menu.enabled = not self.cog_menu.enabled
        self.cog_button.on_click = _toggle_cog_menu
        # print('-----------', time.time() - t) # 0.04

    def update_aspect_ratio(self):
        from ursina import camera
        camera.ui_lens.set_film_size(camera.ui_size * .5 * self.aspect_ratio, camera.ui_size * .5)


    @property
    def size(self):
        return Vec2(self.get_size()[0], self.get_size()[1])

    @size.setter
    def size(self, value):
        self.set_size(int(value[0]), int(value[1]))
        self.aspect_ratio = value[0] / value[1]
        base.win.requestProperties(self)
        self.update_aspect_ratio()


    @property
    def render_mode(self):
        return self._render_mode

    @render_mode.setter
    def render_mode(self, value):
        self._render_mode = value
        print('render mode:', value)
        base.wireframeOff()

        # disable collision display mode
        if hasattr(self, 'original_colors'):
            for i, e in enumerate([e for e in scene.entities if hasattr(e, 'color')]):
                e.color = self.original_colors[i]
                if e.collider:
                    e.collider.visible = False

        for e in [e for e in scene.entities if e.model and e.alpha]:
            e.setShaderAuto()

        if value == 'wireframe':
            base.wireframeOn()

        if value == 'colliders':
            self.original_colors = [e.color for e in scene.entities if hasattr(e, 'color')]
            for e in scene.entities:
                e.color = color.clear
                if e.collider:
                    # e.visible = False
                    e.collider.visible = True

        if value == 'normals':
            from ursina.shaders import normals_shader
            for e in [e for e in scene.entities if e.model and e.alpha]:
                e.shader = normals_shader
                e.set_shader_input('transform_matrix', e.getNetTransform().getMat())


    def next_render_mode(self):
        i = self.render_modes.index(self.render_mode) + 1
        if i >= len(self.render_modes):
            i = 0

        self.render_mode = self.render_modes[i]


    def __setattr__(self, name, value):
        try:
            super().__setattr__(name, value)
        except:
            pass

        if name == 'position':
            self.setOrigin(int(value[0]), int(value[1]))
            application.base.win.request_properties(self)
            object.__setattr__(self, name, value)

        if name == 'fullscreen':
            try:
                if value == True:
                    self.windowed_size = self.size
                    self.windowed_position = self.position
                    self.size = self.fullscreen_size
                    self.center_on_screen()
                else:
                    self.size = self.windowed_size
                    if self.windowed_position is not None:
                        self.position = self.windowed_position
                    else:
                        self.center_on_screen()

                object.__setattr__(self, name, value)
                return
            except:
                print('failed to set fullscreen', value)
                pass

        if name == 'borderless':
            self.setUndecorated(value)
            try:
                application.base.win.request_properties(self)
            except:
                pass
            object.__setattr__(self, name, value)

        if name == 'color':
            application.base.camNode.get_display_region(0).get_window().set_clear_color(value)

        if name == 'vsync':
            if value == True:
                loadPrcFileData('', 'sync-video True')
            else:
                loadPrcFileData('', 'sync-video False')
                print('set vsync to false')
            object.__setattr__(self, name, value)
示例#10
0
        super().__init__()
        self.parent = camera.ui
        self.texture = 'cursor'
        self.model = 'quad'
        self.color = color.light_gray
        # self.origin = (-.49, .49)
        self.scale *= .05
        self.render_queue = 1

        for key, value in kwargs.items():
            setattr(self, key, value)

    def update(self):
        self.position = Vec3(mouse.x, mouse.y, -100)


if __name__ == '__main__':
    from ursina import Ursina, Button, scene, Panel, Mesh
    app = Ursina()
    Button('button').fit_to_text()
    camera.orthographic = True
    camera.fov = 100
    cursor = Cursor(model=Mesh(vertices=[(-.5, 0, 0), (.5, 0, 0), (0, -.5, 0),
                                         (0, .5, 0)],
                               triangles=[(0, 1), (2, 3)],
                               mode='line',
                               thickness=2),
                    scale=.02)
    mouse.visible = False
    app.run()
示例#11
0
    def make_editor_gui(
        self
    ):  # called by main after setting up camera and application.development_mode
        from ursina import camera, Text, Button, ButtonList, Func
        import time

        if not application.development_mode:
            return
        self.editor_ui = Entity(parent=camera.ui, eternal=True)
        self.exit_button = Button(parent=self.editor_ui,
                                  eternal=True,
                                  origin=(.5, .5),
                                  position=self.top_right,
                                  z=-999,
                                  scale=(.05, .025),
                                  color=color.red.tint(-.2),
                                  text='x',
                                  on_click=application.quit)

        def _exit_button_input(key):
            from ursina import held_keys, mouse
            if held_keys['shift'] and key == 'q' and not mouse.right:
                self.exit_button.on_click()

        self.exit_button.input = _exit_button_input

        self.fps_counter = Text(parent=self.editor_ui,
                                eternal=True,
                                position=(.5 * self.aspect_ratio, .47, -999),
                                origin=(.8, .5),
                                text='60',
                                ignore=False,
                                i=0)

        def _fps_counter_update():
            if self.fps_counter.i > 60:
                self.fps_counter.text = str(int(1 // time.dt))
                self.fps_counter.i = 0
            self.fps_counter.i += 1

        self.fps_counter.update = _fps_counter_update

        import webbrowser
        self.cog_menu = ButtonList(
            {
                # 'Build' : Func(print, ' '),
                'Asset Store':
                Func(webbrowser.open, "https://itch.io/tools/tag-ursina"),
                # 'Open Scene Editor' : Func(print, ' '),
                'Reload Textures [F6]':
                application.hot_reloader.reload_textures,
                'Reload Models [F7]':
                application.hot_reloader.reload_models,
                'Reload Code [F5]':
                application.hot_reloader.reload_code,
            },
            width=.3,
            x=.64,
            enabled=False,
            eternal=True)
        self.cog_menu.on_click = Func(setattr, self.cog_menu, 'enabled', False)
        self.cog_menu.y = -.5 + self.cog_menu.scale_y
        self.cog_menu.scale *= .75
        self.cog_menu.text_entity.x += .025
        self.cog_menu.highlight.color = color.azure
        self.cog_button = Button(parent=self.editor_ui,
                                 eternal=True,
                                 model='circle',
                                 scale=.015,
                                 origin=(1, -1),
                                 position=self.bottom_right)

        def _toggle_cog_menu():
            self.cog_menu.enabled = not self.cog_menu.enabled

        self.cog_button.on_click = _toggle_cog_menu
示例#12
0
        except:
            pass

    def close(self):
        if self.popup:
            self.bg.enabled = False
        self.animate_scale_y(0, duration=.1)
        invoke(setattr, self, 'enabled', False, delay=.2)


if __name__ == '__main__':
    '''
    WindowPanel is an easy way to create UI. It will automatically layout the content.
    '''
    from ursina import Ursina, ButtonGroup
    app = Ursina()
    wp = WindowPanel(
        title='Custom Window',
        content=(
            Text('Name:'),
            InputField(name='name_field'),
            Button(text='Submit', color=color.azure),
            Slider(),
            Slider(),
            ButtonGroup(('test', 'eslk', 'skffk'))
            ),
        )


    app.run()
示例#13
0
        if name == 'vsync':
            if value == True:
                loadPrcFileData('', 'sync-video True')
            else:
                loadPrcFileData('', 'sync-video False')
                print('set vsync to false')
            object.__setattr__(self, name, value)


sys.modules[__name__] = Window()

if __name__ == '__main__':
    from ursina import *
    # application.development_mode = False
    app = Ursina()

    window.title = 'Title'
    window.borderless = False
    # window.fullscreen = False
    window.fps_counter.enabled = False
    # window.exit_button.visible = False
    # window.cog_button.enabled = False
    camera.orthographic = True

    camera.fov = 2

    Entity(model='cube', color=color.green, collider='box', texture='shore')
    Button(scale=.5, text='test', position=window.right)
    app.run()