Exemple #1
0
    def show(self):
        if self.window is None:
            raise NoObjectError("World is attached to any Window.")
        self.systems["Entity"].show(self.window.screen)
        self.systems["UI"].show(self.window.screen)
        if self.window.debug:
            draw_options = pygame_util.DrawOptions(self.window.screen)

            self.space.debug_draw(draw_options)
            self.systems["Entity"].show_debug(self.window.screen)
            self.systems["UI"].show_debug(self.window.screen)
Exemple #2
0
 def __init__(self, space):
     init()
     font.init()
     self.font = font.SysFont('Comic Sans MS', 24)
     self.font2 = font.SysFont('arial', 14)
     self.screen = display.set_mode(flags=FULLSCREEN)
     self.draw_options = pygame_util.DrawOptions(self.screen)
     self.StaticObjects(space)
     self.updateCounter = 0
     self.button1 = self.font2.render("Neural Network", False, (0, 0, 0))
     self.button2 = self.font2.render("Fuzzy Logic", False, (0, 0, 0))
     self.repeats = 2
Exemple #3
0
def data_simulation(
        data,
        record=False,
        record_dir=None):  # format data here so it's (num_steps, No, 2)
    """
	Visualizes a sequence of game states input as data as a simulation.
	"""
    pygame.init()
    screen = pygame.display.set_mode(
        (ceil(data[0, 7, 0]) * 100, ceil(data[0, 8, 1]) * 100))
    clock = pygame.time.Clock()
    space = pymunk.Space()
    draw_options = pygame_util.DrawOptions(screen)

    curr_shapes = []
    for j, ts in enumerate(data):
        for s in curr_shapes:
            space.remove(s, s.body)
        curr_shapes.clear()
        for i in range(len(ts) - 4):  # only need to visualise circles
            obj = ts[i]
            body = pymunk.Body()
            body.position = obj[0] * 100, obj[1] * 100
            shape = pymunk.Circle(body, 0.15 * 100)
            space.add(shape, body)
            curr_shapes.append(shape)
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                sys.exit(0)

        if record:
            pygame.image.save(screen, record_dir + str(j) + ".jpeg")

        screen.fill((255, 255, 255))
        space.debug_draw(draw_options)
        pygame.display.flip()
        pygame.display.set_caption("fps: " + str(clock.get_fps()))
        space.step(T_DIFF)
        clock.tick(1 / T_DIFF)

    pygame.quit()
    def update_screen(self):
        """
        If the screen is set, updates the screen and displays the environment.
        """

        if self._screen is not None:

            if self._debug:
                self._screen.fill((0, 0, 0))
                options = pygame_util.DrawOptions(self._screen)
                self.playground.space.debug_draw(options)

            else:
                self._generate_surface_environment(with_interactions=True)
                self._screen.blit(self._surface_buffer, (0, 0), None)

            pygame.display.flip()

        else:
            raise ValueError('No screen to update')
    def __init__(self, do_render, sparse, max_motor_force):
        self.do_render = do_render
        self.sparse = sparse
        self.max_motor_force = max_motor_force

        if self.do_render:
            pygame.init()
            self.screen = pygame.display.set_mode((ENV_SIZE, ENV_SIZE))
            self.draw_options = pygame_util.DrawOptions(self.screen)
            self.clock = pygame.time.Clock()
        self.motors = []
        self.segment_bodies = []

        self.space = Space()
        self.space.iterations = 20

        no_collision = self.space.add_collision_handler(NO_COLLISION_TYPE, NO_COLLISION_TYPE)
        no_collision.begin = lambda a, b, c: False
        ghost_collision = self.space.add_wildcard_collision_handler(GHOST_TYPE)
        ghost_collision.begin = lambda a, b, c: False
