game: collision work

This commit is contained in:
starnakin 2024-02-02 17:39:39 +01:00 committed by AdrienLSH
parent c7e7410baf
commit d45b8a306f
3 changed files with 32 additions and 39 deletions

View File

@ -10,7 +10,7 @@ class Ball:
def __init__(self) -> None: def __init__(self) -> None:
self.size: float = config.BALL_SIZE self.size: float = config.BALL_SIZE
self.position: Point = Point(config.BALL_SPAWN_POS_X + self.size / 2, config.BALL_SPAWN_POS_Y + self.size / 2) self.position: Point = Point(config.BALL_SPAWN_POS_X + self.size / 2, config.BALL_SPAWN_POS_Y + self.size / 2)
self.angle: float = math.pi * 0 self.angle: float = math.pi * 0.25
self.speed: float = config.BALL_SPEED_START self.speed: float = config.BALL_SPEED_START
def to_dict(self): def to_dict(self):

View File

@ -15,6 +15,9 @@ class Segment:
def __str__(self) -> str: def __str__(self) -> str:
return f"Segment(start: {self.start}, stop: {self.stop})" return f"Segment(start: {self.start}, stop: {self.stop})"
def copy(self):
return Segment(self.start.copy(), self.stop.copy())
def to_dict(self): def to_dict(self):
data: dict[str: dict] = { data: dict[str: dict] = {

View File

@ -15,6 +15,8 @@ from .objects.Vector import Vector
from . import config from . import config
from . import config
import math import math
import asyncio import asyncio
@ -65,16 +67,21 @@ def get_interception(segment1: Segment, segment2: Segment):
if (identify(segment1) == VERTICALLY and identify(segment2) == VERTICALLY): if (identify(segment1) == VERTICALLY and identify(segment2) == VERTICALLY):
return None return None
# because of in matematics world y = 10 is above y = 5 and on a display it is inverted I invert the coordonate
tmp1 = Segment(Point(segment1.start.x, config.MAP_SIZE_Y - segment1.start.y), Point(segment1.stop.x, config.MAP_SIZE_Y - segment1.stop.y))
tmp2 = Segment(Point(segment2.start.x, config.MAP_SIZE_Y - segment2.start.y), Point(segment2.stop.x, config.MAP_SIZE_Y - segment2.stop.y))
if (identify(segment1) == NORMAL and identify(segment2) == NORMAL): if (identify(segment1) == NORMAL and identify(segment2) == NORMAL):
# representation m * x + p # representation m * x + p
m1 = get_derive(segment1) m1 = get_derive(tmp1)
m2 = get_derive(segment2) m2 = get_derive(tmp2)
p1 = get_intercept(m1, segment1.start) p1 = get_intercept(m1, tmp1.start)
p2 = get_intercept(m2, segment2.start) p2 = get_intercept(m2, tmp2.start)
# m1 * x + p1 = m2 * x + p2 # m1 * x + p1 = m2 * x + p2
# m1 * x = m2 * x + p2 -p1 # m1 * x = m2 * x + p2 -p1
@ -83,27 +90,27 @@ def get_interception(segment1: Segment, segment2: Segment):
# x = (p1 - p2) / (m1 - m2) # x = (p1 - p2) / (m1 - m2)
if (m1 == m2): if (m1 == m2):
return None return None
else:
x: float = (p1 - p2) / (m1 - m2)
y: float = m1 * x + p1
# reinvert
x: float = (p1 - p2) / (m1 - m2) * (-1)
y: float = config.MAP_SIZE_Y - (m1 * x + p1)
else: else:
if (identify(segment1) == VERTICALLY): if (identify(tmp1) == VERTICALLY):
constant: float = get_constant(segment1) constant: float = get_constant(tmp1)
m: float = get_derive(segment2) m: float = get_derive(tmp2)
p: float = get_intercept(m, segment2.start) p: float = get_intercept(m, tmp2.start)
else: else:
constant: float = get_constant(segment2) constant: float = get_constant(tmp2)
m: float = get_derive(segment1) m: float = get_derive(tmp1)
p: float = get_intercept(m, segment1.start) p: float = get_intercept(m, tmp1.start)
x: float = constant x: float = constant
y: float = m * x + p y: float = config.MAP_SIZE_Y - (m * x + p)
impact: Point = Point(x,y) impact: Point = Point(x, y)
return impact return impact
@ -112,14 +119,8 @@ def get_impact_point(segments: list[Segment], ball: Ball):
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)
print("cos:", cos)
print("sin:", sin)
point: Point = Point(ball.position.x + cos, ball.position.y - sin) point: Point = Point(ball.position.x + cos, ball.position.y - sin)
print(ball.position)
print(point)
ball_segment = Segment(ball.position, point) ball_segment = Segment(ball.position, point)
closest: Point = None closest: Point = None
@ -127,23 +128,17 @@ def get_impact_point(segments: list[Segment], ball: Ball):
for segment in segments: for segment in segments:
impact: Point = get_interception(segment, ball_segment) impact: Point = get_interception(segment, ball_segment)
if (impact is None): if (impact is None):
continue continue
diff_x: float = ball.position.x - impact.x diff_x: float = ball.position.x - impact.x
print("x:", diff_x)
if (get_sign(diff_x) == get_sign(cos) and cos != 0): if (get_sign(diff_x) == get_sign(cos) and cos != 0):
continue continue
print("OK: X")
diff_y: float = ball.position.y - impact.y diff_y: float = (ball.position.y - impact.y)
print("y:", diff_y)
if (get_sign(diff_y) != get_sign(sin) and sin != 0): if (get_sign(diff_y) != get_sign(sin) and sin != 0):
continue continue
print("OK: Y")
print("OK: PARFAIT", impact)
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)
@ -157,12 +152,8 @@ async def update_ball(game: Game, impact: Point):
distance: float = impact.distance(game.ball.position) distance: float = impact.distance(game.ball.position)
print("distance:", distance)
time_before_impact: float = distance / game.ball.speed time_before_impact: float = distance / game.ball.speed
print("time:", time_before_impact)
await asyncio.sleep(time_before_impact) await asyncio.sleep(time_before_impact)
game.ball.angle = game.ball.angle + math.pi game.ball.angle = game.ball.angle + math.pi
@ -177,10 +168,9 @@ 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 = get_impact_point(segments, game.ball, )
await update_ball(game, impact) await update_ball(game, impact)
print("bozo")
def routine(game: Game): def routine(game: Game):