def align(pos: vec3, ball: Ball, goal: vec3): return max( dot(ground_direction(pos, ball), ground_direction(ball, goal)), dot(ground_direction(pos, ball), ground_direction(ball, goal + vec3(800, 0, 0))), dot(ground_direction(pos, ball), ground_direction(ball, goal - vec3(800, 0, 0))))
def turn_circles(self): """renders turning circles in cyan""" speed = norm(self.info.my_car.vel) r = -6.901E-11 * speed**4 + 2.1815E-07 * speed**3 - 5.4437E-06 * speed**2 + 0.12496671 * speed + 157 k = self.turn_c_quality circleR = [] centreR = vec3(0, r, 0) for i in range(k): theta = (2 / k) * math.pi * i point = centreR + vec3(r * math.sin(theta), -r * math.cos(theta), 0) point = self.info.my_car.pos + dot(self.info.my_car.theta, point) circleR.append(point) circleL = [] centreL = vec3(0, -r, 0) for i in range(k): theta = (2 / k) * math.pi * i point = centreL + vec3(r * math.sin(theta), r * math.cos(theta), 0) point = self.info.my_car.pos + dot(self.info.my_car.theta, point) circleL.append(point) self.renderer.begin_rendering("turn circles") self.renderer.draw_polyline_3d(circleR, self.renderer.cyan()) self.renderer.draw_polyline_3d(circleL, self.renderer.cyan()) self.renderer.end_rendering()
def init_kick_off(agent): if abs(agent.info.my_car.pos[0]) < 250: pad = get_closest_small_pad(agent) target = vec3(pad.pos[0], pad.pos[1], pad.pos[2]) - sign(agent.team) * vec3(0, 500, 0) agent.drive = Drive(agent.info.my_car, target, 2400) agent.kickoffStart = "Center" elif abs(agent.info.my_car.pos[0]) < 1000: target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 2400) agent.kickoffStart = "offCenter" else: if random.choice([True, False]): pad = get_closest_small_pad(agent) vec3_pad = vec3(pad.pos[0], pad.pos[1], pad.pos[2]) car_to_pad = vec3_pad - agent.info.my_car.pos target = agent.info.my_car.pos + 1 * car_to_pad agent.drive = Drive(agent.info.my_car, target, 2300) agent.kickoffStart = "Diagonal_Scrub" else: target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 2400) agent.kickoffStart = "Diagonal" agent.step = "Drive" agent.drive.step(agent.FPS) agent.controls = agent.drive.controls
def loc(obj) -> vec3: if hasattr(obj, "pos"): return obj.pos elif hasattr(obj, "x"): return vec3(obj.x, obj.y, obj.z) elif hasattr(obj, "X"): return vec3(obj.X, obj.Y, obj.Z) return obj
def point_to_tile(info, point): if point[1] > 0: point = point - vec3(0, MIDDLE_OFFSET, 0) else: point = point - vec3(0, -MIDDLE_OFFSET, 0) hex = point_to_hex(point) if hex in info.tile_dict: return info.tile_dict[hex] return None
def aerial_face(car, dir, up=vec3(0, 0, 1)): pos = car.pos target = look_at(vec3(dir[0], dir[1], dir[2]), up) action = AerialTurn(car, target) action.step(1 / 60) pitch = action.controls.pitch roll = action.controls.roll yaw = action.controls.yaw return pitch, roll, yaw
def get_path( time, dt ): path = [] t, path1, path2=self.will_hit( ball, self.car, time ) newvel = self.predict_ball(ball, self.car) ball = Ball( self.info.ball ) swapped = False for i in range(int(time/dt)): ball.step(dt) path.append(vec3(ball.pos)) if i > t and not swapped: ball.vel = vec3(newvel[0].item(), newvel[1].item(), newvel[2].item()) swapped = True return path
def __init__(self, car, target_pos=vec3(0, 0, 0), target_speed=0): self.car = car self.target_pos = target_pos self.target_speed = target_speed self.controls = Input() self.finished = False
def handle_aerial_start(self) -> None: ball_prediction: BallPrediction = self.agent.get_ball_prediction_struct() # Find the first viable point on the ball path to aerial to for i in range(ball_prediction.num_slices): loc = ball_prediction.slices[i].physics.location self.aerial.target = vec3(loc.x, loc.y, loc.z) self.aerial.t_arrival = ball_prediction.slices[i].game_seconds if self.aerial.is_viable(): break
def car_trajectory(self, car: Car, end_time: float, dt: float = 1 / 10): steps = [] test_car = Car(car) while test_car.time < end_time: dt = min(dt, end_time - test_car.time) test_car.step(Input(), dt) test_car.time += dt steps.append(vec3(test_car.pos)) self.polyline(steps)
def predict(self): self.bounces = [] ball_prediction = self.get_ball_prediction_struct() for i in range(ball_prediction.num_slices): location = vec3(ball_prediction.slices[i].physics.location.x, ball_prediction.slices[i].physics.location.y, ball_prediction.slices[i].physics.location.z) prev_ang_vel = ball_prediction.slices[i - 1].physics.angular_velocity prev_normalized_ang_vel = normalize( vec3(prev_ang_vel.x, prev_ang_vel.y, prev_ang_vel.z)) current_ang_vel = ball_prediction.slices[ i].physics.angular_velocity current_normalized_ang_vel = normalize( vec3(current_ang_vel.x, current_ang_vel.y, current_ang_vel.z)) if prev_normalized_ang_vel != current_normalized_ang_vel and location[ 2] < 125: self.bounces.append((location, i * 1 / 60))
def shooting_target(agent): ball = agent.info.ball car = agent.info.my_car car_to_ball = ball.pos - car.pos backline_intersect = line_backline_intersect( agent.info.their_goal.center[1], vec2(car.pos), vec2(car_to_ball)) if -500 < backline_intersect < 500: goal_to_ball = normalize(car.pos - ball.pos) error = cap(distance_2d(ball.pos, car.pos) / 1000, 0, 1) else: # Right of the ball if -500 > backline_intersect: target = agent.info.their_goal.corners[3] + vec3(400, 0, 0) # Left of the ball elif 500 < backline_intersect: target = agent.info.their_goal.corners[2] - vec3(400, 0, 0) goal_to_ball = normalize(ball.pos - target) goal_to_car = normalize(car.pos - target) difference = goal_to_ball - goal_to_car error = cap(abs(difference[0]) + abs(difference[1]), 1, 10) goal_to_ball_2d = vec2(goal_to_ball[0], goal_to_ball[1]) test_vector_2d = dot(rotation(0.5 * math.pi), goal_to_ball_2d) test_vector = vec3(test_vector_2d[0], test_vector_2d[1], 0) distance = cap((40 + distance_2d(ball.pos, car.pos) * (error**2)) / 1.8, 0, 4000) location = ball.pos + vec3( (goal_to_ball[0] * distance), goal_to_ball[1] * distance, 0) # this adjusts the target based on the ball velocity perpendicular to the direction we're trying to hit it multiplier = cap(distance_2d(car.pos, location) / 1500, 0, 2) distance_modifier = cap( dot(test_vector, ball.vel) * multiplier, -1000, 1000) modified_vector = vec3(test_vector[0] * distance_modifier, test_vector[1] * distance_modifier, 0) location += modified_vector # another target adjustment that applies if the ball is close to the wall extra = 3850 - abs(location[0]) if extra < 0: location[0] = cap(location[0], -3850, 3850) location[1] = location[1] + (-sign(agent.team) * cap(extra, -800, 800)) return location
def __init__(self, index, team, field_info=None): self.time = 0 self.ball = Ball() self.pitch = Pitch() if field_info is None: self.my_goal = Goal(team) self.their_goal = Goal(1 - team) self.boost_pads = [ BoostPad(3, vec3(-3072.0, -4096.0, 73.0), True, 0.0), BoostPad(4, vec3(3072.0, -4096.0, 73.0), True, 0.0), BoostPad(15, vec3(-3584.0, 0.0, 73.0), True, 0.0), BoostPad(18, vec3(3584.0, 0.0, 73.0), True, 0.0), BoostPad(29, vec3(-3072.0, 4096.0, 73.0), True, 0.0), BoostPad(30, vec3(3072.0, 4096.0, 73.0), True, 0.0) ] self.small_boost_pads = [] else: self.my_goal = Goal(team, field_info) self.their_goal = Goal(1 - team, field_info) self.boost_pads = [] self.small_boost_pads = [] for i in range(field_info.num_boosts): current = field_info.boost_pads[i] if field_info.boost_pads[i].is_full_boost: self.boost_pads.append( BoostPad( i, vec3(current.location.x, current.location.y, current.location.z), True, 0.0)) else: self.small_boost_pads.append( BoostPad( i, vec3(current.location.x, current.location.y, current.location.z), True, 0.0)) self.team = team self.index = index self.cars = [] self.teammates = [] self.opponents = [] self.my_car = Car() self.ball_predictions = [] self.about_to_score = None self.about_to_be_scored_on = None self.time_of_goal = -1
def triangle(self, pos: vec3, pointing_dir: vec3, width=50, length=50, up=vec3(0, 0, 1)): left = pos + cross(pointing_dir, up) * width / 2 right = pos - cross(pointing_dir, up) * width / 2 top = pos + pointing_dir * length self.line(left, right) self.line(left, top) self.line(right, top)
def render_target(self, pos): self.renderer.draw_line_3d(pos - 100 * vec3(1, 0, 0), pos + 100 * vec3(1, 0, 0), self.renderer.blue()) self.renderer.draw_line_3d(pos - 100 * vec3(0, 1, 0), pos + 100 * vec3(0, 1, 0), self.renderer.blue()) self.renderer.draw_line_3d(pos - 100 * vec3(0, 0, 1), pos + 100 * vec3(0, 0, 1), self.renderer.blue())
def highlight_tile(renderer, tile, color): vecs = [ tile.location + vec3(tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0), tile.location + vec3(0, tiles.TILE_SIZE, 0), tile.location + vec3(-tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0), tile.location + vec3(-tiles.TILE_WIDTH / 2, -tiles.TILE_SIZE / 2, 0), tile.location + vec3(0, -tiles.TILE_SIZE, 0), tile.location + vec3(tiles.TILE_WIDTH / 2, -tiles.TILE_SIZE / 2, 0), tile.location + vec3(tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0) ] renderer.draw_polyline_3d(vecs, color)
class Arena: size = vec3(4096, 5120, 2044) @classmethod def clamp(cls, pos: vec3, offset: float = 0) -> vec3: return vec3( signclamp(pos[0], cls.size[0] - offset), signclamp(pos[1], cls.size[1] - offset), pos[2] ) @classmethod def inside(cls, pos: vec3, offset: float = 0) -> bool: return abs(pos[0]) < cls.size[0] - offset and abs(pos[1]) < cls.size[1] - offset
def highlight_point_on_tile(renderer, info, point, color): flat = vec3(point[0], point[1], 0) tile = tiles.point_to_tile(info, point) renderer.draw_line_3d(point, flat, color) if tile != None: vecs = [ tile.location + vec3(tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0), tile.location + vec3(0, tiles.TILE_SIZE, 0), tile.location + vec3(-tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0), tile.location + vec3(-tiles.TILE_WIDTH / 2, -tiles.TILE_SIZE / 2, 0), tile.location + vec3(0, -tiles.TILE_SIZE, 0), tile.location + vec3(tiles.TILE_WIDTH / 2, -tiles.TILE_SIZE / 2, 0), tile.location + vec3(tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0) ] renderer.draw_polyline_3d(vecs, color) for i in range(6): renderer.draw_line_3d(flat, vecs[i], color)
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.info.read_packet(packet) if self.action == None or self.action.finished or self.counter == 400: target_pos = vec3( random.uniform(-3000, 3000), random.uniform(-2000, 2000), 25 ) target_speed = random.uniform(500, 2000) self.action = Drive(self.info.my_car, target_pos, target_speed) self.counter = 0 r = 200 self.renderer.begin_rendering() purple = self.renderer.create_color(255, 230, 30, 230) self.renderer.draw_line_3d(self.action.target_pos - r * vec3(1, 0, 0), self.action.target_pos + r * vec3(1, 0, 0), purple) self.renderer.draw_line_3d(self.action.target_pos - r * vec3(0, 1, 0), self.action.target_pos + r * vec3(0, 1, 0), purple) self.renderer.draw_line_3d(self.action.target_pos - r * vec3(0, 0, 1), self.action.target_pos + r * vec3(0, 0, 1), purple) self.renderer.end_rendering() if controller.L1: self.controls = controller.get_output() else: self.counter += 1 if (self.counter % 10) == 0: print(f"current speed: {norm(self.info.my_car.vel):4.4f}, \ desired speed: {self.action.target_speed:4.4f}") self.action.step(0.01666) self.controls = self.action.controls return self.controls
def arc(self, pos: vec3, radius: float, start: float, end: float, segments: int = 50): step = (end - start) / segments prev_l = None for i in range(segments + 1): angle = start + step * i l = pos + vec3( math.cos(angle) * radius, math.sin(angle) * radius, 0) if prev_l is not None: self.line(prev_l, l) prev_l = l
def highlight_tile_more(renderer, tile, color): vecs = [ tile.location + vec3(tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0), tile.location + vec3(0, tiles.TILE_SIZE, 0), tile.location + vec3(-tiles.TILE_WIDTH / 2, tiles.TILE_SIZE / 2, 0), tile.location + vec3(-tiles.TILE_WIDTH / 2, -tiles.TILE_SIZE / 2, 0), tile.location + vec3(0, -tiles.TILE_SIZE, 0), tile.location + vec3(tiles.TILE_WIDTH / 2, -tiles.TILE_SIZE / 2, 0) ] for i in range(6): for j in range(i + 1, 6): renderer.draw_line_3d(vecs[i], vecs[j], color)
def tick(self, packet: GameTickPacket) -> StepResult: if self.game_info is None: self.game_info = GameInfo(self.index, packet.game_cars[self.index].team) self.game_info.read_packet(packet) if self.aerial is None: self.aerial = Aerial( self.game_info.my_car, vec3(self.target.x, self.target.y, self.target.z), self.arrival_time) self.aerial.step(SECONDS_PER_TICK) controls = SimpleControllerState() controls.boost = self.aerial.controls.boost controls.pitch = self.aerial.controls.pitch controls.yaw = self.aerial.controls.yaw controls.roll = self.aerial.controls.roll controls.jump = self.aerial.controls.jump return StepResult(controls, packet.game_info.seconds_elapsed > self.arrival_time)
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: # Hit the ball blindly if the bot is between the ball and its own goal. This is to clear it away. # Hit the ball to the side if the ball is closer to its own goal than it is. self.agent.game_info.read_packet(packet) if self.dodge is not None: self.dodge.step(1 / 60) if not self.dodge.finished: return self.dodge.controls else: self.dodge = None controller: SimpleControllerState = SimpleControllerState() ball: Vector3 = Vector3(packet.game_ball.physics.location) bot: PhysicsObject = PhysicsObject( packet.game_cars[self.agent.index].physics) target: Vector3 if abs(ball.y) < abs(bot.location.y): target = ball else: offset: float = 100 if ball.x > bot.location.x else -100 offset *= -1 if self.agent.team == 1 else 1 target = ball + Vector3(offset, 0, 0) bot_to_ball: Vector3 = ball - bot.location if abs(bot_to_ball.normalised().x) > 0.7: self.dodge = AirDodge(self.agent.game_info.my_car, 0.1, vec3(ball.x, ball.y, ball.z)) controller.steer = gosling_steering(bot.location, bot.rotation.z, target) controller.boost = True controller.throttle = 1 return controller
import math import rlmath from rlmath import Hex from RLUtilities.LinearAlgebra import vec3 TILE_WIDTH = 768 TILE_SIZE = TILE_WIDTH / math.sqrt(3) TILE_HEIGHT = TILE_SIZE * 2 TILE_COUNT = 140 MIDDLE_OFFSET = 128 Q_VEC = vec3(-TILE_WIDTH, 0, 0) R_VEC = vec3(-TILE_WIDTH / 2, 0.75 * TILE_HEIGHT, 0) class Tile: UNKNOWN = 0 FILLED = 1 DAMAGED = 2 OPEN = 3 def __init__(self, location, hex, team): self.location = location self.hex = hex self.team = team self.state = Tile.UNKNOWN
def get_stats(self): ball = Ball() ball.pos = vec3( self.pos[0].item(), self.pos[1].item(), self.pos[2].item() ) ball.vel = vec3( self.vel[0].item(), self.vel[1].item(), self.vel[2].item() ) ball.omega = vec3( self.avel[0].item(), self.avel[1].item(), self.avel[2].item() ) return ball
def kick_off(agent): if agent.kickoffStart == "Diagonal_Scrub": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.drive.finished: agent.step = "Dodge1" # target = agent.info.ball.pos target = normalize(z0(agent.info.my_car.forward())) * 1000 agent.dodge = AirDodge(agent.info.my_car, 0.075, target) elif agent.step == "Dodge1": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished: agent.step = "Steer" target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 1399) elif agent.step == "Steer": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.info.my_car.on_ground: agent.drive.target_speed = 2400 if distance_2d(agent.info.ball.pos, agent.info.my_car.pos) < 750: agent.step = "Dodge2" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge2": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching" elif agent.kickoffStart == "Diagonal": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if distance_2d(agent.info.ball.pos, agent.info.my_car.pos) < 850: agent.step = "Dodge" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching" elif agent.kickoffStart == "Center": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.drive.finished: agent.step = "Dodge1" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge1": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls agent.controls.boost = 0 if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Steer" target = agent.info.ball.pos + sign(agent.team) * vec3( 0, 850, 0) agent.drive = Drive(agent.info.my_car, target, 2400) elif agent.step == "Steer": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.drive.finished: agent.step = "Dodge2" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge2": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching" elif agent.kickoffStart == "offCenter": if agent.step == "Drive": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if agent.info.my_car.boost < 15 or agent.drive.finished: agent.step = "Dodge1" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge1": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls agent.controls.boost = 0 if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Steer" target = agent.info.ball.pos agent.drive = Drive(agent.info.my_car, target, 2400) elif agent.step == "Steer": agent.drive.step(agent.FPS) agent.controls = agent.drive.controls if distance_2d(agent.info.ball.pos, agent.info.my_car.pos) < 850: agent.step = "Dodge2" agent.dodge = AirDodge(agent.info.my_car, 0.075, agent.info.ball.pos) elif agent.step == "Dodge2": agent.dodge.step(agent.FPS) agent.controls = agent.dodge.controls if agent.dodge.finished and agent.info.my_car.on_ground: agent.step = "Catching"
def ground(pos) -> vec3: pos = loc(pos) return vec3(pos[0], pos[1], 0)
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.info.read_packet(packet) if self.phase == None: self.phase = 1 #phase 1: path-planning elif self.phase == 1: self.targets = [vec3(0, 0, 25)] #TODO pick targets self.pathplan() #adds all active boost pads to this list, big boosts first self.active_pads = [] for pad in self.info.boost_pads: if pad.is_active: self.active_pads.append(pad) for pad in self.info.small_boost_pads: if pad.is_active: self.active_pads.append(pad) self.plan_pads = [] self.convboost() #elif self.phase == 2: #TODO follow path #debug prints if True: self.renderer.begin_rendering("debug") self.renderer.draw_string_2d(20, 20, 1, 1, "phase: " + str(self.phase), self.renderer.black()) self.renderer.draw_string_2d(20, 40, 1, 1, "targets: " + str(len(self.targets)), self.renderer.black()) self.renderer.draw_string_2d(20, 60, 1, 1, "guides: " + str(len(self.guides)), self.renderer.black()) self.renderer.draw_string_2d( 20, 80, 1, 1, "big pads: " + str(len(self.info.boost_pads)), self.renderer.black()) self.renderer.draw_string_2d( 20, 100, 1, 1, "small pads: " + str(len(self.info.small_boost_pads)), self.renderer.black()) self.renderer.draw_string_2d( 20, 120, 1, 1, "active pads: " + str(len(self.active_pads)), self.renderer.black()) self.renderer.draw_string_2d( 20, 140, 1, 1, "turn radius: " + str(self.turn_radius()), self.renderer.black()) self.renderer.draw_string_2d(20, 160, 1, 1, "car direction: " + "test", self.renderer.black()) self.renderer.end_rendering() #renders targets for i in range(len(self.targets)): self.renderer.begin_rendering("target" + str(i)) render_target(self, self.targets[i]) self.renderer.end_rendering() #renders path self.renderer.begin_rendering("path") self.renderer.draw_polyline_3d(self.guides, self.renderer.white()) self.renderer.end_rendering() return self.controls
def read_packet(self, packet): self.time = packet.game_info.seconds_elapsed dyn = packet.game_ball.physics self.ball.pos = vec3(dyn.location.x, dyn.location.y, dyn.location.z) self.ball.vel = vec3(dyn.velocity.x, dyn.velocity.y, dyn.velocity.z) self.ball.omega = vec3(dyn.angular_velocity.x, dyn.angular_velocity.y, dyn.angular_velocity.z) self.ball.t = self.time self.ball.step(GameInfo.DT) for i in range(0, packet.num_cars): game_car = packet.game_cars[i] dyn = game_car.physics car = Car() if i < len(self.cars): car = self.cars[i] car.pos = vec3(dyn.location.x, dyn.location.y, dyn.location.z) car.vel = vec3(dyn.velocity.x, dyn.velocity.y, dyn.velocity.z) car.omega = vec3(dyn.angular_velocity.x, dyn.angular_velocity.y, dyn.angular_velocity.z) car.theta = euler_rotation( vec3(dyn.rotation.pitch, dyn.rotation.yaw, dyn.rotation.roll)) car.on_ground = game_car.has_wheel_contact car.supersonic = game_car.is_super_sonic car.jumped = game_car.jumped car.double_jumped = game_car.double_jumped car.boost = game_car.boost car.time = self.time car.extrapolate(GameInfo.DT) if len(self.cars) <= i: car.id = i car.team = game_car.team self.cars.append(car) if game_car.team == self.team: if i == self.index: self.my_car = car else: self.teammates.append(car) else: self.opponents.append(car) for i in range(0, len(self.boost_pads)): boost_pad = packet.game_boosts[self.boost_pads[i].index] self.boost_pads[i].is_active = boost_pad.is_active self.boost_pads[i].timer = boost_pad.timer for i in range(0, len(self.small_boost_pads)): boost_pad = packet.game_boosts[self.small_boost_pads[i].index] self.small_boost_pads[i].is_active = boost_pad.is_active self.small_boost_pads[i].timer = boost_pad.timer self.time += GameInfo.DT
def z0(vector): return vec3(vector[0], vector[1], 0)