def draw(self, packet): my_car = packet.game_cars[self.index] car_location = Vector2(my_car.physics.location.x, my_car.physics.location.y) ball_location = Vector2(packet.game_ball.physics.location.x, packet.game_ball.physics.location.y) # color color = self.renderer.create_color(255, 255, 255, 255) white_color = self.renderer.create_color(255, 255, 255, 255) x = 5 y = 10 text_size = 1 if my_car.team == 0: x = 5 color = self.renderer.create_color(255, 22, 138, 255) # blue else: x = 150 color = self.renderer.create_color(255, 255, 127, 80) # orange # drawing self.renderer.draw_string_2d(x, y, text_size, text_size, self.car_status, color) self.renderer.draw_string_2d(x, y+10, text_size, text_size, str(Vector2(car_location.x - ball_location.x, car_location.y - ball_location.y).magnitude()), color) self.renderer.draw_string_2d(x, y+20, text_size, text_size, 'boost: '+str(my_car.boost), color) self.renderer.draw_string_2d(x, y+30, text_size, text_size, 'Jumps: '+str(self.jumps), color) self.renderer.draw_string_2d(x, y+40, text_size, text_size, 'Z: '+str(my_car.physics.location.z), color) self.renderer.draw_string_2d(x, y+50, text_size, text_size, 'speed: '+str(self.average_xy_speed), color) if self.car_status == 'kick_ball': self.renderer.draw_string_2d(x, y+60, text_size, text_size, 'TimeTillHit: '+str(kick_ball.prediction_timer), color) if self.car_status == 'clear_ball': self.renderer.draw_string_2d(x, y+60, text_size, text_size, 'TimeTillHit: '+str(clear_ball.prediction_timer), color)
def get_closest_entity(self, fromLocation, targetClass, range=1000, validityTest=None): closestDist = range closestEntity = None for ent in self.entities.itervalues(): if isinstance(ent, targetClass) and Vector2.get_distance(ent.location, fromLocation) < closestDist: if not validityTest or validityTest(ent): closestDist = Vector2.get_distance(ent.location, fromLocation) closestEntity = ent return closestEntity
def switchVehicle(self, vehicle): self.speed = 0.0 if self.vehicle == vehicle: self.vehicle.move(STOP) self.vehicle = None self.location = vehicle.location + Vector2(-20,0) elif self.vehicle == None and Vector2.get_distance(self.location, vehicle.location) <= 50: self.vehicle = vehicle self.vehicle.start()
def wrong_side(agent, packet): my_car = packet.game_cars[agent.index] car_location = Vector2(my_car.physics.location.x, my_car.physics.location.y) car_direction = get_car_facing_vector(my_car) ball_location = Vector2(packet.game_ball.physics.location.x, packet.game_ball.physics.location.y) goal = get_own_goal(agent, packet) difference = abs(difference_angles(Vector3(goal).to_2d().get_angle(), car_location.get_angle())) # double jump if on ground and straight and going good direction if agent.jumps == [] and my_car.physics.location.z < 17.1 and difference < 10 and get_xy_speed(agent, packet) > 1000 and my_car.boost > 50: agent.controller_state.boost = True if agent.jumps == [] and my_car.physics.location.z < 17.1 and difference < 10 and get_xy_speed(agent, packet) > 1000 and not agent.controller_state.boost: double_jump(agent) aim_to(agent, goal) agent.controller_state.throttle = 1.0 # if in front of the ball+200 reset car status if my_car.team == (my_car.physics.location.y-ball_location.y > -2000): agent.car_status = 'none'
def get_closest_entity(self, fromLocation, targetClass, range=1000, validityTest=None): closestDist = range closestEntity = None for ent in self.entities.itervalues(): if isinstance(ent, targetClass) and Vector2.get_distance( ent.location, fromLocation) < closestDist: if not validityTest or validityTest(ent): closestDist = Vector2.get_distance(ent.location, fromLocation) closestEntity = ent return closestEntity
def get_opponents_goal(agent): car = agent.car field_info = agent.get_field_info() goal = Vector2(0, 0) team = 1 if field_info.goals[team].team_num == car.team: team = 0 return Vector3(field_info.goals[team].location)
def kickoff(agent, packet): car = agent.car ball = agent.ball car_to_ball_magnitude = Vector2(car.pos.x - ball.pos.x, car.pos.y - ball.pos.y).magnitude() plus = 0 agent.controller_state.boost = True agent.controller_state.throttle = 1.0 # 255.97 and 3840.01 if abs(car.pos.x) < 300: if car.team: plus = -car.pos.x/100 else: plus = car.pos.x/100 aim_to(agent, agent.ball.pos, (random()*2-1)+plus, ) #print(car_location.x, car_location.y) # if me hit the ball stop kicking the ball if packet.game_ball.latest_touch.player_name == car.name and packet.game_info.seconds_elapsed - packet.game_ball.latest_touch.time_seconds < 1: agent.car_status = 'none' # If realy close to ball Jump if car_to_ball_magnitude < 500: double_jump(agent) # if on wrong side of the ball reset car status if car.team != (car.pos.y-agent.ball.pos.y > 0): agent.car_status = 'none' return agent
def process(self, time_passed): if self.speed != 0.0: rotationDelta = self.rotationToDo * time_passed * self.rotation_speed if abs(self.rotationToDo - rotationDelta) < 5.0: rotationDelta = self.rotationToDo self.rotationToDo -= rotationDelta self.rotation += rotationDelta heading_x = sin(self.rotation*pi/180.0) heading_y = cos(self.rotation*pi/180.0) heading = Vector2(heading_x, heading_y) self.location += heading * self.speed if not self.soundChannel.get_busy(): self.soundChannel.play(self.drivingSound, -1) # no more rotation to do => handle next action if not self.rotationToDo and self.actionQueue: moveAction = self.actionQueue.pop() direction = moveAction.direction if direction in [LEFT, RIGHT]: self.steer(direction) elif direction == UP: self.accelerate() elif direction == DOWN: self.brake() elif direction == STOP: self.brakeHard()
def __init__(self, centrePoint, width, height): self.id = "rectangle" try: self.x = centrePoint.x self.y = centrePoint.y except AttributeError: self.x = centrePoint[0] self.y = centrePoint[1] self.width = width self.height = height self.topLeft = Vector2(self.x - self.width, self.y + self.height) self.bottomRight = Vector2(self.x + self.width, self.y - self.height)
def get_car_facing_vector(car): pitch = float(car.rotation.pitch) yaw = float(car.rotation.yaw) facing_x = math.cos(pitch) * math.cos(yaw) facing_y = math.cos(pitch) * math.sin(yaw) return Vector2(facing_x, facing_y)
def __init__(self, start_coordinates): self.image = pygame.image.load('../images/nedde.png').convert_alpha() self.location = start_coordinates self.speed = 40.0 self.walking_direction = Vector2(0, 0) self.name = "player" self.foodAmount = 15 self.vehicle = None
def __init__(self, display_size, background_image): self.entities = {} self.active_entities = {} self.entity_id = 0 self.background = background_image self.dimension = self.background.get_size() self.focussed_entity = None self.display_size = display_size self.maximum_expansion = Vector2(*display_size).get_magnitude() self.minimapVisible = True
def get_goal_angle(agent): ball = agent.ball ball_pos = clear_ball.ball_prediction.pos own_goal = agent.info.own_goal ball_to_pole1 = Vector2(893 + ball_pos.x, own_goal.y - ball_pos.y) ball_to_pole2 = Vector2(893 - ball_pos.x, own_goal.y - ball_pos.y) #draw lines agent.renderer.draw_line_3d(ball_pos.get_array(), own_goal.change('x', 893).get_array(), black(agent)) agent.renderer.draw_line_3d(ball_pos.get_array(), own_goal.change('x', -893).get_array(), black(agent)) # return angle return abs( difference_angles(ball_to_pole1.get_angle(), ball_to_pole2.get_angle()) / 2)
def collides(self, otherShape): if otherShape.id == "rectangle": #Do rectangle vs rectangle collision if otherShape.topLeft.x > self.bottomRight.x: return False elif otherShape.bottomRight.x < self.topLeft.x: return False elif otherShape.topLeft.y < self.bottomRight.y: return False elif otherShape.bottomRight.y > self.topLeft.y: return False else: return True elif otherShape.id == "circle": #Test each edge against the circle, and see if the centre of the circle is inside the rectangle if self.pointInside(otherShape.middlePoint): return True elif otherShape.collidesWithLine( (self.topLeft, Vector2(self.bottomRight.x, self.topLeft.y))): return True elif otherShape.collidesWithLine( Vector2(self.bottomRight.x, self.topLeft.y), self.bottomRight): return True elif otherShape.collidesWithLine( self.bottomRight, Vector2(self.topLeft.x, self.bottomRight.y)): return True elif otherShape.collidesWithLine( Vector2(self.topLeft.x, self.bottomRight.y), self.topLeft): return True else: return False
def get_angle_for_goal(agent, packet, ball_location): opponents_goal = get_opponents_goal(agent) ball_to_pole1 = Vector2(opponents_goal.x + 893 - ball_location.x, opponents_goal.y - ball_location.y) ball_to_pole2 = Vector2(opponents_goal.x - 893 - ball_location.x, opponents_goal.y - ball_location.y) #draw lines a = [ball_location.x, ball_location.y, 96] b = [ ball_to_pole1.x + ball_location.x, ball_to_pole1.y + ball_location.y, 96 ] c = [ ball_to_pole2.x + ball_location.x, ball_to_pole2.y + ball_location.y, 96 ] agent.renderer.draw_line_3d(a, b, agent.renderer.create_color(255, 0, 0, 0)) agent.renderer.draw_line_3d(a, c, agent.renderer.create_color(255, 0, 0, 0)) # return angle return abs( (ball_to_pole1.get_angle() - ball_to_pole2.get_angle()) / 2 * 1.5)
def collidesWithLine(self, line): point1 = line[0] point2 = line[1] try: point1.id point2.id except AttributeError: point1 = Vector2(point1[0], point1[1]) point2 = Vector2(point2[0], point2[1]) #Point1 has to be 0 in order to turn the other point into a vector that we can use editedPoint = point2.subtract(point1) editedMiddle = self.middlePoint.subtract(point1) projection = editedMiddle.projection(editedPoint) newProjection = projection.add(point1) if self.pointInside(newProjection): return True else: return False
def __init__(self, middlePoint, radius): self.id = "circle" #If the middlePoint is not provided as a vector, make it one try: middlePoint.id self.middlePoint = middlePoint except AttributeError: self.middlePoint = Vector2(middlePoint[0], middlePoint[1]) self.x = self.middlePoint.x self.y = self.middlePoint.y self.radius = radius
def render(self, surface): display_x = min( self.dimension[0] - self.display_size[0], max(0, self.focussed_entity.location.x - self.display_size[0] / 2)) display_y = min( self.dimension[1] - self.display_size[1], max(0, self.focussed_entity.location.y - self.display_size[1] / 2)) surface.blit( self.background, (0, 0), (display_x, display_y, self.display_size[0], self.display_size[1])) for entity in self.entities.itervalues(): if Vector2.get_distance(self.focussed_entity.location, entity.location) <= self.maximum_expansion: entity.render(surface, (display_x, display_y)) if self.minimapVisible: minimapSize = (200, 100) minimapOffset = (10, 490) pygame.draw.rect(surface, (0, 0, 0), pygame.Rect(minimapOffset, minimapSize)) pygame.draw.rect( surface, (255, 255, 255), pygame.Rect((minimapOffset[0] - 1, minimapOffset[1] - 1), (minimapSize[0] + 2, minimapSize[1] + 2)), 1) for entity in self.active_entities.itervalues(): # render entity point on minimap x = minimapOffset[0] + int( (minimapSize[0] * entity.location.x) / self.dimension[0]) y = minimapOffset[1] + int( (minimapSize[1] * entity.location.y) / self.dimension[1]) if entity.name == 'player' and not entity.vehicle: color = (0, 0, 255) pygame.draw.circle(surface, color, (x, y), 3) elif entity.name == 'cat': color = entity.hungerColour pygame.draw.rect(surface, color, pygame.Rect((x, y), (2, 2))) elif entity.name == 'car': color = (200, 200, 200) pygame.draw.circle(surface, color, (x, y), 3)
def render(self, surface): display_x = min( self.dimension[0] - self.display_size[0], max(0, self.focussed_entity.location.x - self.display_size[0] / 2) ) display_y = min( self.dimension[1] - self.display_size[1], max(0, self.focussed_entity.location.y - self.display_size[1] / 2) ) surface.blit(self.background, (0, 0), (display_x, display_y, self.display_size[0], self.display_size[1])) for entity in self.entities.itervalues(): if Vector2.get_distance(self.focussed_entity.location, entity.location) <= self.maximum_expansion: entity.render(surface, (display_x, display_y)) if self.minimapVisible: minimapSize = (200, 100) minimapOffset = (10, 490) pygame.draw.rect(surface, (0, 0, 0), pygame.Rect(minimapOffset, minimapSize)) pygame.draw.rect( surface, (255, 255, 255), pygame.Rect((minimapOffset[0] - 1, minimapOffset[1] - 1), (minimapSize[0] + 2, minimapSize[1] + 2)), 1, ) for entity in self.active_entities.itervalues(): # render entity point on minimap x = minimapOffset[0] + int((minimapSize[0] * entity.location.x) / self.dimension[0]) y = minimapOffset[1] + int((minimapSize[1] * entity.location.y) / self.dimension[1]) if entity.name == "player" and not entity.vehicle: color = (0, 0, 255) pygame.draw.circle(surface, color, (x, y), 3) elif entity.name == "cat": color = entity.hungerColour pygame.draw.rect(surface, color, pygame.Rect((x, y), (2, 2))) elif entity.name == "car": color = (200, 200, 200) pygame.draw.circle(surface, color, (x, y), 3)
def main(agent, packet): if kick_ball.ball_prediction != 0: ball_location = kick_ball.ball_prediction.pos else: ball_location = Vector3(packet.game_ball.physics.location) kick_ball.prediction_timer = -1 ball = agent.ball car = agent.car car_location = car.pos.to_2d() car_to_ball_vector = Vector3(ball.pos) - Vector3(car.pos) car_to_ball_magnitude = car_to_ball_vector.magnitude() car_to_ball_magnitude_2d = car_to_ball_vector.to_2d().magnitude() car_direction = get_car_facing_vector(car) goal = get_opponents_goal(agent) go_to = car_location plus = 0 # ball prediction kick_ball.prediction_timer -= 1 / 60 if kick_ball.prediction_timer < -0.1: agent.car_status = 'none' kick_ball.in_position = False time = kick_ball.predict_when_ball_hit(agent) kick_ball.prediction_timer = time kick_ball.ball_prediction = ball.prediction[int(time * 60)] kick_ball.correction_timer = kick_ball.when_ball_hit_correction(agent) kick_ball.ball_prediction = ball.prediction[int( cap_num(kick_ball.prediction_timer * 60, 0, 1e9))] # a few variables ball_location = kick_ball.ball_prediction.pos car_to_ball_vector = Vector3(ball.pos) - Vector3(car.pos) car_to_ball_magnitude = car_to_ball_vector.magnitude() car_to_ball_magnitude_2d = car_to_ball_vector.to_2d().magnitude() ideal_car_location = kick_ball.get_ideal_car_location( agent, packet, ball_location) # draw line from ball to ideal car location Vector3(ball_location).draw_to(agent, ideal_car_location, [0, 100, 0]) # 3D correction timer vs actual prediction agent.renderer.draw_string_3d( car.pos.change('z', 100).get_array(), 2, 2, 'corr: ' + str( round(kick_ball.correction_timer, 2) - round(kick_ball.prediction_timer, 2)), white(agent)) # draw place where car will hit ball agent.renderer.draw_string_3d(ball_location.get_array(), 2, 2, ball_location.string(), white(agent)) ideal_car_to_ball_angle = (ball_location - ideal_car_location).to_2d().get_angle() car_to_ball_to_angle = (ball_location - car.pos).to_2d().get_angle() difference_angle_car_ideal = difference_angles(ideal_car_to_ball_angle, car_to_ball_to_angle) if difference_angle_car_ideal > kick_ball.get_angle_for_goal( agent, packet, ball_location) * 2: kick_ball.in_position = False car_inline_bool = abs( difference_angle_car_ideal) < kick_ball.get_angle_for_goal( agent, packet, ball_location) * 2 # If car not close enough to ideal and car not close to idealLine. Go there if Vector2( ideal_car_location.x - car_location.x, ideal_car_location.y - car_location.y).magnitude( ) > 1000 and not car_inline_bool and not kick_ball.in_position: go_to = ideal_car_location #plus = -difference_angle_car_ideal/(car_to_ball_magnitude/200) # double jump if on ground and straight and going good direction and far away far_away_enough = Vector2( car_location.x - ideal_car_location.x, car_location.y - ideal_car_location.y).magnitude() > 1000 # draw ideal location a = [ideal_car_location.x, ideal_car_location.y, 17] agent.renderer.draw_rect_3d(a, 40, 40, True, own_color(agent, packet)) # Else head towards the ball else: kick_ball.in_position = True # predict ball location and go there go_to = ball_location plus = -difference_angle_car_ideal / (car_to_ball_magnitude / 200) #if car_to_ball_magnitude_2d > 2000: plus = -difference_angle_car_ideal/40 # boost too_slow = kick_ball.correction_timer > kick_ball.prediction_timer + 0.01 if car.pos.z < 17.1 and car_inline_bool and too_slow: agent.controller_state.boost = True agent.renderer.draw_line_3d( car.pos.get_array(), ball_location.get_array(), agent.renderer.create_color(255, 255, 255, 255)) agent.renderer.draw_line_3d(ideal_car_location.get_array(), ball_location.get_array(), own_color(agent, packet)) draw_text(agent, 'LR. corr: ' + str(plus), 110) aim_to(agent, go_to, plus) # If realy close to ball and good direction Jump if car_to_ball_magnitude < 200 and abs( car_direction.correction_to( Vector2(ball_location.x, ball_location.y) - car_location)) < 0.1: double_jump(agent) agent.controller_state.throttle = 1 if kick_ball.correction_timer + 0.05 < kick_ball.prediction_timer: agent.controller_state.throttle = 1 - ( kick_ball.prediction_timer - kick_ball.correction_timer - kick_ball.prediction_timer) / 5 # if me hit the ball stop kicking the ball if packet.game_ball.latest_touch.player_name == car.name and packet.game_info.seconds_elapsed - packet.game_ball.latest_touch.time_seconds < 1: agent.car_status = 'none' kick_ball.ball_prediction = 0 return agent
def dropFood(self): if self.foodAmount <= 0 or self.vehicle: return None else: self.foodAmount -= 1 return Food(self.location - Vector2(10,0))
def runLevel(screen, level_number, cat_number): soundChannel = pygame.mixer.Channel(0) finishSound = pygame.mixer.Sound('../sounds/finish.ogg') builder = LevelBuilder() level = builder.buildLevelFromFile('../levels/level%s.txt' % level_number) world = World(SCREEN_SIZE, level) car = Car(Vector2(100, 100)) player = Player(Vector2(100, 180)) world.add_entity(player) world.add_entity(car) world.setFocus(player) worldobserver = WorldObserver(world) clock = pygame.time.Clock() for i in range(cat_number): cat = Cat( Vector2(randint(0, world.dimension[0]), randint(0, world.dimension[1])), world) world.add_entity(cat) countdown_to_next_level = LEVEL_INTERMEDIATE_TIME while True: for event in pygame.event.get(): if event.type == QUIT: exit() if event.type == KEYDOWN: if event.key == K_LEFT: player.move(LEFT) elif event.key == K_RIGHT: player.move(RIGHT) elif event.key == K_UP: player.move(UP) elif event.key == K_DOWN: player.move(DOWN) elif event.key == K_SPACE: food = player.dropFood() if food is not None: world.add_entity(food) elif event.key == K_c: player.switchVehicle(car) world.setFocus(player.vehicle or player) elif event.key == K_m: world.toggleMinimap() time_passed = clock.tick(30) world.process(time_passed) world.render(screen) worldobserver.writeMessages(screen) if worldobserver.levelFinished: if countdown_to_next_level == LEVEL_INTERMEDIATE_TIME: soundChannel.play(finishSound) countdown_to_next_level -= 2 if countdown_to_next_level <= 0: return for r in range(countdown_to_next_level + 1, LEVEL_INTERMEDIATE_TIME, 8): pygame.draw.circle(screen, (0, 0, 0), (SCREEN_SIZE[0] / 2, SCREEN_SIZE[1] / 2), r, 1) pygame.display.update()
def findRandomTarget(self): self.cat.destination = self.cat.location + Vector2(randint(-200, 200), randint(-200, 200))
def entry_actions(self): self.cat.set_image(self.cat.roamingImage, 4) self.cat.speed = 100 self.cat.animationSpeed = 0.1 self.cat.destination = self.cat.pot.location - Vector2(30, 0)
def check_conditions(self): if self.cat.pot is not None and Vector2.get_distance(self.cat.location, self.cat.destination) < 10: return "eating" return None
from vectors import (Vector2, Vector3) class Line: def __init__(self, start, end): if not (isinstance(start, (Vector2, Vector3)) and isinstance( end, (Vector2, Vector3)) and type(start) == type(end)): raise TypeError( "Both the start and end points of the line need to be a Vector2 or Vector3 (Start and end need to match type)" ) self.start = start self.end = end def length(self): return (self.end - self.start).magnitude() if __name__ == "__main__": print(Line(Vector2(0, 0), Vector2(3, 4)).length())