Esempio n. 1
0
class World(object):

    def __init__(self):
        self.items = []
        self.words = []
        self.springs = []
        init_pymunk()
        self.space = Space()
        self.space.resize_static_hash()
        self.space.resize_active_hash()

    def add_item(self, item):
##        self.items.append(item)
        self.space.add(item.shape)
        self.space.add(item.body)

    def add_spring(self, spring):
        self.springs.append(spring)
        self.space.add(spring)


    def add_word(self, word):
        self.words.append(word)

    def update(self):
        self.space.step(1.0)
Esempio n. 2
0
class PhysicsWorld(object):

    def __init__(self):
        self.space = None

    def init(self):
        init_pymunk()
        self.space = Space()
        self.space.gravity = (0, -0.002)
        self.space.resize_static_hash()
        self.space.resize_active_hash()


    def add(self, item, position, static):
        item.body.position = position
        if static:
            self.space.add_static(item.shape)
        else:
            self.space.add(item.body)
            self.space.add(item.shape)
            if item.rest_angle_spring:
                self.space.add(item.rest_angle_spring)


    def update(self, items):
        for item in items.itervalues():
            item.physics.update()

        self.space.step(1)
Esempio n. 3
0
class World(object):


    def __init__(self, debug_draw=None):
        self.space = Space()
        self.debug_draw = debug_draw


    def step(self, elapsed):
        if self.debug_draw:
            self.debug_draw.pre_world_step()
        self.space.step(elapsed)

        if self.debug_draw:
            for shape in self.space.shapes:
                if isinstance(shape, Poly):
                    self.debug_draw.DrawPolygon(shape)

        for body in self.space.bodies:
            body.reset_forces()

            

    def add(self, body_or_joint, shape=None):
        if shape is not None:
            self.space.add(body_or_joint, shape)
        else:
            self.space.add(body_or_joint)


    def render(self):
        if self.debug_draw:
            self.debug_draw.render()
Esempio n. 4
0
    def step(space: pymunk.Space, dt: float) -> None:
        """Step the space using a fixed timestep, even when ``dt`` varies.

        :param space: The space to step forward
        :param dt: A variable amount of time to move forward
        """
        nonlocal unused_dt
        steps, unused_dt = divmod(dt + unused_dt, fixed_timestep)
        for _ in range(int(steps)):
            space.step(fixed_timestep)
Esempio n. 5
0
class World(object):
    "Container for everything in the model, eg: Rooms and Chunks"

    def __init__(self):
        # pylint: disable-msg=W0212
        #   Access to a protected member '_space': ack
        init_pymunk()
        self.space = Space()
        self.space.gravity = (0, 0)
        self.space._space.contents.elasticIterations = 10
        self.static_body = Body(inf, inf)

        self.rooms = {}
        self.ents = set()
        self.chunks = set()
        self.player = None

        self.material = granite


    def add_to_pymunk(self):
        for room in self.rooms.itervalues():
            room.add_to_body(self.space, self.static_body)


    def add_chunk(self, chunk, position, angle=0):
        chunk.add_to_space(self.space, position, angle)
        self.chunks.add(chunk)


    def add_ent(self, ent, position, angle=0.0):
        ent.body.position = position
        ent.body.angle = angle
        self.space.add(ent.body)
        for shape in ent.shapes:
            self.space.add(shape)
        self.ents.add(ent)


    def tick(self, delta_t):
        if hasattr(self, 'player'):
            self.player.move()
        self.space.step(delta_t)
Esempio n. 6
0
class World(object):
    def __init__(self):
        self.items = []
        self.words = []
        self.springs = []
        init_pymunk()
        self.space = Space()
        self.space.resize_static_hash()
        self.space.resize_active_hash()

    def add_item(self, item):
        ##        self.items.append(item)
        self.space.add(item.shape)
        self.space.add(item.body)

    def add_spring(self, spring):
        self.springs.append(spring)
        self.space.add(spring)

    def add_word(self, word):
        self.words.append(word)

    def update(self):
        self.space.step(1.0)