Exemple #6
0
    def initial_state(self):
        """
		Sets up the initial state of the magnetic environment
		"""
        if self.vis:
            pygame.init()
            self.screen = pygame.display.set_mode(
                (self.max_x * 100, self.max_y * 100))  # 100pixels/meter
            self.clock = pygame.time.Clock()
            self.space = pymunk.Space()
            self.draw_options = pygame_util.DrawOptions(self.screen)

        obj_positions = []
        for i in range(self.No):  # create No magnetic poles
            yes = True
            while yes:  # loops until we get an initialization of objects with no collisions
                r = 0.15  # + np.random.rand() * 0.1 # 0.1-0.2m
                x = r + np.random.rand() * (self.max_x - 2 * r)
                y = r + np.random.rand() * (self.max_y - 2 * r)
                collision = False
                for o in obj_positions:
                    if 2 * r >= np.sqrt((x - o[0])**2 + (y - o[1])**2):
                        collision = True
                        continue
                if not collision:
                    yes = False
                    obj_positions.append((x, y, r))

            m = 1 / (0.75 + np.random.rand() * 0.5
                     )  # 0.75-1.25kg - stored as m^-1
            v_x = -5 + np.random.rand() * 10  # -5-5m/s
            v_y = -5 + np.random.rand() * 10  # -5-5m/s
            q = 7.5 * 1e3
            obj = CircleMagnet(x, y, m, q, r, v_x, v_y)

            if self.vis:
                obj.shape = self.add_obj(obj)
                self.space.add(obj.shape, obj.shape.body)

            self.data[0].append(obj)
        self.data[0].extend(self.walls)
