コード例 #1
0
    def handle_message(self, message):
        self.polling = False

        bodies = message.split("#")
        for body_info in bodies:
            seperator = body_info.find(":")
            body_type = body_info[:seperator]
            body_values = body_info[seperator + 1:].split(",")

            if body_type == "solar-body":
                planet = KnownPlanet(
                    body_values[0], body_values[1], int(body_values[2]),
                    Vector(float(body_values[3]), float(body_values[4]),
                           float(body_values[5])), float(body_values[6]),
                    float(body_values[7]))

                if planet.name in self.planets.keys():
                    current = self.planets[planet.name]
                    current.update(planet.pos)
                else:
                    self.planets[planet.name] = planet
            elif body_type == "general-body":
                body = KnownBody(
                    body_values[0], int(body_values[1]),
                    Vector(float(body_values[2]), float(body_values[3]),
                           float(body_values[4])), float(body_values[5]),
                    float(body_values[6]))

                if body.uid in self.general.keys():
                    current = self.general[body.uid]
                    current.update(body.pos)
                else:
                    self.general[body.uid] = body
            else:
                pass
コード例 #2
0
	def load(self, blob):
		entities.Entity.load(self, blob)
		self.pos = Vector.from_list(blob['physical.pos'])
		self.vel = Vector.from_list(blob['physical.vel'])
		self.rot = Quaternion.from_list(blob['physical.rot'])
		self.rotvel = Quaternion.from_list(blob['physical.rotvel'])
		self.radius = blob['physical.radius']
		self.mass = blob['physical.mass']
コード例 #3
0
	def __init__(self, category_uid, instance_uid, sim):
		entities.Entity.__init__(self, category_uid, instance_uid, sim)
		
		self.pos = Vector(0.0, 0.0, 0.0)
		self.vel = Vector(0.0, 0.0, 0.0)
		self.rot = Quaternion.from_angle_and_axis(0.0, Vector(0, 0, 1))
		self.rotvel = Quaternion.from_angle_and_axis(0.0, Vector(0.0, 0.0, 1.0))
		self.radius = 1.0
		self.mass = 1.0
コード例 #4
0
ファイル: game.py プロジェクト: GalHorowitz/NEATRacingGame
    def __init__(self, num_cars, start_pos, walls, checkpoints):
        self.camera_position = Vector(0, 0)

        self.walls = walls
        self.checkpoints = [Vector.from_tuple(x) for x in checkpoints]

        start_pos_x, start_pos_y = start_pos
        self.cars = [Car(start_pos_x, start_pos_y) for _ in range(num_cars)]
        self.reached_checkpoint = [0] * num_cars
        self.dead = [False] * num_cars

        self.tracked_car = 0
コード例 #5
0
class PhysicalEntity(entities.Entity):
	
	def __init__(self, category_uid, instance_uid, sim):
		entities.Entity.__init__(self, category_uid, instance_uid, sim)
		
		self.pos = Vector(0.0, 0.0, 0.0)
		self.vel = Vector(0.0, 0.0, 0.0)
		self.rot = Quaternion.from_angle_and_axis(0.0, Vector(0, 0, 1))
		self.rotvel = Quaternion.from_angle_and_axis(0.0, Vector(0.0, 0.0, 1.0))
		self.radius = 1.0
		self.mass = 1.0
	
	def should_think(self):
		return True
	
	def think(self, dt):
		self.pos = self.pos + (self.vel * dt)
		self.rot = self.rot * (self.rotvel ** dt)
	
	def accelerate(self, force, dt):
		acceleration = (force / self.mass) * dt
		self.vel = self.vel + acceleration
	
	def apply_moment(self, angular_acceleration, dt):
		#print "angular e:", angular_acceleration.as_tuple()
		q = Quaternion.from_euler_rotation(angular_acceleration)
		#print "angular q:", q.as_tuple()
		self.rotvel = self.rotvel * q ** 2
		#print "rotvel  q:", self.rotvel.as_tuple()
		#print "rotvel  e:", self.rotvel.to_euler_angle().as_tuple()
	
	def load(self, blob):
		entities.Entity.load(self, blob)
		self.pos = Vector.from_list(blob['physical.pos'])
		self.vel = Vector.from_list(blob['physical.vel'])
		self.rot = Quaternion.from_list(blob['physical.rot'])
		self.rotvel = Quaternion.from_list(blob['physical.rotvel'])
		self.radius = blob['physical.radius']
		self.mass = blob['physical.mass']
	
	def save(self):
		blob = entities.Entity.save(self)
		blob['physical.pos'] = self.pos.as_list()
		blob['physical.vel'] = self.vel.as_list()
		blob['physical.rot'] = self.rot.as_list()
		blob['physical.rotvel'] = self.rotvel.as_list()
		blob['physical.radius'] = self.radius
		blob['physical.mass'] = self.mass
		return blob