Esempio n. 7
0
class World(object):

    def __init__(self):
        self.items = []
        init_pymunk()
        self.space = Space()
        self.space.gravity = (0, -0.5)
        self.space.resize_static_hash()
        self.space.resize_active_hash()
        self.leaves = []
        self.end_game = False
        

    def add_item(self, item):
        if isinstance(item, Bough):
            self.leaves.append(item)
        self.items.append(item)
        item.create_body()
        item.add_to_space(self.space)

    def remove_item(self, item):
        self.items.remove(item)
        item.remove_from_space(self.space)


    def update(self):
        self.space.step(0.5)
        for item in self.items:
            item.update()

    def remove_collided(self):
        for item in self.items:
            if item.status == "Collided":
                self.remove_item(item)
            
    def tick(self):
        max_limit = len(self.leaves) - 1
        if len(self.leaves) == 0:
                max_limit = 0 
##                print "End Level"
                self.end_game = True

        else:
##            print max_limit
            randno = random.randint(0, max_limit)
##            print randno
            leaf = self.leaves.pop(randno)
##            print leaf
            leaf.remove_from_tree(self.space)

    def add_cherry(self, x, y):
        cherry = Cherry(x, y)
        self.add_item(cherry)

    def add_owange(self, x, y):
        owange = Owange(x, y)
        self.add_item(owange)



    def add_collision_handler( self, 
                               col_typ1, 
                               col_typ2, 
                               begin=None, 
                               pre_solve=None,
                               post_solve=None, 
                               separate=None, 
                               **kwargs
        ):
        self.space.add_collision_handler(
            col_typ1, col_typ2,
            begin, pre_solve,
            post_solve, separate,
            **kwargs)
Esempio n. 8
0
class World(PyxelWorld):
    def __init__(self):
        super().__init__()
        self.space = Space(threaded=True)
        self.space.collision_slop = 0.7
        self.iter = 0
        self.time = 0.0
        self.on_reset = []
        self.P, self.I, self.D = 4.25347222, 0.0001041666, -4.67881944
        self.I = 0.0

        y = 0
        L = 500
        self.ground = self.line(-L,
                                y,
                                L,
                                y,
                                static=True,
                                friction=0.75,
                                radius=5)
        handler = self.space.add_wildcard_collision_handler(1)
        handler.begin = self.on_collision

    def update(self):
        dt = 1 / 30
        with LOCK:
            self.space.step(dt)
            self.time += dt

    def on_collision(self, arbiter, space, data):
        for fn in self.on_reset:
            fn(self)
        return True

    def reset(self):
        global segway

        self.time = 0.0
        self.iter += 1
        self.clear()
        ctrl.object = segway = self.segway()

    def clear(self):
        for shape in self.space.shapes:
            if shape not in self.ground.shapes:
                self.space.remove(shape)

        for cons in self.space.constraints:
            self.space.remove(cons)

        for body in self.space.bodies:
            if body is not self.ground:
                self.space.remove(body)

    def segway(self):
        R = 12
        L = 60
        segway = self.circ(0, R, R, mass=1, moment=1, friction=2.0)
        arm = self.line(0, R, 0, R + L, mass=2, moment=50)
        head = self.circ(0,
                         R + L,
                         R,
                         mass=8,
                         moment=8,
                         velocity=(-1, 0),
                         friction=0.1)
        self.pin([head, arm], collide=False)

        next(iter(head.shapes)).collision_type = 1

        self.pin([segway, arm], anchor=(0, -L / 2), collide=False)

        segway.update = iter(self.pid(segway, arm)).__next__
        segway.radius = R
        segway.arm = arm
        segway.head = head
        return segway

    def pid(self, wheel, arm):
        P, I, D = self.P, self.I, self.D
        cte = 100
        R = wheel.radius
        err_ = 0.0
        err_i = 0.0
        gamma = 0.02

        while True:
            err = arm.angle
            err_i = err + 0.9 * err_i
            err_d = err - err_

            w = cte * (P * err - I * err_i - D * err_d)
            if w == 0:
                F = 0
            else:
                F = 100 * (1 if w > wheel.angular_velocity else -1)
            F -= gamma * abs(F) * wheel.angular_velocity

            wheel.apply_force_at_local_point((0, +F), (+R, 0))
            wheel.apply_force_at_local_point((0, -F), (-R, 0))
            err_ = err
            yield
