bascenev1lib.actor.background
Defines Actor(s).
1# Released under the MIT License. See LICENSE for details. 2# 3"""Defines Actor(s).""" 4 5from __future__ import annotations 6 7import random 8import weakref 9import logging 10from typing import TYPE_CHECKING, override 11 12import bascenev1 as bs 13 14if TYPE_CHECKING: 15 from typing import Any 16 17 18class Background(bs.Actor): 19 """Simple Fading Background Actor.""" 20 21 def __init__( 22 self, 23 fade_time: float = 0.5, 24 start_faded: bool = False, 25 show_logo: bool = False, 26 ): 27 super().__init__() 28 self._dying = False 29 self.fade_time = fade_time 30 # We're special in that we create our node in the session 31 # scene instead of the activity scene. 32 # This way we can overlap multiple activities for fades 33 # and whatnot. 34 session = bs.getsession() 35 self._session = weakref.ref(session) 36 with session.context: 37 self.node = bs.newnode( 38 'image', 39 delegate=self, 40 attrs={ 41 'fill_screen': True, 42 'texture': bs.gettexture('bg'), 43 'tilt_translate': -0.3, 44 'has_alpha_channel': False, 45 'color': (1, 1, 1), 46 }, 47 ) 48 if not start_faded: 49 bs.animate( 50 self.node, 51 'opacity', 52 {0.0: 0.0, self.fade_time: 1.0}, 53 loop=False, 54 ) 55 if show_logo: 56 logo_texture = bs.gettexture('logo') 57 logo_mesh = bs.getmesh('logo') 58 logo_mesh_transparent = bs.getmesh('logoTransparent') 59 self.logo = bs.newnode( 60 'image', 61 owner=self.node, 62 attrs={ 63 'texture': logo_texture, 64 'mesh_opaque': logo_mesh, 65 'mesh_transparent': logo_mesh_transparent, 66 'scale': (0.7, 0.7), 67 'vr_depth': -250, 68 'color': (0.15, 0.15, 0.15), 69 'position': (0, 0), 70 'tilt_translate': -0.05, 71 'absolute_scale': False, 72 }, 73 ) 74 self.node.connectattr('opacity', self.logo, 'opacity') 75 # add jitter/pulse for a stop-motion-y look unless we're in VR 76 # in which case stillness is better 77 if not bs.app.env.vr: 78 self.cmb = bs.newnode( 79 'combine', owner=self.node, attrs={'size': 2} 80 ) 81 for attr in ['input0', 'input1']: 82 bs.animate( 83 self.cmb, 84 attr, 85 {0.0: 0.693, 0.05: 0.7, 0.5: 0.693}, 86 loop=True, 87 ) 88 self.cmb.connectattr('output', self.logo, 'scale') 89 cmb = bs.newnode( 90 'combine', owner=self.node, attrs={'size': 2} 91 ) 92 cmb.connectattr('output', self.logo, 'position') 93 # Gen some random keys for that stop-motion-y look. 94 keys = {} 95 timeval = 0.0 96 for _i in range(10): 97 keys[timeval] = (random.random() - 0.5) * 0.0015 98 timeval += random.random() * 0.1 99 bs.animate(cmb, 'input0', keys, loop=True) 100 keys = {} 101 timeval = 0.0 102 for _i in range(10): 103 keys[timeval] = (random.random() - 0.5) * 0.0015 + 0.05 104 timeval += random.random() * 0.1 105 bs.animate(cmb, 'input1', keys, loop=True) 106 107 @override 108 def __del__(self) -> None: 109 # Normal actors don't get sent DieMessages when their 110 # activity is shutting down, but we still need to do so 111 # since our node lives in the session and it wouldn't die 112 # otherwise. 113 self._die() 114 super().__del__() 115 116 def _die(self, immediate: bool = False) -> None: 117 session = self._session() 118 if session is None and self.node: 119 # If session is gone, our node should be too, 120 # since it was part of the session's scene. 121 # Let's make sure that's the case. 122 # (since otherwise we have no way to kill it) 123 logging.exception( 124 'got None session on Background _die' 125 ' (and node still exists!)' 126 ) 127 elif session is not None: 128 with session.context: 129 if not self._dying and self.node: 130 self._dying = True 131 if immediate: 132 self.node.delete() 133 else: 134 bs.animate( 135 self.node, 136 'opacity', 137 {0.0: 1.0, self.fade_time: 0.0}, 138 loop=False, 139 ) 140 bs.timer(self.fade_time + 0.1, self.node.delete) 141 142 @override 143 def handlemessage(self, msg: Any) -> Any: 144 assert not self.expired 145 if isinstance(msg, bs.DieMessage): 146 self._die(msg.immediate) 147 else: 148 super().handlemessage(msg)
class
Background(bascenev1._actor.Actor):
19class Background(bs.Actor): 20 """Simple Fading Background Actor.""" 21 22 def __init__( 23 self, 24 fade_time: float = 0.5, 25 start_faded: bool = False, 26 show_logo: bool = False, 27 ): 28 super().__init__() 29 self._dying = False 30 self.fade_time = fade_time 31 # We're special in that we create our node in the session 32 # scene instead of the activity scene. 33 # This way we can overlap multiple activities for fades 34 # and whatnot. 35 session = bs.getsession() 36 self._session = weakref.ref(session) 37 with session.context: 38 self.node = bs.newnode( 39 'image', 40 delegate=self, 41 attrs={ 42 'fill_screen': True, 43 'texture': bs.gettexture('bg'), 44 'tilt_translate': -0.3, 45 'has_alpha_channel': False, 46 'color': (1, 1, 1), 47 }, 48 ) 49 if not start_faded: 50 bs.animate( 51 self.node, 52 'opacity', 53 {0.0: 0.0, self.fade_time: 1.0}, 54 loop=False, 55 ) 56 if show_logo: 57 logo_texture = bs.gettexture('logo') 58 logo_mesh = bs.getmesh('logo') 59 logo_mesh_transparent = bs.getmesh('logoTransparent') 60 self.logo = bs.newnode( 61 'image', 62 owner=self.node, 63 attrs={ 64 'texture': logo_texture, 65 'mesh_opaque': logo_mesh, 66 'mesh_transparent': logo_mesh_transparent, 67 'scale': (0.7, 0.7), 68 'vr_depth': -250, 69 'color': (0.15, 0.15, 0.15), 70 'position': (0, 0), 71 'tilt_translate': -0.05, 72 'absolute_scale': False, 73 }, 74 ) 75 self.node.connectattr('opacity', self.logo, 'opacity') 76 # add jitter/pulse for a stop-motion-y look unless we're in VR 77 # in which case stillness is better 78 if not bs.app.env.vr: 79 self.cmb = bs.newnode( 80 'combine', owner=self.node, attrs={'size': 2} 81 ) 82 for attr in ['input0', 'input1']: 83 bs.animate( 84 self.cmb, 85 attr, 86 {0.0: 0.693, 0.05: 0.7, 0.5: 0.693}, 87 loop=True, 88 ) 89 self.cmb.connectattr('output', self.logo, 'scale') 90 cmb = bs.newnode( 91 'combine', owner=self.node, attrs={'size': 2} 92 ) 93 cmb.connectattr('output', self.logo, 'position') 94 # Gen some random keys for that stop-motion-y look. 95 keys = {} 96 timeval = 0.0 97 for _i in range(10): 98 keys[timeval] = (random.random() - 0.5) * 0.0015 99 timeval += random.random() * 0.1 100 bs.animate(cmb, 'input0', keys, loop=True) 101 keys = {} 102 timeval = 0.0 103 for _i in range(10): 104 keys[timeval] = (random.random() - 0.5) * 0.0015 + 0.05 105 timeval += random.random() * 0.1 106 bs.animate(cmb, 'input1', keys, loop=True) 107 108 @override 109 def __del__(self) -> None: 110 # Normal actors don't get sent DieMessages when their 111 # activity is shutting down, but we still need to do so 112 # since our node lives in the session and it wouldn't die 113 # otherwise. 114 self._die() 115 super().__del__() 116 117 def _die(self, immediate: bool = False) -> None: 118 session = self._session() 119 if session is None and self.node: 120 # If session is gone, our node should be too, 121 # since it was part of the session's scene. 122 # Let's make sure that's the case. 123 # (since otherwise we have no way to kill it) 124 logging.exception( 125 'got None session on Background _die' 126 ' (and node still exists!)' 127 ) 128 elif session is not None: 129 with session.context: 130 if not self._dying and self.node: 131 self._dying = True 132 if immediate: 133 self.node.delete() 134 else: 135 bs.animate( 136 self.node, 137 'opacity', 138 {0.0: 1.0, self.fade_time: 0.0}, 139 loop=False, 140 ) 141 bs.timer(self.fade_time + 0.1, self.node.delete) 142 143 @override 144 def handlemessage(self, msg: Any) -> Any: 145 assert not self.expired 146 if isinstance(msg, bs.DieMessage): 147 self._die(msg.immediate) 148 else: 149 super().handlemessage(msg)
Simple Fading Background Actor.
Background( fade_time: float = 0.5, start_faded: bool = False, show_logo: bool = False)
22 def __init__( 23 self, 24 fade_time: float = 0.5, 25 start_faded: bool = False, 26 show_logo: bool = False, 27 ): 28 super().__init__() 29 self._dying = False 30 self.fade_time = fade_time 31 # We're special in that we create our node in the session 32 # scene instead of the activity scene. 33 # This way we can overlap multiple activities for fades 34 # and whatnot. 35 session = bs.getsession() 36 self._session = weakref.ref(session) 37 with session.context: 38 self.node = bs.newnode( 39 'image', 40 delegate=self, 41 attrs={ 42 'fill_screen': True, 43 'texture': bs.gettexture('bg'), 44 'tilt_translate': -0.3, 45 'has_alpha_channel': False, 46 'color': (1, 1, 1), 47 }, 48 ) 49 if not start_faded: 50 bs.animate( 51 self.node, 52 'opacity', 53 {0.0: 0.0, self.fade_time: 1.0}, 54 loop=False, 55 ) 56 if show_logo: 57 logo_texture = bs.gettexture('logo') 58 logo_mesh = bs.getmesh('logo') 59 logo_mesh_transparent = bs.getmesh('logoTransparent') 60 self.logo = bs.newnode( 61 'image', 62 owner=self.node, 63 attrs={ 64 'texture': logo_texture, 65 'mesh_opaque': logo_mesh, 66 'mesh_transparent': logo_mesh_transparent, 67 'scale': (0.7, 0.7), 68 'vr_depth': -250, 69 'color': (0.15, 0.15, 0.15), 70 'position': (0, 0), 71 'tilt_translate': -0.05, 72 'absolute_scale': False, 73 }, 74 ) 75 self.node.connectattr('opacity', self.logo, 'opacity') 76 # add jitter/pulse for a stop-motion-y look unless we're in VR 77 # in which case stillness is better 78 if not bs.app.env.vr: 79 self.cmb = bs.newnode( 80 'combine', owner=self.node, attrs={'size': 2} 81 ) 82 for attr in ['input0', 'input1']: 83 bs.animate( 84 self.cmb, 85 attr, 86 {0.0: 0.693, 0.05: 0.7, 0.5: 0.693}, 87 loop=True, 88 ) 89 self.cmb.connectattr('output', self.logo, 'scale') 90 cmb = bs.newnode( 91 'combine', owner=self.node, attrs={'size': 2} 92 ) 93 cmb.connectattr('output', self.logo, 'position') 94 # Gen some random keys for that stop-motion-y look. 95 keys = {} 96 timeval = 0.0 97 for _i in range(10): 98 keys[timeval] = (random.random() - 0.5) * 0.0015 99 timeval += random.random() * 0.1 100 bs.animate(cmb, 'input0', keys, loop=True) 101 keys = {} 102 timeval = 0.0 103 for _i in range(10): 104 keys[timeval] = (random.random() - 0.5) * 0.0015 + 0.05 105 timeval += random.random() * 0.1 106 bs.animate(cmb, 'input1', keys, loop=True)
Instantiates an Actor in the current bascenev1.Activity.
@override
def
handlemessage(self, msg: Any) -> Any:
143 @override 144 def handlemessage(self, msg: Any) -> Any: 145 assert not self.expired 146 if isinstance(msg, bs.DieMessage): 147 self._die(msg.immediate) 148 else: 149 super().handlemessage(msg)
General message handling; can be passed any message object.