コード例 #6
0
def ray_segment_intersection(ray, segment):
    """
	Finds the point of intersection between a ray and a segment, or returns None if such a point
	does not exist.

	`ray` must be of type `Ray`. A `segment` is a tuple of two `(x, y)` points that define the start
	and end	of the segment accordingly.
	"""

    # Based on Wikipedia's `Line–line intersection`
    x1 = ray.start.x
    y1 = ray.start.y
    ray_point = ray.start + ray.direction
    x2 = ray_point.x
    y2 = ray_point.y
    x3, y3 = segment[0]
    x4, y4 = segment[1]

    t_num = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4))
    t_den = ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))
    u_num = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3))
    u_den = ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))

    # The condition is essentially 0 <= u <= 1 and 0 <= t but we check it this way to avoid having
    # to actually do the division unless we must.
    if u_den != 0 and (u_num*u_den) >= 0 and abs(u_num) <= abs(u_den) \
     and t_den != 0.0 and (t_num*t_den) >= 0:
        # Intersection!

        u = u_num / u_den
        return Vector(x3 + u * (x4 - x3), y3 + u * (y4 - y3))
    else:
        return None
コード例 #7
0
ファイル: game.py プロジェクト: GalHorowitz/NEATRacingGame
    def get_screen_mapping(self, screen):
        """
		Calculates a vector that when added to a point in game-space maps it to screen-space
		"""

        screen_rect = screen.get_rect()
        screen_middle = Vector(screen_rect.width, screen_rect.height) / 2

        return screen_middle - self.camera_position
コード例 #8
0
ファイル: car.py プロジェクト: GalHorowitz/NEATRacingGame
    def __init__(self, initial_x, initial_y):
        """
		Constructs a car with the given initial position: `(initial_x, initial_y)`
		"""

        self.position = Vector(initial_x, initial_y)
        self.direction = 0  # In radians

        self.velocity = 0
        self.acceleration = 0
コード例 #9
0
ファイル: car.py プロジェクト: GalHorowitz/NEATRacingGame
    def get_sight_rays(self):
        """
		Returns a list of Ray objects representing the sensors of the car
		"""

        rays = []
        for ray_angle in (-RAY_ANGLE, 0, RAY_ANGLE):
            start_pos = self.position
            direction = Vector.unit_from_angle(self.direction + ray_angle)
            rays.append(Ray(start_pos, direction))
        return rays
コード例 #10
0
ファイル: car.py プロジェクト: GalHorowitz/NEATRacingGame
    def get_bounding_box(self):
        """
		Returns a list represention of the 4 points that define the car's bounding box.

		This method is expensive, if possible (i.e. the car's position and direction doesn't change)
		the result should be cached.
		"""

        half_width = CAR_BOUNDING_BOX_WIDTH / 2
        half_height = CAR_BOUDNING_BOX_HEIGHT / 2
        car_rect = [
            (Vector(half_width, half_height).rotated(self.direction) +
             self.position).as_tuple(),
            (Vector(half_width, -half_height).rotated(self.direction) +
             self.position).as_tuple(),
            (Vector(-half_width, -half_height).rotated(self.direction) +
             self.position).as_tuple(),
            (Vector(-half_width, half_height).rotated(self.direction) +
             self.position).as_tuple()
        ]
        return car_rect