Exemple #7
0
    def __init__(self, params, seed, fidelity=10, debug_options=None):
        """Constructor

        @param params: dict of parameters that define how symbols behave and are rendered. See the
        detailed description for this class for supported parameters.
        @param seed: Seed for the RNG (int)
        @param fidelity: How many iterations to run in the physics simulator per step (int)
        @param debug_options: dict with options for visual debugging, or None if visual debugging
                              should be turned off. The following key-value pairs are supported:
                              - show_pymunk_debug, bool: Whether to use PyMunk's default drawing
                                function
                              - show_bounding_poly, bool: Whether to render PyMunk surface outlines
                              - show_frame_number, bool: Whether to show the index of the frame
                              - frame_number_font_size, int: Size of the frame index font
                              - frame_rate, int: Frame rate of the debug visualization

        """

        self.params = merge_dicts(MovingSymbolsEnvironment.DEFAULT_PARAMS, params)
        self.fidelity = fidelity
        self.debug_options = None if debug_options is None \
            else merge_dicts(MovingSymbolsEnvironment.DEFAULT_DEBUG_OPTIONS, debug_options)
        self.video_size = self.params['video_size']

        self._subscribers = []
        self._init_messages = []
        self._step_called = False

        self._add_init_message(dict(
            step=-1,
            type='params',
            meta=dict(self.params)
        ))

        # Convert translation/rotation/scale period/speed limits to lists
        if isinstance(self.params['scale_period_limits'], tuple):
            self.params['scale_period_limits'] = [self.params['scale_period_limits']]
        if isinstance(self.params['rotation_speed_limits'], tuple):
            self.params['rotation_speed_limits'] = [self.params['rotation_speed_limits']]
        if isinstance(self.params['position_speed_limits'], tuple):
            self.params['position_speed_limits'] = [self.params['position_speed_limits']]

        self.cur_rng_seed = seed
        np.random.seed(self.cur_rng_seed)

        if self.debug_options is not None:
            self._pg_screen = pg.display.set_mode(self.video_size)
            self._pg_draw_options = pmu.DrawOptions(self._pg_screen)
            pg.font.init()
            font_size = self.debug_options['frame_number_font_size']
            self._pg_font = pg.font.SysFont(pg.font.get_default_font(), font_size)
            self._pg_clock = pg.time.Clock()
            self._add_init_message(dict(
                step=-1,
                type='debug_options',
                meta=dict(debug_options)
            ))

        self._space = pm.Space()
        self.symbols = []
        image_loader = ImageLoader(os.path.join(self.params['data_dir'], self.params['split']),
                                   'tight_crop')
        if self.params['background_data_dir'] is None or self.params['background_labels'] is None:
            bg_image_loader = None
        else:
            bg_image_loader = ImageLoader(os.path.join(self.params['background_data_dir'],
                                                       self.params['split']))

        for id in xrange(self.params['num_symbols']):
            label = self.params['symbol_labels'][
                np.random.randint(len(self.params['symbol_labels']))
            ]
            image, image_path = image_loader.get_image(label)

            # Define the scale function
            period_limits_index = np.random.choice(len(self.params['scale_period_limits']))
            period = np.random.uniform(
                *tuple(self.params['scale_period_limits'][period_limits_index])
            )
            amplitude = (self.params['scale_limits'][1] - self.params['scale_limits'][0]) / 2.
            x_offset = np.random.uniform(period)
            # Override offset if digits should not start at random scale
            if not self.params['rescale_at_start']:
                x_offset = 0
            # Randomly shift offset (i.e. symbol can either grow or shrink at start)
            x_offset += (period/2 if np.random.choice([True, False]) else 0)
            y_offset = (self.params['scale_limits'][1] + self.params['scale_limits'][0]) / 2.
            if self.params['scale_function_type'] == 'sine':
                scale_fn = create_sine_fn(period, amplitude, x_offset, y_offset)
            elif self.params['scale_function_type'] == 'triangle':
                scale_fn = create_triangle_fn(period, amplitude, x_offset, y_offset)
            elif self.params['scale_function_type'] == 'constant':
                scale = np.random.uniform(*self.params['scale_limits'])
                scale_fn = lambda x: scale
            else:
                raise ValueError('scale_function_type "%s" is unsupported'
                                 % self.params['scale_function_type'])

            symbol = Symbol(id, label, image, image_path, scale_fn)

            # Set the symbol's initial rotation and scale
            symbol.set_scale(0)
            start_angle = np.random.uniform(2 * math.pi)
            if self.params['rotate_at_start']:
                symbol.body.angle = start_angle

            # Compute the minimum possible margin between the symbol's center and the wall
            w_half = image.size[0] / 2.
            h_half = image.size[1] / 2.
            margin = math.sqrt(w_half ** 2 + h_half ** 2) * self.params['scale_limits'][1]
            # Set the symbol position at least one margin's distance from any wall
            x_limits = (margin+1, self.video_size[0] - margin - 1)
            y_limits = (margin+1, self.video_size[1] - margin - 1)
            symbol.body.position = (np.random.uniform(*x_limits), np.random.uniform(*y_limits))
            # If symbols will interact with each other, make sure they don't overlap initially
            while self.params['interacting_symbols'] and len(self._space.shape_query(symbol.shape)) > 0:
                symbol.body.position = (np.random.uniform(*x_limits), np.random.uniform(*y_limits))

            # Set angular velocity
            rotation_speed_limit_index = np.random.choice(len(self.params['rotation_speed_limits']))
            symbol.body.angular_velocity = np.random.uniform(
                *tuple(self.params['rotation_speed_limits'][rotation_speed_limit_index])
            )
            symbol.body.angular_velocity *= 1 if np.random.binomial(1, .5) else -1
            symbol.angular_velocity = symbol.body.angular_velocity

            # Set translational velocity
            sampled_velocity = np.random.uniform(-1, 1, 2)
            # If only lateral motion is allowed, map velocity to the nearest lateral one
            if self.params['lateral_motion_at_start']:
                v_angle = math.degrees(np.arctan2(sampled_velocity[1], sampled_velocity[0]))
                if v_angle >= -135 and v_angle < -45:
                    sampled_velocity = np.array([0, -1])
                elif v_angle >= -45 and v_angle < 45:
                    sampled_velocity = np.array([1, 0])
                elif v_angle >= 45 and v_angle < 135:
                    sampled_velocity = np.array([0, 1])
                else:
                    sampled_velocity = np.array([-1, 0])
            symbol.body.velocity = sampled_velocity / np.linalg.norm(sampled_velocity)
            position_speed_limit_index = np.random.choice(len(self.params['position_speed_limits']))
            symbol.body.velocity *= np.random.uniform(
                *tuple(self.params['position_speed_limits'][position_speed_limit_index])
            )

            # Add symbol to the space and environment
            self._space.add(symbol.body, symbol.shape)
            self.symbols.append(symbol)

            # Publish message about the symbol
            # self._publish_message(symbol.get_init_message())
            self._add_init_message(symbol.get_init_message())

        # Add walls
        self._add_walls()
        # Add collision handlers
        self._add_collision_handlers(
            interacting_symbols=self.params['interacting_symbols']
        )
        # Init step count
        self._step_count = 0

        # Set background image
        self.background = Image.fromarray(np.zeros((self.video_size[0], self.video_size[1], 3),
                                                   dtype=np.uint8))
        if bg_image_loader is not None:
            # Choose a category
            bg_labels = self.params['background_labels']
            category_name = bg_labels[np.random.randint(len(bg_labels))]
            # Choose an image
            bg_image, full_image_path = bg_image_loader.get_image(category_name)
            self.background.paste(bg_image)

            # Publish information about the chosen background
            self._add_init_message(dict(
                step=-1,
                type='background',
                meta=dict(
                    label=category_name,
                    image=np.array(self.background),
                    image_path=full_image_path
                )
            ))
