game: add: wall collision
This commit is contained in:
parent
768af46c66
commit
cc4c09fd0d
@ -110,7 +110,7 @@ def get_interception(segment1: Segment, segment2: Segment):
|
|||||||
|
|
||||||
return impact
|
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)
|
cos: float = round(math.cos(ball.angle), 6)
|
||||||
sin: float = round(math.sin(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)
|
ball_segment = Segment(ball.position, point)
|
||||||
|
|
||||||
closest: Point = None
|
closest: dict = None
|
||||||
|
|
||||||
for segment in segments:
|
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.x += (ball.size / 2) * get_sign(cos) * (-1)
|
||||||
impact.y += (ball.size / 2) * get_sign(sin)
|
impact.y += (ball.size / 2) * get_sign(sin)
|
||||||
|
|
||||||
if (closest is None or impact.distance(ball.position) < closest.distance(ball.position)):
|
if (closest is None or impact.distance(ball.position) < closest.get("distance")):
|
||||||
closest = impact
|
closest = {
|
||||||
|
"impact": impact,
|
||||||
|
"segment": segment,
|
||||||
|
"distance": impact.distance(ball.position),
|
||||||
|
}
|
||||||
|
|
||||||
return closest
|
return closest
|
||||||
|
|
||||||
async def update_ball(game: Game, impact: Point):
|
def wall_colision(ball_angle: float, wall_angle: float) -> float:
|
||||||
|
|
||||||
distance: float = impact.distance(game.ball.position)
|
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):
|
||||||
|
|
||||||
|
distance: float = impact.get("distance")
|
||||||
|
|
||||||
time_before_impact: float = distance / game.ball.speed
|
time_before_impact: float = distance / game.ball.speed
|
||||||
|
|
||||||
await asyncio.sleep(time_before_impact)
|
await asyncio.sleep(time_before_impact)
|
||||||
|
|
||||||
game.ball.angle = game.ball.angle + math.pi
|
segment: Segment = impact.get("segment")
|
||||||
|
|
||||||
game.ball.position = impact
|
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.get("impact")
|
||||||
|
|
||||||
await SyncToAsync(game.broadcast)("update_ball", game.ball.to_dict())
|
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]
|
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)
|
await update_ball(game, impact)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user