コード例 #11
0
ファイル: car.py プロジェクト: GalHorowitz/NEATRacingGame
    def draw(self, screen, screen_mapping):
        """
		Draws the car on `screen`, with the position adjusted based on the provided `screen_mapping`
		"""

        rotated_sprite = pygame.transform.rotate(
            Car.get_sprite(), self.direction * 180 / math.pi)

        sprite_rect = rotated_sprite.get_rect()
        sprite_middle = Vector(sprite_rect.width, sprite_rect.height) / 2
        sprite_position = self.position - sprite_middle
        screen_position = sprite_position + screen_mapping
        screen.blit(rotated_sprite, screen_position.as_tuple())
コード例 #12
0
    def __init__(self, host_computer):
        computer.Program.__init__(self, host_computer)

        global MyProgram

        self.state = MyProgram.STATE_STOP_THRUSTERS
        self.timer_end = None
        self.stat_counter = 0.0

        self.rotation = Vector(0, 0, 0)

        self.rot_period = 1.0

        self.set_timer(self.rot_period)
        self.computer.write('maneuver', 'thrust', ('rot-rcs-ryl', 1E2))
        self.computer.write('maneuver', 'thrust', ('rot-rcs-lyl', 1E2))
コード例 #13
0
ファイル: car.py プロジェクト: GalHorowitz/NEATRacingGame
    def physics_update(self, delta_time):
        """
		Updates the car's position and velocity based on its acceleration, given that `delta_time`
		seconds passed since the last `physics_update` call.
		"""

        self.position += delta_time * self.velocity * Vector.unit_from_angle(
            self.direction)
        self.velocity += delta_time * self.acceleration

        # Deal with floating-point instability
        if abs(self.velocity) < 0.9:
            self.velocity = 0

        if math.fabs(self.velocity) > MAX_VELOCITY:
            self.velocity *= MAX_VELOCITY / (math.fabs(self.velocity))
コード例 #14
0
ファイル: game.py プロジェクト: GalHorowitz/NEATRacingGame
    def raycast_against_walls(self, ray, max_ray_length=0):
        # Raycasting against every wall (and therefore against every rect segment) is way too slow
        # with regards to the amount of ray-casts we want to perform every frame. As such, we must
        # prune away walls that we know we can't hit anyway, i.e. those that are too far away to
        # hit. We can only use that optimization if we know the `max_ray_length`.

        candidate_walls = []
        if max_ray_length == 0:
            candidate_walls = self.walls
        else:
            for wall in self.walls:
                # For each wall, we find the minimum distance to the ray start from the vertices
                min_sqr_dist_lower_bound = None
                for vert in wall.verts:
                    sqr_vert_dist = (Vector.from_tuple(vert) -
                                     ray.start).sqr_magnitude()
                    sqr_dist_lower_bound = sqr_vert_dist - wall.sqr_half_side
                    if min_sqr_dist_lower_bound is None or sqr_dist_lower_bound < min_sqr_dist_lower_bound:
                        min_sqr_dist_lower_bound = sqr_dist_lower_bound

                # We then only consider walls that are below the threshold as candidates for hit detection
                if min_sqr_dist_lower_bound < max_ray_length**2:
                    candidate_walls.append(wall)

        # We go through each candidate wall, and calculate if an intersection exists between and the
        # wall and ray, if it does, we update the hit point if it is closer to the ray start
        closest_point = None
        shortest_distance = None
        for wall in candidate_walls:
            inter_point, ray_dist = ray_rect_intersection(ray, wall.verts)
            if ray_dist is not None:
                if shortest_distance is None or ray_dist < shortest_distance:
                    closest_point = inter_point
                    shortest_distance = ray_dist

        return (closest_point, shortest_distance)