Exemple #8
0
from pymunk.vec2d import Vec2d
from pymunk import pygame_util

fps = 60.0
pygame.init()
screen = pygame.display.set_mode((690, 300))
clock = pygame.time.Clock()

clock.tick(1 / 5.)

### Physics stuff
space = pymunk.Space()
space.gravity = 0, 900
space.sleep_time_threshold = 0.3

draw_options = pygame_util.DrawOptions(screen)
pygame_util.positive_y_is_up = False

### Physics stuff
space = pymunk.Space()
space.gravity = 0, 900
space.sleep_time_threshold = 0.3

draw_options = pygame_util.DrawOptions(screen)
pygame_util.positive_y_is_up = False

floor = pymunk.Segment(space.static_body, (-100, 210), (1000, 210), 5)
floor.friction = 1.0
space.add(floor)

# class Spider:
def run():
    celestialBodies = []
    celestialShapes = []
    screen = pg.display.get_surface()
    clock = pg.time.Clock()

    game = pg.Surface((10000, 10000))

    space = pm.Space()
    hud = HUD()

    earth = cb('earth', space, 10**13, 1000, 5000, 5000, 0.9, 0, 0)
    celestialBodies.append(earth.body)
    celestialShapes.append(earth.shape)

    earthMoon1 = cb('earthMoon1', space, 10**11, 250, 6500, 5000, 0.9, 0, 1)
    celestialBodies.append(earthMoon1.body)
    celestialShapes.append(earthMoon1.shape)

    planetGage = cb('planetGage', space, 10**12, 200, 1000, 1000, 0.9, 0, 0)
    celestialBodies.append(planetGage.body)
    celestialShapes.append(planetGage.shape)

    planetThomas = cb('planetThomas', space, 10**13, 200, 1500, 1500, .9, 0, 0)
    celestialBodies.append(planetThomas.body)
    celestialShapes.append(planetThomas.shape)

    planetZach = cb('planetZach', space, 10**13, 200, 2000, 1000, 0.9, 0, 0)
    celestialBodies.append(planetZach.body)
    celestialShapes.append(planetZach.shape)

    rocket = tr.genRocket(space)
    x, y = (earth.posx + earth.radius / math.sqrt(2),
            earth.posy + earth.radius / math.sqrt(2))
    rocket.position = x, y
    draw_options = pygame_util.DrawOptions(game)
    space.damping = 0.9

    fire_ticks = 480 * 50
    fire = False
    rotate = False
    auto = False
    sas_angle = 0
    print(rocket.position)

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT or keyDown(event, pg.K_ESCAPE):
                pg.quit()
                sys.exit(0)
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_a or event.key == pg.K_d:
                    rotKey = event.key
                    rotate = True
                elif event.key == pg.K_f:
                    fireKey = event.key
                    fire = True

            elif event.type == pg.KEYUP:
                if event.key == pg.K_a or event.key == pg.K_d:
                    rotate = False
                elif event.key == pg.K_f:
                    fire = False
                elif event.key == pg.K_v:
                    sas_angle = rocket.angle
                    auto = not auto

            elif event.type == pg.VIDEORESIZE:
                screen = pg.display.set_mode((event.w, event.h), pg.RESIZABLE)

        if fire:
            fire_ticks -= 1
            rocket.thrust(fireKey)
        if rotate:
            rocket.turn_SAS(rotKey, 1)
        if auto:
            rocket.auto_SAS(sas_angle)

        print(rocket.position)
        updateGravity(space, rocket, celestialShapes, celestialBodies)
        space.step(1 / 50.0)
        updateCamera(screen, game, rocket.position, space, draw_options)
        pos = rocket.position
        vel = rocket.velocity
        grav = space.gravity
        hud.updateHUD(pos[0], pos[1], (math.degrees(rocket.angle) + 90) % 360,
                      vel.length, vel.angle_degrees % 360, grav.length,
                      grav.angle_degrees % 360, rocket.components,
                      clock.get_fps())

        pg.display.flip()
        clock.tick(60)
