Last active
April 7, 2020 22:25
-
-
Save vinci6k/ffec6f3dfdc3df586f66ffb6409a1eda to your computer and use it in GitHub Desktop.
Make entities bounce in Source Engine games with Source.Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ../bouncy_entity/bouncy_entity.py | |
# Python | |
import math | |
import random | |
# Source.Python | |
from entities.dictionary import EntityDictionary | |
from entities.entity import Entity | |
from mathlib import Vector | |
class BouncyEntity(Entity): | |
"""Modified Entity class with some bouncy elements. | |
Args: | |
index (int): A valid entity index. | |
caching (bool): Check for a cached instance? | |
Attributes: | |
bounce_multiplier (float): Used to fine tune or exaggerate the | |
bounce velocity. | |
ground_check (bool): Does the entity have to be on the ground before | |
bouncing? | |
think (Repeat): Instance of Repeat() used for looping the `_think()` | |
function. | |
""" | |
def __init__(self, index, caching=True): | |
"""Initializes the object.""" | |
super().__init__(index, caching) | |
self.bounce_multiplier = 1.0 | |
self.ground_check = False | |
self.think = self.repeat(self._think) | |
def bounce(self): | |
"""Makes the entity jump in a random direction.""" | |
# Pick a random direction. (x = left/right, y = forward/backward) | |
x = 150 * random.randint(-1, 1) | |
y = 150 * random.randint(-1, 1) | |
# Calculate the new velocity. | |
velocity = (Vector(x, y, 300) * self.physics_object.mass * | |
self.bounce_multiplier) | |
# Apply the new velocity. | |
self.physics_object.apply_force_center(velocity) | |
def start_bouncing(self, tickrate, multiplier, ground_check, duration=0): | |
"""Sets up the bounce related attributes and starts the thinking loop. | |
Args: | |
tickrate (float): How often should the `_think()` function be | |
called? (in seconds) | |
multiplier (float): Used to fine tune or exaggerate the | |
bounce velocity. | |
ground_check (bool): Do we check if the entity is on the ground? | |
duration (float): For how long should the entity bounce? | |
""" | |
self.bounce_multiplier = multiplier | |
self.ground_check = ground_check | |
# Let the entity do some thinking. (start looping `_think()`) | |
self.think.start( | |
interval=tickrate, | |
# Should the entity stop bouncing after a while? | |
limit=(duration / tickrate) if duration else math.inf | |
) | |
def _think(self): | |
# Is the entity parented to something? | |
# (e.g. weapon being carried by a player) | |
if self.parent: | |
self.think.stop() | |
return | |
if self.ground_check: | |
# Is the entity still falling? | |
if int(self.physics_object.velocity[0].length): | |
return | |
self.bounce() | |
bouncy_instances = EntityDictionary(BouncyEntity) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment