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

Simple Fading Background Actor.

Background( fade_time: float = 0.5, start_faded: bool = False, show_logo: bool = False)
 23    def __init__(
 24        self,
 25        fade_time: float = 0.5,
 26        start_faded: bool = False,
 27        show_logo: bool = False,
 28    ):
 29        super().__init__()
 30        self._dying = False
 31        self.fade_time = fade_time
 32        # We're special in that we create our node in the session
 33        # scene instead of the activity scene.
 34        # This way we can overlap multiple activities for fades
 35        # and whatnot.
 36        session = bs.getsession()
 37        self._session = weakref.ref(session)
 38        with session.context:
 39            self.node = bs.newnode(
 40                'image',
 41                delegate=self,
 42                attrs={
 43                    'fill_screen': True,
 44                    'texture': bs.gettexture('bg'),
 45                    'tilt_translate': -0.3,
 46                    'has_alpha_channel': False,
 47                    'color': (1, 1, 1),
 48                },
 49            )
 50            if not start_faded:
 51                bs.animate(
 52                    self.node,
 53                    'opacity',
 54                    {0.0: 0.0, self.fade_time: 1.0},
 55                    loop=False,
 56                )
 57            if show_logo:
 58                logo_texture = bs.gettexture('logo')
 59                logo_mesh = bs.getmesh('logo')
 60                logo_mesh_transparent = bs.getmesh('logoTransparent')
 61                self.logo = bs.newnode(
 62                    'image',
 63                    owner=self.node,
 64                    attrs={
 65                        'texture': logo_texture,
 66                        'mesh_opaque': logo_mesh,
 67                        'mesh_transparent': logo_mesh_transparent,
 68                        'scale': (0.7, 0.7),
 69                        'vr_depth': -250,
 70                        'color': (0.15, 0.15, 0.15),
 71                        'position': (0, 0),
 72                        'tilt_translate': -0.05,
 73                        'absolute_scale': False,
 74                    },
 75                )
 76                self.node.connectattr('opacity', self.logo, 'opacity')
 77                # add jitter/pulse for a stop-motion-y look unless we're in VR
 78                # in which case stillness is better
 79                if not bs.app.env.vr:
 80                    self.cmb = bs.newnode(
 81                        'combine', owner=self.node, attrs={'size': 2}
 82                    )
 83                    for attr in ['input0', 'input1']:
 84                        bs.animate(
 85                            self.cmb,
 86                            attr,
 87                            {0.0: 0.693, 0.05: 0.7, 0.5: 0.693},
 88                            loop=True,
 89                        )
 90                    self.cmb.connectattr('output', self.logo, 'scale')
 91                    cmb = bs.newnode(
 92                        'combine', owner=self.node, attrs={'size': 2}
 93                    )
 94                    cmb.connectattr('output', self.logo, 'position')
 95                    # Gen some random keys for that stop-motion-y look.
 96                    keys = {}
 97                    timeval = 0.0
 98                    for _i in range(10):
 99                        keys[timeval] = (random.random() - 0.5) * 0.0015
100                        timeval += random.random() * 0.1
101                    bs.animate(cmb, 'input0', keys, loop=True)
102                    keys = {}
103                    timeval = 0.0
104                    for _i in range(10):
105                        keys[timeval] = (random.random() - 0.5) * 0.0015 + 0.05
106                        timeval += random.random() * 0.1
107                    bs.animate(cmb, 'input1', keys, loop=True)

Instantiates an Actor in the current bascenev1.Activity.

fade_time
@override
def handlemessage(self, msg: Any) -> Any:
144    @override
145    def handlemessage(self, msg: Any) -> Any:
146        assert not self.expired
147        if isinstance(msg, bs.DieMessage):
148            self._die(msg.immediate)
149        else:
150            super().handlemessage(msg)

General message handling; can be passed any message object.

Inherited Members
bascenev1._actor.Actor
autoretain
on_expire
expired
exists
is_alive
activity
getactivity