Skip to content

Instantly share code, notes, and snippets.

@joereynolds
Created December 11, 2024 17:37
Show Gist options
  • Select an option

  • Save joereynolds/a8b4f4a54980e33b8ef1f7f333417bf2 to your computer and use it in GitHub Desktop.

Select an option

Save joereynolds/a8b4f4a54980e33b8ef1f7f333417bf2 to your computer and use it in GitHub Desktop.
Move and pause baby
from typing import List
from src.entity import Entity
from pygame import Vector2
from src.countdown_timer import CountdownTimer
import src.graphics as g
import itertools
import src.ptext as ptext
class MovesAndPauses:
def __init__(self, parent, pause_for: float, distance: int, velocities: str|List[List[int]], path_id=None) -> None:
self.parent = parent
self.timer = CountdownTimer(pause_for)
self.initial_timer = CountdownTimer(pause_for)
self.distance = distance
self.tiles_travelled = 0
self.rest_position = Vector2(self.parent.physics_rect.x, self.parent.physics_rect.y)
self.pause = False
self.path_id = path_id
if self.path_id:
self.points = itertools.cycle(self.parent.level.paths[self.path_id].points)
self.current_point = next(self.points)
# for convenience
if isinstance(velocities, str):
friendly_mappings = {
'clockwise': [[1,0], [0, 1], [-1,0], [0, -1]],
'anticlockwise': [[0, 1], [1, 0], [0, -1], [-1, 0]],
'up-down': [[0, -1],[0, 1]],
'down-up': [[0, 1], [0, -1]]
}
velocities = friendly_mappings[velocities]
self.velocities = itertools.cycle(velocities)
self.current_velocity = next(self.velocities)
def update(self, dt: float, level, player, events: List):
if self.path_id:
self.update_with_path(dt, level, player, events)
return
if not self.initial_timer.has_ended():
self.initial_timer.update(dt)
return
speed = self.parent.get_component('speed').speed
current_position = (self.parent.physics_rect.x, self.parent.physics_rect.y)
travelled = current_position - self.rest_position
distance_travelled = 0
tile_width = 16
if self.current_velocity in [[1, 0],[-1, 0]]:
if travelled.x > 0:
distance_travelled = travelled.x // tile_width
else:
distance_travelled = -(travelled.x) // tile_width
if self.current_velocity in [[0, 1],[0, -1]]:
if travelled.y > 0:
distance_travelled = travelled.y // tile_width
else:
distance_travelled = -(travelled.y) // tile_width
if distance_travelled >= self.distance and not self.pause: # and not self.timer.has_ended():
self.pause = True
self.current_velocity = Vector2(0, 0)
nearest_tile_x = g.round_up_to_closest_tile(self.parent.physics_rect.x)
nearest_tile_y = g.round_up_to_closest_tile(self.parent.physics_rect.y)
self.rest_position = Vector2(nearest_tile_x, nearest_tile_y)
self.parent.move_to(nearest_tile_x, nearest_tile_y)
if self.pause:
self.timer.update(dt)
if self.timer.has_ended():
self.current_velocity = next(self.velocities)
self.pause = False
self.timer.reset()
self.parent.physics_rect.topleft += Vector2(self.current_velocity) * dt * speed
self.parent.rect.topleft += Vector2(self.current_velocity) * dt * speed
# self.debug(dt, level, player, events)
def update_with_path(self, dt, level, player, events):
if not self.initial_timer.has_ended():
self.initial_timer.update(dt)
return
speed = self.parent.get_component('speed').speed
target = Vector2(self.current_point.x, self.current_point.y)
position = Vector2(self.parent.physics_rect.x, self.parent.physics_rect.y)
heading = (target - position)
distance = heading.length()
snap_radius = 4
if heading != [0, 0]:
heading = heading.normalize()
if distance <= snap_radius and not self.pause:
self.pause = True
self.current_point = next(self.points)
nearest_tile_x = g.round_up_to_closest_tile(self.parent.physics_rect.x)
nearest_tile_y = g.round_up_to_closest_tile(self.parent.physics_rect.y)
self.parent.move_to(nearest_tile_x, nearest_tile_y)
if self.pause:
self.timer.update(dt)
if self.timer.has_ended():
self.pause = False
self.timer.reset()
if distance > snap_radius:
self.parent.physics_rect.topleft += Vector2(heading) * dt * speed
self.parent.rect.topleft += Vector2(heading) * dt * speed
def debug(self, dt: float, level, player, events: List):
if not hasattr(self, 'debug_box'):
self.debug_box = Entity(
self.parent.rect.x + 20,
self.parent.rect.y - 4,
g.tile_width * 8,
g.tile_width,
alpha=True
)
self.debug_box.image.fill((0,0,0,50))
self.debug_box.rect.x = self.parent.rect.x + 20
self.debug_box.rect.y = self.parent.rect.y - 4
ptext.draw(
str(self.timer.timer),
(0,0),
surf=self.debug_box.image,
fontsize=10,
antialias=False
)
level.map.sprites.add(self.debug_box)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment