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.

fade_time
@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.