Esempio n. 9
0
class PlatformerScene(Scene):
    def __init__(self, game):
        super().__init__(game)
        self.player = None
        self.active = True

        self.geometry = list()
        self.space = Space()
        self.space.gravity = (0, 1000)
        self.sprites = LayeredUpdates()
        self.event_handler = event_handling.EventQueueHandler()
        self.background = resources.gfx("background.png", convert=True)
        self.load()
        pygame.mixer.music.load(resources.music_path("zirkus.ogg"))
        pygame.mixer.music.play(-1)

    def add_static(self, vertices, rect):
        body = pymunk.Body(body_type=pymunk.Body.STATIC)
        body.position = rect.x, rect.y
        shape = pymunk.Poly(body, vertices)
        shape.friction = 1.0
        shape.elasticity = 1.0
        self.space.add(body, shape)

    def load(self):
        def box_vertices(x, y, w, h):
            lt = x, y
            rt = x + w, y
            rb = x + w, y + h
            lb = x, y + h
            return lt, rt, rb, lb

        filename = path_join("data", "maps", "untitled.tmx")
        tmxdata = pytmx.util_pygame.load_pygame(filename)
        for obj in tmxdata.objects:
            if obj.type == map_fixed:
                rect = Rect(obj.x, obj.y, obj.width, obj.height)
                vertices = box_vertices(0, 0, obj.width, obj.height)
                self.add_static(vertices, rect)

            elif obj.type == map_yarn_spawn:
                ball = sprite.Ball(Rect((obj.x, obj.y), (32, 32)))
                model = BasicModel()
                model.sprites = [ball]
                model.pymunk_objects = ball.pymunk_shapes
                self.add_model(model)
                self.player = model

            elif obj.type == map_player_spawn:
                self.player = unicyclecat.build(self.space, self.sprites)
                self.player.position = obj.x, obj.y

        self.fsm = SimpleFSM(control, "idle")

    def add_model(self, model):
        self.sprites.add(*model.sprites)
        self.space.add(model.pymunk_objects)

    def remove_model(self, model):
        self.sprites.remove(*model.sprites)
        self.space.remove(model.pymunk_objects)

    def render(self):
        surface = self._game.screen
        surface.blit(self.background, (0, 0))
        self.sprites.draw(surface)
        return [surface.get_rect()]

    def tick(self, dt):
        step_amount = (1 / 30.) / 30
        for i in range(30):
            self.space.step(step_amount)
        self.sprites.update(dt)

    def event(self, pg_event):
        events = self.event_handler.process_event(pg_event)
        position = self.player.position

        for event in events:
            try:
                cmd, arg = self.fsm((event.button, event.held))
            except ValueError as e:
                continue

            if cmd == "move":
                resources.sfx("cat_wheel.ogg", False, True)
                resources.sfx("cat_wheel.ogg", True)
                self.player.accelerate(arg)

            if cmd == "idle":
                self.player.brake()

            elif cmd == "jump":
                resources.sfx("cat_jump.ogg", True)
                self.player.main_body.apply_impulse_at_world_point((0, -600),
                                                                   position)