Exemple #10
0
    def __init__(self):
        #pygame init
        pygame.init()
        self.w, self.h= W, H     #width and height
        self.gameDisplay= pygame.display.set_mode((self.w, self.h))
        self.clock= pygame.time.Clock()
        
        #pymunk init
        self.space= pymunk.Space()
        self.space.gravity= (0, -1000)         #gravity
        self.space.damping= 0.5

        draw_options = pgutil.DrawOptions(self.gameDisplay)
        draw_options.flags= pymunk.SpaceDebugDrawOptions.DRAW_SHAPES
        
        #Create Level
        self.level= Level(self.space, self.gameDisplay)
        
        #the collision handling for bird and pig
        bpgcol= self.space.add_collision_handler(1,2)
        bpgcol.data["pigs"]= self.level.pigs
        bpgcol.pre_solve= bird_pig_col

        #the collision handling for bird and plank
        bpl_col= self.space.add_collision_handler(1, 3)
        bpl_col.data["objs"]= self.level.objects
        bpl_col.pre_solve= bird_plank_col

        #the collision handling for bird and plank
        ppl_col= self.space.add_collision_handler(2, 3)
        ppl_col.data["objs"]= self.level.objects
        ppl_col.data["pigs"]= self.level.pigs
        ppl_col.pre_solve= pig_plank_col

        #the collision handling for pig with ground
        pg_col= self.space.add_collision_handler(0, 2)
        pg_col.data["objs"]= self.level.pigs
        pg_col.pre_solve= ground_col

        #the collision handling for plank with ground
        pg_col= self.space.add_collision_handler(0, 3)
        pg_col.data["objs"]= self.level.objects
        pg_col.pre_solve= ground_col

        self.mb_down=False     #to hold the bird

        self.counter=-1        #to add gap between bird shoot and new bird addition

        while True:
            for event in pygame.event.get():
                if event.type== pygame.QUIT:
                    pygame.quit()
                    quit()
                elif event.type== KEYDOWN and event.key== K_ESCAPE:
                    pygame.quit()
                    quit()
                elif event.type == KEYDOWN and event.key == K_SPACE and type(self.level.birds[-1]) == ThreeBird and self.level.birds[-1].a_avail:
                    self.level.birds[-1].split(self.level.birds)
                elif event.type== 5 and event.button==1 and self.level.sl_bird.is_avail==True:
                    '''
                    Add the bird to click down event, drag with mouse
                    added constrain to accept the drag event if click within 50pix distance max
                    '''
                    # print(event, H-event.pos[1]-self.bird.body.position[1])
                    if all([abs(event.pos[0]-self.level.sl_bird.body.position[0])<50,
                         abs(H-event.pos[1]-self.level.sl_bird.body.position[1])<50]):
                        self.mb_down=True
                        pos=event.pos      #stores current pos of mouse
                elif event.type==4 and self.mb_down:
                    '''Just to store new position of mouse'''
                    pos= event.pos

                elif event.type==6 and self.mb_down:
                    '''
                    If mouse is up, then shoot
                    '''
                    self.level.sl_bird.is_avail=False    #bird not available to shoot
                    self.mb_down=False
                    p=power(event.pos)             #calculate impulse to be applied
                    f= self.level.sl_bird.b_m*15          #factor
                    impulse= pymunk.Vec2d(p*f, 0)  #net impluse to apply
                    try:
                        impulse.rotate(math.atan2((event.pos[1]-sling_init[1]),-(event.pos[0]-sling_init[0])))
                    except ZeroDivisionError:
                        #to handle tan 90 case
                        impulse= pymunk.Vec2d(0, p*f)
                    self.level.sl_bird.shoot_bird(impulse)
                    self.level.birds.append(self.level.sl_bird)
                    self.counter=10       #10 frames to next bird add
            if self.counter==0:
                #add new bird
                self.counter-=1
                self.level.sl_bird=Bird(self.space)
            elif self.counter>0:
                #decrease countdown
                self.counter-=1

            #graphics behaviour
            self.gameDisplay.fill((255,255,255))

            #show first bird
            if self.mb_down:
                self.level.sl_bird.sling_bird(pos, self.gameDisplay)
            else:
                self.level.sl_bird.show(self.gameDisplay)
            
            #show other birds
            
            for bird in self.level.birds:
                bird.show(self.gameDisplay)
                #bird self destruct
                bird.timer-=1
                if bird.timer<0:
                    self.space.remove(bird, bird.body)
                    self.level.birds.remove(bird)
                    continue
                # if bird goes out of screen
                if bird.body.position.y<0 or bird.body.position.x<0 or bird.body.position.x>self.w:
                    self.space.remove(bird, bird.body)
                    self.level.birds.remove(bird)
                    # print("Bird Removed")
            
            for pig in self.level.pigs:
                #show pig
                if pig:
                    pig.show(self.gameDisplay)
                #pig cleanup
                if pig.body.position.y<0 or pig.body.position.x<0 or pig.body.position.x>self.w:
                    self.space.remove(pig.body, pig)
                    self.level.pigs.remove(pig)
                    print("Pig Removed")

            pygame.draw.line(self.gameDisplay, (225, 180, 255), to_pygame(*self.level.ground.a), to_pygame(*self.level.ground.b), 20)
            # self.space.debug_draw(draw_options)
            for obj in self.level.objects:
                obj.show(self.gameDisplay)
            # for ele in self.level.objects:
            #     pygame.draw.circle(self.gameDisplay, [0, 0, 0], to_pygame(*ele.pos), 5)

            # delta t= 1/80
            self.space.step(1/80.0)
            pygame.display.flip()
            #60 fps
            self.clock.tick(60)
