game: add: wall collision

This commit is contained in:
starnakin 2024-02-07 14:50:03 +01:00
parent 768af46c66
commit cc4c09fd0d

View File

@ -110,7 +110,7 @@ def get_interception(segment1: Segment, segment2: Segment):
return impact
def get_impact_point(segments: list[Segment], ball: Ball):
def get_impact_point(segments: list[Segment], ball: Ball) -> dict:
cos: float = round(math.cos(ball.angle), 6)
sin: float = round(math.sin(ball.angle), 6)
@ -119,7 +119,7 @@ def get_impact_point(segments: list[Segment], ball: Ball):
ball_segment = Segment(ball.position, point)
closest: Point = None
closest: dict = None
for segment in segments:
@ -139,22 +139,46 @@ def get_impact_point(segments: list[Segment], ball: Ball):
impact.x += (ball.size / 2) * get_sign(cos) * (-1)
impact.y += (ball.size / 2) * get_sign(sin)
if (closest is None or impact.distance(ball.position) < closest.distance(ball.position)):
closest = impact
if (closest is None or impact.distance(ball.position) < closest.get("distance")):
closest = {
"impact": impact,
"segment": segment,
"distance": impact.distance(ball.position),
}
return closest
def wall_colision(ball_angle: float, wall_angle: float) -> float:
ball_cos: float = math.cos(ball_angle)
ball_sin: float = math.sin(ball_angle)
incident_angle: float = ball_angle - wall_angle
reflection_angle: float = wall_angle - incident_angle
new_cos: float = math.cos(reflection_angle)
new_sin: float = math.sin(reflection_angle)
new_angle: float = math.atan2(new_sin, new_cos)
return new_angle
async def update_ball(game: Game, impact: dict):
async def update_ball(game: Game, impact: Point):
distance: float = impact.distance(game.ball.position)
distance: float = impact.get("distance")
time_before_impact: float = distance / game.ball.speed
await asyncio.sleep(time_before_impact)
game.ball.angle = game.ball.angle + math.pi
segment: Segment = impact.get("segment")
wall_angle: float = math.atan2(segment.stop.y - segment.start.y, segment.stop.x - segment.start.x)
game.ball.angle = wall_colision(game.ball.angle, wall_angle)
game.ball.position = impact
game.ball.position = impact.get("impact")
await SyncToAsync(game.broadcast)("update_ball", game.ball.to_dict())
@ -164,7 +188,7 @@ async def render(game: Game):
segments: list[Segment] = [player.rail for player in game.players] + [wall.rail for wall in game.walls]
impact = get_impact_point(segments, game.ball, )
impact: dict = get_impact_point(segments, game.ball, )
await update_ball(game, impact)