Esempio n. 10
0
class Main(Scene):

	FADE_SPEED = 75

	def load(self):
		self.world_size = Size(3000, 3000)

		self.camera = Camera(self.size, self.world_size, 1000, 10)

		self._tool = None
		self.tool = None

		self.batch = graphics.Batch()
		self.background = CameraGroup(graphics.OrderedGroup(0), self.camera)
		self.foreground = CameraGroup(graphics.OrderedGroup(1), self.camera)
		self.playerg = CameraGroup(graphics.OrderedGroup(2), self.camera)
		self.world_ui = CameraGroup(graphics.OrderedGroup(3), self.camera)
		self.ui = graphics.OrderedGroup(2)

		self.space = Space()
		self.space.gravity = (0.0, 0.0)
		buffer = 100
		borders = Body()
		borders.position = (0, 0)
		left = Segment(borders, (-buffer, -buffer), (-buffer, self.world_size.height+buffer), buffer)
		bottom = Segment(borders, (-buffer, -buffer), (self.world_size.width+buffer, -buffer), buffer)
		right = Segment(borders, (self.world_size.width+buffer, self.world_size.height+buffer),
			(self.world_size.width+buffer, -buffer), buffer)
		top = Segment(borders, (self.world_size.width+buffer, self.world_size.height+buffer),
			(-buffer, self.world_size.height+buffer), buffer)
		self.space.add_static(left, bottom, right, top)

		self.stars = Stars(self.world_size, self.batch, self.background)

		self.asteroids = Asteroid.populate(50, 100, self.world_size, self.batch, self.foreground, self.space)

		if not self.asteroids:
			print("None of a particular resource on this asteroid belt, that'd be unfair. Trying again.")
			self.end(Main())
			return

		self.home_world = choice([asteroid for asteroid in self.asteroids if asteroid.position.y > self.world_size.height/4*3])
		self.home_world.type = "home"
		self.home_world.populated = True

		x, y = self.home_world.position
		self.camera.move(Vector(x-self.size.width/2, y-self.size.height/2))

		# Let's make stuff a bit more interesting.
		for asteroid in self.asteroids:
			if not asteroid.type == "home":
				asteroid.body.apply_impulse((triangular(-20000, 20000, 0), triangular(-20000, 20000, 0)))

		x, y = self.home_world.position
		self.player = Person(x+150, y+150, self.batch, self.playerg, self.space)
		self.mouse = x+150, y+150

		centre = Vector(self.size.width/2, self.size.height/2)
		image = centre_image(resource.image("logo.png"))
		self.logo = sprite.Sprite(image, centre.x, centre.y, batch=self.batch, group=self.ui)
		self.logo.opacity = 255
		self.fade = True
		self.faded = False

		planet = centre_image(resource.image("planet.png"))
		x = self.world_size.width/2
		y = planet.height/2
		self.planet_sprite = sprite.Sprite(planet, x, y, batch=self.batch, group=self.world_ui)
		self.win_box = BB(x-200, y-200, x+200, y+200)

		#self.tools = sorted([tool(self.space) for tool in Tool.__subclasses__()], key=attrgetter("order"), reverse=True)
		#self.buttons = {tool: Button(30, 30+number*50, tool.image, tool.description, self.use_tool(tool), self.ui, self.batch) for number, tool in enumerate(self.tools)}

		self.constraints = set()

	def use_tool(self, tool):
		"""For callback usage."""
		def f():
		  self.tool = tool
		return f

	@property
	def tool(self):
		return self._tool

	@tool.setter
	def tool(self, tool):
		if tool:
			if self._tool and not self._tool == tool:
				self._tool.end_selecting()
				self.buttons[self._tool].normal()
				self.window.set_mouse_cursor(self.window.get_system_mouse_cursor(self.window.CURSOR_DEFAULT))
				self.selecting = False
				self.selection = []
			self.window.set_mouse_cursor(self.window.get_system_mouse_cursor(self.window.CURSOR_CROSSHAIR))
			self.selecting = True
			self.buttons[tool].using()
		else:
			if self._tool:
				self._tool.end_selecting()
				self.buttons[self._tool].normal()
			self.window.set_mouse_cursor(self.window.get_system_mouse_cursor(self.window.CURSOR_DEFAULT))
			self.selecting = False
			self.selection = []
		self._tool = tool

	def key_pressed(self, symbol, modifiers):
		self.fade = True
		#self.camera.key_pressed(symbol)

	def key_released(self, symbol, modifiers):
		pass
		#self.camera.key_released(symbol)

	def mouse_pressed(self, x, y, key, modifiers):
		self.fade = True
		#for button in self.buttons.values():
		#	if button.point_over(x, y):
		#		button.callback()
		#		return
		if self.selecting:
			for asteroid in self.asteroids:
				clicked = self.camera.translate(x, y)
				if asteroid.point_over(*clicked):
					self.selection.append((asteroid, clicked))
					self.tool = self.tool.selection(self.selection, self.constraints)
					return
			self.tool = None
			return

	def mouse_motion(self, x, y, dx, dy):
		self.mouse = self.camera.translate(x, y)
		#for button in self.buttons.values():
	#		if button.point_over(x, y):
	#			button.on_mouse_over()
	#		else:
	#			button.on_mouse_leave()

	def mouse_drag(self, x, y, dx, dy, buttons, modifiers):
		if buttons & window.mouse.RIGHT:
			self.camera.mouse_dragged(dx, dy)

	def update(self, frame_time):
		self.constraints = {constraint for constraint in self.constraints if not constraint.update(self.batch, self.foreground)}
		if self.fade and not self.faded:
			self.logo.opacity -= Main.FADE_SPEED*frame_time
			if self.logo.opacity < 0:
				self.logo.opacity = 0
				del self.logo
				self.faded = True
		self.player.target = self.mouse
		self.player.update()
		x, y = self.player.body.position
		self.camera.x, self.camera.y = x-self.size.width/2, y-self.size.height/2
		self.camera.update(frame_time)
		self.space.step(1/60)
		if self.win_box.contains_vect(self.player.body.position):
			self.end(Win())

	def draw(self):
		self.batch.draw()
