diff --git a/frontend/static/js/api/game/Ball.js b/frontend/static/js/api/game/Ball.js index 24de54e..6836317 100644 --- a/frontend/static/js/api/game/Ball.js +++ b/frontend/static/js/api/game/Ball.js @@ -57,12 +57,8 @@ class Ball { let distance = this.speed * (this.game.time.deltaTime() / 1000) - let angle_radian = this.angle * Math.PI / 180 - - console.log(angle_radian) - - this.position.x = this.position.x + distance * Math.cos(angle_radian); - this.position.y = this.position.y + distance * Math.sin(angle_radian); + this.position.x = this.position.x + distance * Math.cos(this.angle); + this.position.y = this.position.y + distance * Math.sin(this.angle); this.draw(ctx); } diff --git a/games/objects/Game.py b/games/objects/Game.py index 3550f48..e50a2ee 100644 --- a/games/objects/Game.py +++ b/games/objects/Game.py @@ -43,7 +43,7 @@ class Game(AbstractRoom): for i in range(nb_sides): angle: float = (i * 2 * math.pi / nb_sides) + (math.pi * 3 / nb_sides) - + x: float = round(config.MAP_CENTER_X + radius * math.cos(angle)) y: float = round(config.MAP_CENTER_Y + radius * math.sin(angle)) diff --git a/games/routine.py b/games/routine.py index 6dd909a..3dfbcbf 100644 --- a/games/routine.py +++ b/games/routine.py @@ -22,52 +22,100 @@ from asgiref.sync import SyncToAsync from time import sleep -def get_sign(num: float): - return 1 if num >= 0 else -1 +def get_sign(num: float) -> int: + if (num == 0): + return 1 + if (num > 0): + return 1 + if (num < 0): + return -1 -def get_impact_point(segments: list[Segment], ball: Ball): - - angle_radian: float = ball.angle * math.pi / 180 - - direction_vector: Vector = Vector(math.cos(angle_radian), math.sin(angle_radian)) - - x: float = ball.position.x - if (direction_vector.x > 0): - x = x + ball.size / 2 - elif (direction_vector.x < 0): - x = x - ball.size / 2 +def simplify_angle(angle: float): - y: float = ball.position.y - if (direction_vector.y > 0): - y = y + ball.size / 2 - elif (direction_vector.y < 0): - y = y - ball.size / 2 - - position: Point = Point(x, y) + return (angle + 2 * math.pi) % (2 * math.pi) +def exclude_invalid_segments(segments: list[Segment], ball: Ball): + + cos: float = math.cos(ball.angle) + sin: float = math.sin(ball.angle) + + valid_segments = [] + + print(ball.angle) + angle: float = ball.angle + for segment in segments: - segment_vector: Vector = Vector(segment.start.x - segment.stop.x, segment.start.y - segment.stop.y) - segment_vector_unit = segment_vector / segment_vector.norm + diff_x: float = segment.start.x - ball.position.x + diff_y: float = segment.start.y - ball.position.y - scalar: float = segment_vector_unit.scalar(direction_vector) + start_angle: float = math.atan2(diff_y, diff_x) - if (scalar < 0.01): + diff_x: float = segment.stop.x - ball.position.x + diff_y: float = segment.stop.y - ball.position.y + stop_angle: float = math.atan2(diff_y, diff_x) + + min_angle: float = min(start_angle, stop_angle) + max_angle: float = max(start_angle, stop_angle) + + print(min_angle, max_angle) + + if not (min_angle <= angle <= max_angle): continue + + start_cos: float = math.cos(start_angle) + start_sin: float = math.sin(start_angle) + stop_cos: float = math.cos(stop_angle) + stop_sin: float = math.sin(stop_angle) + + if (get_sign(start_cos) != get_sign(cos) and get_sign(cos) != get_sign(stop_cos)): + continue + + if (get_sign(start_sin) != get_sign(sin) and get_sign(sin) != get_sign(stop_sin)): + continue + + valid_segments.append(segment) - print(segment_vector, segment_vector_unit, direction_vector) + return valid_segments + +def get_derive(segment: Segment): + + if (segment.start.x == segment.stop.x): + return None + + return (segment.stop.y - segment.start.y) / (segment.stop.x - segment.stop.y) + +def get_intercept(derive: float, point: Point): + + if (derive is None): + return None + + return point.y - (point.x * derive) + +def get_interception(segment1: Segment, segment2: Segment): + + #TODO https://chat.openai.com/c/3fd8b80f-86cc-4fb9-8ff1-44c108f5ccae + pass + +def get_impact_point(segments: list[Segment], ball: Ball): + + valid_segments: list[Segment] = exclude_invalid_segments(segments, ball) + + point: Point = Point(ball.position.x + math.cos(ball.angle), ball.position.y + math.sin(ball.angle)) + + closest: Point = None + distance: float = None + + for segment in valid_segments: + + impact: Point = get_interception(Segment(ball.position, point), segment) + distance2: float = impact.distance(ball.position) - distance: float = scalar * segment_vector.norm / 2 - - impact_x: float = position.x + distance * direction_vector.x - - impact_y: float = position.y + distance * direction_vector.y - - impact: Point = Point(impact_x, impact_y) - - print("impact", impact) - - return impact + if (closest is None or distance2 < distance): + closest = impact + distance = distance2 + + return closest async def update_ball(game: Game, impact: Point):