def main():
    # Start up the game
    pygame.init()
    screen: Surface = pygame.display.set_mode((width, height))
    clock = pygame.time.Clock()
    running = True

    space = pymunk.Space()

    # This gravity would be if we wanted to have every object move in one direction, not towards each other
    space.gravity = (0, 0)

    # Allow pymunk to draw to pygame screen
    draw_options = pygame_util.DrawOptions(screen)

    # Sound to play when planets collide
    global click_sound
    click_sound = pygame.mixer.Sound('resources/click.ogg')

    # Initialize physical objects ---------------------------------------------------------------------------

    # Ball
    ball_body = pymunk.Body(mass=1000,
                            moment=pymunk.moment_for_circle(
                                1000, 0,
                                marble_img.get_width() / 2))
    ball_shape = pymunk.Circle(ball_body, marble_img.get_width() / 2)
    ball_shape.friction = 0.5
    ball_shape.elasticity = .9
    ball_shape.collision_type = BALL
    ball_shape.color = color.THECOLORS['coral']

    # add ball to the scene
    space.add(ball_shape)
    space.add(ball_body)

    # Planets
    planets = []
    for i in range(num_planets):
        size = random.randint(10, 15)
        planet_body, planet_shape = create_planet(
            space, size, math.pi * size**2,
            (random.randint(15,
                            screen.get_width() - 15),
             random.randint(15,
                            screen.get_height() - 15)))
        space.add(planet_shape)
        space.add(planet_body)
        planets.append(planet_body)

    # Set gravitational constant for planets - more planets means lower starting constant
    grav_const = 200 / num_planets
    gravity_enabled = False

    # Set up collision sounds between planets (see planet_collision)
    # handler = space.add_collision_handler(PLANET, PLANET)
    # handler.post_solve = planet_collision

    # Walls
    walls = [
        pymunk.Segment(space.static_body, (0, 0), (0, screen.get_width()), 2),
        pymunk.Segment(space.static_body, (0, screen.get_width()),
                       (screen.get_height(), screen.get_width()), 2),
        pymunk.Segment(space.static_body,
                       (screen.get_height(), screen.get_width()),
                       (screen.get_height(), 0), 2),
        pymunk.Segment(space.static_body, (screen.get_height(), 0), (0, 0), 2),
    ]
    for wall in walls:
        wall.friction = 0.1
        wall.elasticity = 0.999
    space.add(walls)

    music_started = True
    pygame.mixer.music.load('resources/moon.ogg')
    pygame.mixer.music.play(-1, 0.0)

    ball_body.position = (300, 400)

    # Main game loop ----------------------------------------------------------------------------------------
    while running:
        # Event handling
        for event in pygame.event.get():
            if event.type == QUIT or \
                    event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]):
                running = False
            if event.type == MOUSEBUTTONDOWN and event.button == 1:
                print(pygame.mouse.get_pos())
                if not music_started:
                    # Background Music
                    pygame.mixer.music.load('resources/moon.ogg')
                    pygame.mixer.music.play(-1, 0.0)
                    music_started = True
                mouse_position = pymunk.pygame_util.from_pygame(
                    Vec2d(pygame.mouse.get_pos()), screen)
                mouse_angle = (mouse_position - ball_body.position).angle
                impulse = ball_body.mass * 1000 * Vec2d(1, 0)
                impulse.rotate(mouse_angle)
                ball_body.apply_impulse_at_world_point(impulse,
                                                       ball_body.position)

            if event.type == KEYDOWN:
                # If up or down is pressed, change the gravitational constant by a factor of 10
                if event.key == K_UP:
                    grav_const *= 1.5
                    print("Gravity:", grav_const)
                if event.key == K_DOWN:
                    print("Gravity:", grav_const)
                    grav_const /= 1.5

                # Enable / Disable gravity with space
                if event.key == K_SPACE:
                    gravity_enabled = not gravity_enabled

        if gravity_enabled:
            for i, planet_1 in enumerate(planets):
                # run_gravity(planet_1, ball_body, grav_const)
                for planet_2 in planets[i + 1:]:
                    run_gravity(planet_1, planet_2, grav_const)

        # Graphics ---------------------------------------------------------------------------

        # Clear Screen
        screen.fill(pygame.color.THECOLORS['black'])

        # Use pygame interactivity to draw pymunk stuff
        space.debug_draw(draw_options)

        # Draw the rest of the stuff
        # screen.blit(pygame.transform.rotate(marble_img, ball_body.rotation_vector.angle_degrees), (ball_body.position[0] - ball_shape.radius, screen.get_height() - ball_body.position[1] - ball_shape.radius))
        font = pygame.font.SysFont("Arial", 13)
        # pygame.draw.rect(screen, color.THECOLORS['gray'], Rect(0, 0, 260, 60), 0)
        screen.blit(
            font.render(
                "Click anywhere to fire the red ball towards the mouse", 1,
                color.THECOLORS["white"]), (5, 5))
        screen.blit(
            font.render(
                "Press up or down to change the strength of gravity, space to enable/disable",
                1, color.THECOLORS["white"]), (5, 20))
        screen.blit(
            font.render("Gravitational Strength:", 1,
                        color.THECOLORS["white"]), (5, 40))
        screen.blit(
            font.render(str(round(grav_const, 3)), 1,
                        color.THECOLORS["yellow"]), (115, 40))

        gravity_color, gravity_text = (color.THECOLORS['green'],
                                       'Enabled') if gravity_enabled else (
                                           color.THECOLORS['red'], 'Disabled')
        screen.blit(font.render("Gravity:", 1, color.THECOLORS["white"]),
                    (5, 55))
        screen.blit(font.render(gravity_text, 1, gravity_color), (45, 55))

        # Update the screen
        pygame.display.flip()

        # Update physics and pygame clock
        fps = 60
        dt = 1. / fps
        space.step(dt)

        clock.tick(fps)
