Skip to content

Instantly share code, notes, and snippets.

@vinci6k
Last active April 7, 2020 22:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vinci6k/ffec6f3dfdc3df586f66ffb6409a1eda to your computer and use it in GitHub Desktop.
Save vinci6k/ffec6f3dfdc3df586f66ffb6409a1eda to your computer and use it in GitHub Desktop.
Make entities bounce in Source Engine games with Source.Python.
# ../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