コード例 #15
0
    def __init__(self, host, port):
        asyncore.dispatcher_with_send.__init__(self)
        self.rx = ""

        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((host, port))

        self.connected = False

        self.zoom = 1E-10
        self.camera = Vector(0, 0, 0)

        self.running = True
        self.polling = False

        self.network_thread = None

        self.verbose = False

        self.bodies = []
        self.planets = {}
        self.general = {}
        self.transmissions = []

        self.colours = {
            'Sol': (255, 255, 0),
            'Mercury': (100, 50, 50),
            'Venus': (200, 200, 50),
            'Earth': (100, 100, 255),
            'Earth.Moon': (200, 200, 200),
            'Mars': (200, 0, 0),
            'Jupiter': (150, 0, 50),
            'Saturn': (200, 200, 50),
            'Uranus': (100, 200, 255),
            'Neptune': (50, 100, 255)
        }
コード例 #16
0
ファイル: observatory.py プロジェクト: omaskery/yellow-lama
def circle_on_screen(screen, pos, radius):
	screen_size = screen.get_size()
	centre = Vector(screen_size[0] / 2, screen_size[1] / 2, 0)
	distance2 = (pos - centre).magnitude2()
	return ((distance2 + radius ** 2) < (max(centre.as_tuple()) ** 2))
コード例 #17
0
def main():
    state_file = "sim.state"
    load_state = False
    save_state = True

    print "[space-sim] starting"
    sim = simulation.Simulation()
    server = Networking(8000, sim)

    signal_handler = SignalHandler(sim)

    sim.register_entity_category('spaceship', ship_entity.ShipEntity)
    sim.register_entity_category('solar-body', solar_entities.SolarBodyEntity)

    if load_state:
        print "[space-sim] loading state"
        sim.load(state_file)
    else:
        print "[space-sim] generating state"

        solar_bodies = [
            {
                'name': 'Sol',
                'pos': Vector(0, 0, 0),
                'vel': Vector(0, 0, 0),
                'mass': 1.9891E30,
                'radius': 695500E3
            },
            #{
            #	'name': 'BlackHole',
            #	'pos': Vector(-2.4E20, 0, 0),
            #	'vel': Vector(0, 0, 0),
            #	'mass': 7.9564E34,
            #	'radius': 6.7453303E12
            #},
            {
                'name': 'Mercury',
                'pos': Vector(5.791000e+10, 0, 0),
                'vel': Vector(0, -47.36E3, 0),
                'mass': 328.5E21,
                'radius': 2440E3
            },
            {
                'name': 'Venus',
                'pos': Vector(1.082000e+11, 0, 0),
                'vel': Vector(0, -35.02E3, 0),
                'mass': 4.867E24,
                'radius': 6052E3
            },
            {
                'name': 'Earth',
                'pos': Vector(149.59787E9, 0, 0),
                'vel': Vector(0, -29.77E3, 0),
                'mass': 5.97219E24,
                'radius': 6378.1E3
            },
            {
                'name': 'Earth.Moon',
                'pos': Vector(149.59787E9 + 385E6, 0, 0),
                'vel': Vector(0, -29.77E3 + -1020, 0),
                'mass': 7.34767309E22,
                'radius': 1737.4E3
            },
            {
                'name': 'Mars',
                'pos': Vector(2.279000e+11, 0, 0),
                'vel': Vector(0, -24.07E3, 0),
                'mass': 6.4174E23,
                'radius': 3389.5E3
            },
            {
                'name': 'Jupiter',
                'pos': Vector(7.785000e+11, 0, 0),
                'vel': Vector(0, -13.06E3, 0),
                'mass': 1.898E27,
                'radius': 69911E3
            },
            {
                'name': 'Saturn',
                'pos': Vector(1.433000e+12, 0, 0),
                'vel': Vector(0, -9.68E3, 0),
                'mass': 568.3E24,
                'radius': 58232E3
            },
            {
                'name': 'Uranus',
                'pos': Vector(2.877000e+12, 0, 0),
                'vel': Vector(0, -6.8E3, 0),
                'mass': 86.81E24,
                'radius': 25362E3
            },
            {
                'name': 'Neptune',
                'pos': Vector(4.503000e+12, 0, 0),
                'vel': Vector(0, -5.43E3, 0),
                'mass': 102.4E24,
                'radius': 24622E3
            }
        ]

        for body in solar_bodies:
            planet = solar_entities.SolarBodyEntity('solar-body',
                                                    sim.allocate_uid(), sim)
            planet.name = body['name']
            planet.pos = body['pos']
            planet.vel = body['vel']
            planet.mass = body['mass']
            planet.radius = body['radius']
            sim.add_entity(planet)

        ship = ship_entity.ShipEntity('spaceship', sim.allocate_uid(), sim)

        ship.pos = Vector(149.59787E9 + 6378.1E3 + 370E3, 0,
                          0)  # around the earth
        ship.vel.y = -29.77E3 + -7.7E3  # Hopefully in orbit
        ship.radius = 8  # metres
        ship.mass = 2E3  # kg

        sim.add_entity(ship)

    print "[space-sim] hooking SIGINT"
    signal.signal(signal.SIGINT, signal_handler.handle)

    print "[space-sim] starting networking"
    server.start()

    print "[space-sim] entering simulation loop"
    while sim.running:
        sim.update()

    if save_state:
        print "[space-sim] saving state"
        sim.save(state_file)

    print "[space-sim] shutting down"