Exemple #12
0
    def reset(self):
        """
		Simply returns the initial state of the game
		"""
        if self.vis:
            pygame.init()
            self.screen = pygame.display.set_mode(
                (ceil(self.max_x) * 100,
                 ceil(self.max_y) * 100))  # 100pixels/meter
            self.clock = pygame.time.Clock()
            self.space = pymunk.Space()
            self.draw_options = pygame_util.DrawOptions(self.screen)

        # Initialise objects in game
        obj_positions = []
        for i in range(self.No):
            yes = True
            while yes:  # loops until we get an initialization of objects with no collisions
                r = 0.15
                x = r + np.random.rand() * (self.max_x - 2 * r)
                y = r + np.random.rand() * (self.max_y - 2 * r)
                collision = False
                for o in obj_positions:
                    if 2 * r >= np.sqrt((x - o[0])**2 + (y - o[1])**2):
                        collision = True
                        continue
                if not collision:
                    yes = False
                    obj_positions.append((x, y, r))

            m = 1.0 / (0.75 + np.random.rand() * 0.5
                       )  # 0.75-1.25kg - stored as m^-1
            v_x = -5 + np.random.rand() * 10  # -5-5m/s
            v_y = -5 + np.random.rand() * 10  # -5-5m/s
            q = 7.5 * 1e3
            obj = CircleMagnet(x, y, m, q, r, v_x, v_y)

            if self.vis:
                obj.shape = self.add_obj(obj)
                self.space.add(obj.shape, obj.shape.body)

            self.data[0].append(obj)
        self.data[0].extend(self.walls)

        # Initialize agent
        yes = True
        while yes:
            x = np.random.rand() * self.max_x
            y = np.random.rand() * self.max_y
            collision = False
            for o in obj_positions:
                if 0.15 + self.agent.r >= np.sqrt(
                    (x - o[0])**2 +
                    (y - o[1])**2):  # 0.2 = sum of agent and object radii
                    collision = True
                    continue
            if not collision:
                yes = False
                self.agent.x, self.agent.y = x, y

        # add agent to visualization
        if self.vis:
            self.agent.shape = self.add_agent(self.agent)
            self.space.add(self.agent.shape, self.agent.shape.body)

        # Convert state to RL format for output
        prev_state = self.data[0]
        for i in range(0, (self.No) * 2, 2):
            self.init_state[i] = prev_state[(i + 1) // 2].x
            self.init_state[i + 1] = prev_state[(i + 1) // 2].y
        self.init_state[(self.No + 4) * 2] = self.agent.x
        self.init_state[(self.No + 4) * 2 + 1] = self.agent.y