class PymunkSimulation:
    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

    def set_motor_rates(self, motor_rates):
        for i, motor in enumerate(self.motors):
            motor.rate = motor_rates[i]

    def set_motor_max_forces(self, motor_forces):
        for i, motor in enumerate(self.motors):
            motor.max_force = motor_forces[i]

    def step(self):
        dt = 0.03
        steps = 30
        for i in range(steps):
            self.space.step(dt / steps)

    def add_arm(self, segment_lengths, anchor_position):
        anchor = pymunk.Body(body_type=pymunk.Body.STATIC)
        anchor.position = anchor_position
        self.space.add(anchor)

        segment_anchor = anchor
        next_anchor_pos = anchor_position
        for i, segment_length in enumerate(segment_lengths):
            segment_size = segment_length, 10
            segment_body = pymunk.Body(10, pymunk.moment_for_box(10, segment_size))

            end_effector_shape = pymunk.Poly.create_box(segment_body, segment_size)
            end_effector_shape.collision_type = NO_COLLISION_TYPE
            end_effector_shape.friction = 1.0
            end_effector_shape.elasticity = 0.1

            alpha = random.random() * math.pi * 2
            dx = np.cos(alpha) * segment_length / 2
            dy = np.sin(alpha) * segment_length / 2
            segment_body.position = next_anchor_pos[0] - dx, next_anchor_pos[1] - dy
            next_anchor_pos = (next_anchor_pos[0] - 2 * dx, next_anchor_pos[1] - 2 * dy)
            segment_body.angle = alpha
            anchor_pin_pos = (0 if i == 0 else -segment_lengths[i - 1] / 2, 0)
            pin = pymunk.PinJoint(segment_anchor, segment_body, anchor_pin_pos, (segment_length / 2, 0))
            self.space.add(pin)
            self.space.add(segment_body, end_effector_shape)

            motor = pymunk.SimpleMotor(segment_anchor, segment_body, 0)
            motor.max_force = self.max_motor_force
            self.space.add(motor)
            self.motors.append(motor)
            self.segment_bodies.append(segment_body)
            segment_anchor = segment_body

        return segment_anchor, next_anchor_pos
