game: add: use straight line colision (Not finished)

This commit is contained in:
starnakin 2024-02-01 17:37:46 +01:00
parent beb0cd4702
commit 5f8c42d0c3
3 changed files with 87 additions and 43 deletions

View File

@ -57,12 +57,8 @@ class Ball
{ {
let distance = this.speed * (this.game.time.deltaTime() / 1000) let distance = this.speed * (this.game.time.deltaTime() / 1000)
let angle_radian = this.angle * Math.PI / 180 this.position.x = this.position.x + distance * Math.cos(this.angle);
this.position.y = this.position.y + distance * Math.sin(this.angle);
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.draw(ctx); this.draw(ctx);
} }

View File

@ -22,52 +22,100 @@ from asgiref.sync import SyncToAsync
from time import sleep from time import sleep
def get_sign(num: float): def get_sign(num: float) -> int:
return 1 if num >= 0 else -1 if (num == 0):
return 1
if (num > 0):
return 1
if (num < 0):
return -1
def get_impact_point(segments: list[Segment], ball: Ball): def simplify_angle(angle: float):
angle_radian: float = ball.angle * math.pi / 180 return (angle + 2 * math.pi) % (2 * math.pi)
direction_vector: Vector = Vector(math.cos(angle_radian), math.sin(angle_radian)) def exclude_invalid_segments(segments: list[Segment], ball: Ball):
x: float = ball.position.x cos: float = math.cos(ball.angle)
if (direction_vector.x > 0): sin: float = math.sin(ball.angle)
x = x + ball.size / 2
elif (direction_vector.x < 0):
x = x - ball.size / 2
y: float = ball.position.y valid_segments = []
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) print(ball.angle)
angle: float = ball.angle
for segment in segments: for segment in segments:
segment_vector: Vector = Vector(segment.start.x - segment.stop.x, segment.start.y - segment.stop.y) diff_x: float = segment.start.x - ball.position.x
segment_vector_unit = segment_vector / segment_vector.norm 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 continue
print(segment_vector, segment_vector_unit, direction_vector) 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)
distance: float = scalar * segment_vector.norm / 2 if (get_sign(start_cos) != get_sign(cos) and get_sign(cos) != get_sign(stop_cos)):
continue
impact_x: float = position.x + distance * direction_vector.x if (get_sign(start_sin) != get_sign(sin) and get_sign(sin) != get_sign(stop_sin)):
continue
impact_y: float = position.y + distance * direction_vector.y valid_segments.append(segment)
impact: Point = Point(impact_x, impact_y) return valid_segments
print("impact", impact) def get_derive(segment: Segment):
return impact 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)
if (closest is None or distance2 < distance):
closest = impact
distance = distance2
return closest
async def update_ball(game: Game, impact: Point): async def update_ball(game: Game, impact: Point):