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

Simple Fading Background Actor.

Background( fade_time: float = 0.5, start_faded: bool = False, show_logo: bool = False)
 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 = ba.getsession()
 35        self._session = weakref.ref(session)
 36        with ba.Context(session):
 37            self.node = ba.newnode(
 38                'image',
 39                delegate=self,
 40                attrs={
 41                    'fill_screen': True,
 42                    'texture': ba.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                ba.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 = ba.gettexture('logo')
 57                logo_model = ba.getmodel('logo')
 58                logo_model_transparent = ba.getmodel('logoTransparent')
 59                self.logo = ba.newnode(
 60                    'image',
 61                    owner=self.node,
 62                    attrs={
 63                        'texture': logo_texture,
 64                        'model_opaque': logo_model,
 65                        'model_transparent': logo_model_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 ba.app.vr_mode:
 78                    self.cmb = ba.newnode(
 79                        'combine', owner=self.node, attrs={'size': 2}
 80                    )
 81                    for attr in ['input0', 'input1']:
 82                        ba.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 = ba.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                    ba.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                    ba.animate(cmb, 'input1', keys, loop=True)

Instantiates an Actor in the current ba.Activity.

def handlemessage(self, msg: Any) -> Any:
141    def handlemessage(self, msg: Any) -> Any:
142        assert not self.expired
143        if isinstance(msg, ba.DieMessage):
144            self._die(msg.immediate)
145        else:
146            super().handlemessage(msg)

General message handling; can be passed any message object.

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