Esempio n. 12
0
class VehicleSimulator(object):
    COLLISION_TYPE = IntEnum("COLLISION_TYPE",
                             "OBJECT VEHICLE LEFT_SENSOR RIGHT_SENSOR FEED")
    DISPLAY_MARGIN = 10
    ARENA_SIZE = 600

    # simulation setting parameters
    VEHICLE_RADIUS = 20
    SENSOR_ANGLE = np.pi * 45 / 180
    SENSOR_RANGE = 80
    SENSOR_NOISE = 0
    MOTOR_NOISE = 1.0
    FEED_COLOR = (0, 0, 0)
    FEED_ACTIVE_COLOR = (255, 0, 0)
    FEED_EATING_TIME = 200

    def __init__(self,
                 width=600,
                 height=600,
                 obstacle_num=5,
                 obstacle_radius=30,
                 feed_num=0,
                 feed_radius=5):
        import pyglet
        from pymunk import Space, Segment, Body, Circle, moment_for_circle, pyglet_util
        super(VehicleSimulator, self).__init__()
        self.__left_sensor_val = 0
        self.__right_sensor_val = 0
        self.__feed_sensor_val = False
        self.__feed_touch_counter = {}
        self.__feed_bodies = []
        self.__feed_radius = feed_radius

        self.__window = pyglet.window.Window(
            self.ARENA_SIZE + self.DISPLAY_MARGIN * 2,
            self.ARENA_SIZE + self.DISPLAY_MARGIN * 2,
            vsync=False)
        self.__draw_options = pyglet_util.DrawOptions()
        self.__closed = False

        @self.__window.event
        def on_draw():
            pyglet.gl.glClearColor(255, 255, 255, 255)
            self.__window.clear()
            self.__simulation_space.debug_draw(self.__draw_options)

        @self.__window.event
        def on_close():
            pyglet.app.EventLoop().exit()
            self.__closed = True

        self.__simulation_space = Space()
        self.__simulation_space.gravity = 0, 0

        # arena
        walls = [
            Segment(
                self.__simulation_space.static_body,
                (self.DISPLAY_MARGIN, self.DISPLAY_MARGIN),
                (self.ARENA_SIZE + self.DISPLAY_MARGIN, self.DISPLAY_MARGIN),
                0),
            Segment(
                self.__simulation_space.static_body,
                (self.ARENA_SIZE + self.DISPLAY_MARGIN, self.DISPLAY_MARGIN),
                (self.ARENA_SIZE + self.DISPLAY_MARGIN,
                 self.ARENA_SIZE + self.DISPLAY_MARGIN), 0),
            Segment(
                self.__simulation_space.static_body,
                (self.ARENA_SIZE + self.DISPLAY_MARGIN,
                 self.ARENA_SIZE + self.DISPLAY_MARGIN),
                (self.DISPLAY_MARGIN, self.ARENA_SIZE + self.DISPLAY_MARGIN),
                0),
            Segment(
                self.__simulation_space.static_body,
                (self.DISPLAY_MARGIN, self.ARENA_SIZE + self.DISPLAY_MARGIN),
                (self.DISPLAY_MARGIN, self.DISPLAY_MARGIN), 0)
        ]
        for w in walls:
            w.collision_type = self.COLLISION_TYPE.OBJECT
            w.friction = 0.2
        self.__simulation_space.add(walls)

        # vehicle
        mass = 1
        self.__vehicle_body = Body(
            mass, moment_for_circle(mass, 0, self.VEHICLE_RADIUS))
        self.__vehicle_shape = Circle(self.__vehicle_body, self.VEHICLE_RADIUS)
        self.__vehicle_shape.friction = 0.2
        self.__vehicle_shape.collision_type = self.COLLISION_TYPE.VEHICLE
        self.__simulation_space.add(self.__vehicle_body, self.__vehicle_shape)

        # left sensor
        sensor_l_s = Segment(self.__vehicle_body, (0, 0),
                             (self.SENSOR_RANGE * np.cos(self.SENSOR_ANGLE),
                              self.SENSOR_RANGE * np.sin(self.SENSOR_ANGLE)),
                             0)
        sensor_l_s.sensor = True
        sensor_l_s.collision_type = self.COLLISION_TYPE.LEFT_SENSOR
        handler_l = self.__simulation_space.add_collision_handler(
            self.COLLISION_TYPE.LEFT_SENSOR, self.COLLISION_TYPE.OBJECT)
        handler_l.pre_solve = self.__left_sensr_handler
        handler_l.separate = self.__left_sensr_separate_handler
        self.__simulation_space.add(sensor_l_s)

        # right sensor
        sensor_r_s = Segment(self.__vehicle_body, (0, 0),
                             (self.SENSOR_RANGE * np.cos(-self.SENSOR_ANGLE),
                              self.SENSOR_RANGE * np.sin(-self.SENSOR_ANGLE)),
                             0)
        sensor_r_s.sensor = True
        sensor_r_s.collision_type = self.COLLISION_TYPE.RIGHT_SENSOR
        handler_r = self.__simulation_space.add_collision_handler(
            self.COLLISION_TYPE.RIGHT_SENSOR, self.COLLISION_TYPE.OBJECT)
        handler_r.pre_solve = self.__right_sensr_handler
        handler_r.separate = self.__right_sensr_separate_handler
        self.__simulation_space.add(sensor_r_s)

        # obstacles
        for a in (np.linspace(0, np.pi * 2, obstacle_num, endpoint=False) +
                  np.pi / 2):
            body = Body(body_type=Body.STATIC)
            body.position = (self.DISPLAY_MARGIN + self.ARENA_SIZE / 2 +
                             self.ARENA_SIZE * 0.3 * np.cos(a),
                             self.DISPLAY_MARGIN + self.ARENA_SIZE / 2 +
                             self.ARENA_SIZE * 0.3 * np.sin(a))
            shape = Circle(body, obstacle_radius)
            shape.friction = 0.2
            shape.collision_type = self.COLLISION_TYPE.OBJECT
            self.__simulation_space.add(shape)

        for i in range(feed_num):
            body = Body(1, 1)
            self.__feed_bodies.append(body)
            shape = Circle(body, self.__feed_radius)
            shape.sensor = True
            shape.color = self.FEED_COLOR
            shape.collision_type = self.COLLISION_TYPE.FEED
            handler = self.__simulation_space.add_collision_handler(
                self.COLLISION_TYPE.VEHICLE, self.COLLISION_TYPE.FEED)
            handler.pre_solve = self.__feed_touch_handler
            handler.separate = self.__feed_separate_handler
            self.__simulation_space.add(body, shape)
            self.__feed_touch_counter[shape] = 0

        self.reset()

    def reset(self, random_seed=None):
        np.random.seed(random_seed)
        self.__vehicle_body.position = self.ARENA_SIZE / 2 + self.DISPLAY_MARGIN, self.ARENA_SIZE / 2 + self.DISPLAY_MARGIN
        self.__vehicle_body.angle = 0
        for b in self.__feed_bodies:
            b.position = self.DISPLAY_MARGIN + self.__feed_radius + np.random.rand(
                2) * (self.ARENA_SIZE - self.__feed_radius * 2)

    def update(self, action):
        self.__vehicle_body.velocity = (0, 0)
        self.__vehicle_body.angular_velocity = 0
        velocity_l, velocity_r = action[0], action[1]
        velocity_l += self.MOTOR_NOISE * np.random.randn()
        velocity_r += self.MOTOR_NOISE * np.random.randn()
        self.__vehicle_body.apply_impulse_at_local_point(
            (velocity_l * self.__vehicle_body.mass, 0),
            (0, self.VEHICLE_RADIUS))
        self.__vehicle_body.apply_impulse_at_local_point(
            (velocity_r * self.__vehicle_body.mass, 0),
            (0, -self.VEHICLE_RADIUS))
        lf = self.__get_lateral_velocity() * self.__vehicle_body.mass
        self.__vehicle_body.apply_impulse_at_local_point(-lf, (0, 0))
        self.__simulation_space.step(1 / 100)

        from pyglet import clock
        clock.tick()
        self.__window.switch_to()
        self.__window.dispatch_events()
        self.__window.dispatch_event('on_draw')
        self.__window.flip()

    def get_sensor_data(self):
        sensor_data = {
            "left_distance": self.__left_sensor_val,
            "right_distance": self.__right_sensor_val,
            "feed_touching": self.__feed_sensor_val
        }
        return sensor_data

    def set_bodycolor(self, color):
        assert len(color) == 3
        self.__vehicle_shape.color = color

    def __feed_touch_handler(self, arbiter, space, data):
        feed = arbiter.shapes[1]
        feed.color = self.FEED_ACTIVE_COLOR
        self.__feed_touch_counter[feed] += 1
        self.__feed_sensor_val = True
        if (self.__feed_touch_counter[feed] > self.FEED_EATING_TIME):
            feed.body.position = self.DISPLAY_MARGIN + feed.radius / 2 + np.random.rand(
                2) * (self.ARENA_SIZE - feed.radius)
        return True

    def __feed_separate_handler(self, arbiter, space, data):
        feed = arbiter.shapes[1]
        feed.color = self.FEED_COLOR
        self.__feed_touch_counter[feed] = 0
        self.__feed_sensor_val = False
        return True

    def __left_sensr_handler(self, arbiter, space, data):
        p = arbiter.contact_point_set.points[0]
        distance = self.__vehicle_body.world_to_local(p.point_b).get_length()
        self.__left_sensor_val = 1 - distance / self.SENSOR_RANGE
        self.__left_sensor_val += self.SENSOR_NOISE * np.random.randn()
        return True

    def __left_sensr_separate_handler(self, arbiter, space, data):
        self.__left_sensor_val = 0
        return True

    def __right_sensr_handler(self, arbiter, space, data):
        p = arbiter.contact_point_set.points[0]
        distance = self.__vehicle_body.world_to_local(p.point_b).get_length()
        self.__right_sensor_val = 1 - distance / self.SENSOR_RANGE
        self.__right_sensor_val += self.SENSOR_NOISE * np.random.randn()
        return True

    def __right_sensr_separate_handler(self, arbiter, space, data):
        self.__right_sensor_val = 0
        return True

    def __get_lateral_velocity(self):
        from pymunk.vec2d import Vec2d
        v = self.__vehicle_body.world_to_local(self.__vehicle_body.velocity +
                                               self.__vehicle_body.position)
        rn = Vec2d(0, -1)
        return v.dot(rn) * rn

    def __bool__(self):
        return not self.__closed