コード例 #18
0
def circle_on_screen(screen, pos, radius):
    screen_size = screen.get_size()
    centre = Vector(screen_size[0] / 2, screen_size[1] / 2, 0)
    distance2 = (pos - centre).magnitude2()
    return ((distance2 + radius**2) < (max(centre.as_tuple())**2))
コード例 #19
0
def main():
    pygame.init()
    width, height = (1024, 768)
    screen = pygame.display.set_mode((width, height))
    running = True

    observatory = Observatory('localhost', 8000)
    observatory.start_networking()

    focus = None
    focus_name = 'Earth'

    if focus_name == 'Sol':
        observatory.zoom = 5E-11
    elif focus_name == 'Earth':
        observatory.zoom = 1E-6

    clicked = None

    poll_rate = 20
    next_poll = now_plus(1.0 / poll_rate)

    zoom_rate = 1.05
    large_zoom_rate = zoom_rate * 10

    while observatory.running:
        if now(
        ) >= next_poll and observatory.connected and not observatory.polling:
            observatory.poll()
            next_poll += datetime.timedelta(seconds=1.0 / poll_rate)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                observatory.running = False
                break
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    clicked = event.pos
                elif event.button == 4:
                    observatory.zoom *= zoom_rate
                elif event.button == 5:
                    observatory.zoom /= zoom_rate
            elif event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    clicked = None
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_e:
                    observatory.zoom *= large_zoom_rate
                elif event.key == pygame.K_q:
                    observatory.zoom /= large_zoom_rate

        width_metres = width / observatory.zoom
        height_metres = height / observatory.zoom

        if focus_name in observatory.planets.keys():
            focus = observatory.planets[focus_name]

        if focus is not None:
            px, py, pz = focus.pos.as_tuple()
            offset_x, offset_y = width_metres / 2, height_metres / 2
            if clicked is not None:
                cx, cy = clicked
                mx, my = pygame.mouse.get_pos()
                offset_x -= cx - mx
                offset_y -= cy - my
            observatory.camera = Vector(px - offset_x, py - offset_y, 0)

        observatory.draw(screen)

    observatory.close()
    pygame.quit()