Esempio n. 13
0
class World(object):
    def __init__(self):
        self.items = []
        init_pymunk()
        self.space = Space()
        self.space.gravity = (0, -0.5)
        self.space.resize_static_hash()
        self.space.resize_active_hash()
        self.leaves = []
        self.end_game = False

    def add_item(self, item):
        if isinstance(item, Bough):
            self.leaves.append(item)
        self.items.append(item)
        item.create_body()
        item.add_to_space(self.space)

    def remove_item(self, item):
        self.items.remove(item)
        item.remove_from_space(self.space)

    def update(self):
        self.space.step(0.5)
        for item in self.items:
            item.update()

    def remove_collided(self):
        for item in self.items:
            if item.status == "Collided":
                self.remove_item(item)

    def tick(self):
        max_limit = len(self.leaves) - 1
        if len(self.leaves) == 0:
            max_limit = 0
            ##                print "End Level"
            self.end_game = True

        else:
            ##            print max_limit
            randno = random.randint(0, max_limit)
            ##            print randno
            leaf = self.leaves.pop(randno)
            ##            print leaf
            leaf.remove_from_tree(self.space)

    def add_cherry(self, x, y):
        cherry = Cherry(x, y)
        self.add_item(cherry)

    def add_owange(self, x, y):
        owange = Owange(x, y)
        self.add_item(owange)

    def add_collision_handler(self,
                              col_typ1,
                              col_typ2,
                              begin=None,
                              pre_solve=None,
                              post_solve=None,
                              separate=None,
                              **kwargs):
        self.space.add_collision_handler(col_typ1, col_typ2, begin, pre_solve,
                                         post_solve, separate, **kwargs)