Example #1
0
 def initializeTerrain(self,
                       polys,
                       color=(0, 0, 0),
                       linewidth=4,
                       sprite=None):
     obstacles = []
     points = [(0, 0), (self.dimensions[0], 0),
               (self.dimensions[0], self.dimensions[1]),
               (0, self.dimensions[1])]
     lines = [((0, 0), (self.dimensions[0], 0)),
              ((self.dimensions[0], 0), (self.dimensions[0],
                                         self.dimensions[1])),
              ((self.dimensions[0], self.dimensions[1]),
               (0, self.dimensions[1])), ((0, self.dimensions[1]), (0, 0))]
     for poly in polys:
         #minpt = (min(map(lambda p: p[0], poly)), min(map(lambda p: p[1], poly)))
         #maxpt = (max(map(lambda p: p[0], poly)), max(map(lambda p: p[1], poly)))
         #center = [ (sum(map(lambda p: p[0], poly))/float(len(poly)))-((maxpt[0]-minpt[0])/2.0), (sum(map(lambda p: p[1], poly))/float(len(poly)))-((maxpt[1]-minpt[1])/2.0) ]
         #newpoly = map(lambda pt: (pt[0] - minpt[0], pt[1] - minpt[1]), poly)
         o = ManualObstacle(poly, color, linewidth, sprite)
         points = points + o.getPoints()
         lines = lines + o.getLines()
         obstacles.append(o)
     self.obstacles = obstacles
     self.quadTree = QuadTree(self.obstacles)
     self.points = points
     self.lines = lines
Example #2
0
 def change_size(self, size):
     self.mapsize = size
     self.realrect_quadtree = QuadTree(self.gen_real_rect(self.mapsize), 0, 5, 10, [], "realrect")
     self.floor_quadtree = QuadTree(Rect(0, 0, self.mapsize[0] * WIDTH, self.mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
     self.refresh_realrect_quadtree()
     self.refresh_floor_quadtree()
     self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
Example #3
0
File: FMM.py Project: sjtuzwj/FMMM
def singlelevel(Points):
    k = 0
    while (k < ST.TIME / ST.ITERATIONTIME):
        Tree = QT.tree(QT.Rect(ST.MINX, ST.MAXX, ST.MAXY, ST.MINY))
        Tree.QuadtreeBuild(Points.values())
        Tree.QuadTreeShrink(Tree.root)
        Multipole_Framework(Points, Tree)
        k = k + 1
Example #4
0
 def load_map(self, path, mapsize):
     self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5, 10, [], "realrect")
     self.floor_quadtree = QuadTree(Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
     self.load_obstaclemap(os.path.join(path, "obstacles.py"))
     self.load_charactermap(os.path.join(path, "characters.py"))
     self.load_triggermap(os.path.join(path, "triggers.py"))
     self.load_item_map(os.path.join(path, "items.py"))
     self.refresh_realrect_quadtree()
     self.refresh_floor_quadtree()
     self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
Example #5
0
 def create_map(self, mapsize):
     self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5, 10, [], "realrect")
     self.floor_quadtree = QuadTree(Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
     self.layers = [[], []]
     self.rect_obstacles = []
     self.charactermap = []
     self.triggers = []
     self.item_map = []
     self.refresh_realrect_quadtree()
     self.refresh_floor_quadtree()
     self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
Example #6
0
 def change_size(self, size):
     self.mapsize = size
     self.realrect_quadtree = QuadTree(self.gen_real_rect(self.mapsize), 0,
                                       5, 10, [], "realrect")
     self.floor_quadtree = QuadTree(
         Rect(0, 0, self.mapsize[0] * WIDTH, self.mapsize[1] * TILEHEIGHT),
         0, 5, 10, [], "rect")
     self.refresh_realrect_quadtree()
     self.refresh_floor_quadtree()
     self.map_diam = math.ceil(
         math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))
Example #7
0
 def load_map(self, path, mapsize):
     self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5,
                                       10, [], "realrect")
     self.floor_quadtree = QuadTree(
         Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10,
         [], "rect")
     self.load_obstaclemap(os.path.join(path, "obstacles.py"))
     self.load_charactermap(os.path.join(path, "characters.py"))
     self.load_triggermap(os.path.join(path, "triggers.py"))
     self.load_item_map(os.path.join(path, "items.py"))
     self.refresh_realrect_quadtree()
     self.refresh_floor_quadtree()
     self.map_diam = math.ceil(
         math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))
Example #8
0
 def create_map(self, mapsize):
     self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5,
                                       10, [], "realrect")
     self.floor_quadtree = QuadTree(
         Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10,
         [], "rect")
     self.layers = [[], []]
     self.rect_obstacles = []
     self.charactermap = []
     self.triggers = []
     self.item_map = []
     self.refresh_realrect_quadtree()
     self.refresh_floor_quadtree()
     self.map_diam = math.ceil(
         math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))
Example #9
0
    def update(self):
        """

        Returns:

        """
        self.last_update = []
        quad_tree = QuadTree.QuadTree(
            QuadTree.Rect(self.board.centerx, self.board.centery,
                          self.board.width / 2, self.board.height / 2), 5)
        for key, orb in self.orbs.iteritems():
            quad_tree.insert(QuadTree.Point(orb.point.x, orb.point.y, key))

        self.move_snakes()
        self.orbs_collision(quad_tree)
        self.snakes_collision()
        self.border_collision()
        self.add_orbs()
Example #10
0
    def orbs_collision(self, quad_tree):
        """

        Args:
            quad_tree:

        Returns:

        """
        for snake in self.snakes.itervalues():
            for sector in [snake.head] + snake.tail:
                range = QuadTree.Rect(sector.point.x, sector.point.y,
                                      sector.radius + objects.Orb.MAX_RADIUS,
                                      sector.radius + objects.Orb.MAX_RADIUS)
                orbs = quad_tree.qurey(range)
                for orb_point in orbs:
                    key = orb_point.data
                    if key not in self.orbs:
                        continue

                    orb = self.orbs[key]
                    if sector.collide(orb):
                        self.del_orb(key)
                        snake.mass += orb.mass
def navigate(goal_xw, goal_yw, world_w, world_h, world_map):
    #pub = rospy.Publisher('chatter', String, queue_size=10)
    global x
    global y
    global heading
    global pose_init

    # Create ROS node
    rospy.init_node('quadtree_planner')

    # Subscribe to currnet pose
    rospy.Subscriber('base_pose_ground_truth', Odometry, current_pose_callback)

    # Publisher
    velocity_publisher = rospy.Publisher('cmd_vel', Twist, queue_size=10)

    # Command to publish
    base_cmd = Twist()

    # Read Map File
    r = png.Reader(filename=world_map)
    w, h, pixels, metadata = r.read_flat()

    # Create quadtree
    quad = QuadTree.QuadTree(0, 0, w, h, pixels, w, None)

    # Wait for current pose
    rate = rospy.Rate(10)
    while not pose_init and not rospy.is_shutdown():
        rospy.loginfo("waiting for pose init...")
        rate.sleep()

    x_start, y_start = helpers.world_to_map_transform(x, y, w, h, world_w,
                                                      world_h)
    x_goal, y_goal = helpers.world_to_map_transform(goal_xw, goal_yw, w, h,
                                                    world_w, world_h)

    rospy.loginfo("Trying to find a path from (" + str(x) + "," + str(y) +
                  ") to (" + str(goal_xw) + ", " + str(goal_yw) + ").")

    path = QuadTree.dijkstras(x_start, y_start, x_goal, y_goal, quad)

    if path == None:
        rospy.loginfo("No path found.")
        return

    rospy.loginfo("Path found... Let's go!")

    # Render map
    draw(quad, w, h, path, x_goal, y_goal)

    world_path = helpers.transform_path(path, w, h, world_w, world_h)
    world_path.append((goal_xw, goal_yw))

    waypoint_idx = 0

    # Let's go
    while not rospy.is_shutdown():
        dx = world_path[waypoint_idx][0] - x
        dy = world_path[waypoint_idx][1] - y

        if (dx * dx + dy * dy < 0.1) and (waypoint_idx < len(world_path) - 1):
            waypoint_idx += 1

        target_heading = math.atan2(dy, dx)
        d_heading = (target_heading - heading)

        if (target_heading > math.pi / 2
                and heading < -math.pi / 2) or (target_heading < -math.pi / 2
                                                and heading > math.pi / 2):
            d_heading = -d_heading

        # Drive forward if we are facing the right direction
        if math.fabs(d_heading) < math.pi / 10 and dx * dx + dy * dy > 0.1:
            base_cmd.linear.x = 2
        else:
            base_cmd.linear.x = 0

        base_cmd.angular.z = 1 * d_heading

        velocity_publisher.publish(base_cmd)

        #        velocity_publisher.publish(base_cmd)
        rate.sleep()
Example #12
0
            pos_i = Shapes.Point(opponent.x, opponent.y)

    running1 = True
    pygame.init()
    gameDisplay = pygame.display.set_mode((width, length))
    gameDisplay.fill((255, 255, 255))
    clock = pygame.time.Clock()

    iters = 0
    while any([player1.alive for player1 in players]) and running1:
        #print(iters)
        iters += 1
        pygame.display.update()
        gameDisplay.fill((255, 255, 255))

        q1 = QuadTree.QuadTree(r1, 4, keys=['x', 'y'])
        for player1 in players:
            if player1.alive:
                player1.show(gameDisplay)
                if player1.color == (0, 255, 0):
                    pygame.draw.circle(gameDisplay, (0, 255, 0),
                                       (int(player1.x), int(player1.y)), rad,
                                       1)
                q1.insert(player1)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                running1 = False

            keys = pygame.key.get_pressed()
Example #13
0
class MapBuilder:
    def __init__(self):
        self.gridList = []  #type:List[Grid]
        self.sceneTree = None  #type:QuadTree
        self.bounds = None  #type:Box2D
        self.obstacles = None  #type:List[Obstacle]

    def BuildMap(self, bounds: Box2D, obstacles: List[Obstacle]):
        self.sceneTree = QuadTree(bounds)
        self.bounds = bounds
        for ob in obstacles:
            self.sceneTree.AddElement(ob)

        xValues = []  #type:List[Tuple[int,bool,Obstacle]]

        xValues.append((bounds.GetMinX(), False, None))
        for ob in obstacles:
            xValues.append((ob.GetBounds().GetMinX(), True, ob))
            xValues.append((ob.GetBounds().GetMaxX(), False, ob))
        xValues.append((bounds.GetMaxX(), True, None))

        xValues.sort(key=lambda e: e[0])

        #leftEdges = [Edge(Point2D(bounds.GetMinX(),bounds.GetMinY()),Point2D(bounds.GetMinX(),bounds.GetMaxY()))]
        leftEdges = []  #type:List[Edge]

        rightEdges = []  #type:List[Tuple[Edge,bool]]
        for i in range(len(xValues) + 1):
            if i == len(xValues) or (i > 0
                                     and xValues[i - 1][0] != xValues[i][0]):
                if len(rightEdges) > 0:
                    x = xValues[i - 1][0]
                    # add non-existent edge to finish finding upper edge of new grid
                    rightEdges.append(
                        (Edge(Point2D(x,
                                      bounds.GetMaxY() + 1),
                              Point2D(x,
                                      bounds.GetMaxY() + 2)), True))
                    #sort
                    rightEdges.sort(key=lambda e: e[0].GetMinY())
                    # remove repeated edge
                    edgeNum = len(rightEdges)
                    idx = 1
                    while idx < edgeNum:
                        if rightEdges[idx][0] == rightEdges[idx - 1][0]:
                            del rightEdges[idx]
                            edgeNum -= 1
                            continue
                        idx += 1

                    #use right edges to close left edges and get grids
                    newGrid = Grid()
                    closedEdge = []

                    rIdx = 0
                    lIdx = 0
                    startY = rightEdges[rIdx][0].GetMinY()
                    endY = rightEdges[rIdx][0].GetMaxY()
                    bottomY = -1
                    upY = -1

                    #walk through edges from bottom to up
                    while rIdx < edgeNum - 1 and lIdx < len(leftEdges):
                        if leftEdges[lIdx].GetMaxY() <= startY:
                            # current right edge can not close this left edge,try next.
                            lIdx += 1
                            continue
                        if endY <= leftEdges[lIdx].GetMinY():
                            #no left edge can be closed by current right edge.
                            rIdx += 1
                            #update Y
                            startY = rightEdges[rIdx][0].GetMinY()
                            endY = rightEdges[rIdx][0].GetMaxY()
                            continue

                        if leftEdges[lIdx].GetMinY() <= startY:
                            if leftEdges[lIdx].GetMaxY() == endY:

                                newGrid.AddLeftEdge(leftEdges[lIdx])
                                newGrid.AddRightEdge(
                                    Edge(
                                        Point2D(x,
                                                rightEdges[rIdx][0].GetMinY()),
                                        Point2D(
                                            x, rightEdges[rIdx][0].GetMaxY())))
                                closedEdge.append(lIdx)

                                if bottomY == -1:
                                    bottomY = startY

                                if (rightEdges[rIdx][0].GetMaxY() <
                                        rightEdges[rIdx + 1][0].GetMinY()
                                        or lIdx == len(leftEdges)
                                        or leftEdges[lIdx].GetMaxY() <
                                        leftEdges[lIdx + 1].GetMinY()):
                                    #get new grid
                                    if upY == -1:
                                        upY = endY
                                        leftX = leftEdges[lIdx].GetMinX()
                                        rightX = x
                                        newGrid.SetBottomEdge(
                                            Edge(Point2D(leftX, bottomY),
                                                 Point2D(rightX, bottomY)))
                                        newGrid.SetUpperEdge(
                                            Edge(Point2D(leftX, upY),
                                                 Point2D(rightX, upY)))
                                        self.gridList.append(newGrid)
                                        # reset grid info to get next new grid
                                        newGrid = Grid()
                                        bottomY = -1
                                        upY = -1

                                lIdx += 1
                                rIdx += 1
                                #update Y
                                startY = rightEdges[rIdx][0].GetMinY()
                                endY = rightEdges[rIdx][0].GetMaxY()

                            elif leftEdges[lIdx].GetMaxY() < endY:

                                newGrid.AddLeftEdge(leftEdges[lIdx])
                                closedEdge.append(lIdx)

                                if bottomY == -1:
                                    bottomY = startY
                                #update Y
                                startY = leftEdges[lIdx].GetMaxY()
                                lIdx += 1

                            else:  #leftEdges[lIdx].GetMaxY() > endY:

                                newGrid.AddRightEdge(
                                    Edge(
                                        Point2D(x,
                                                rightEdges[rIdx][0].GetMinY()),
                                        Point2D(
                                            x, rightEdges[rIdx][0].GetMaxY())))

                                if bottomY == -1:
                                    bottomY = startY

                                if rightEdges[rIdx][0].GetMaxY() < rightEdges[
                                        rIdx + 1][0].GetMinY():
                                    #get new grid
                                    if upY == -1:
                                        upY = endY
                                        leftX = leftEdges[lIdx].GetMinX()
                                        rightX = x
                                        newGrid.SetBottomEdge(
                                            Edge(Point2D(leftX, bottomY),
                                                 Point2D(rightX, bottomY)))
                                        newGrid.SetUpperEdge(
                                            Edge(Point2D(leftX, upY),
                                                 Point2D(rightX, upY)))
                                        self.gridList.append(newGrid)
                                        # reset grid info to get next new grid
                                        newGrid = Grid()
                                        bottomY = -1
                                        upY = -1

                                rIdx += 1
                                #update Y
                                startY = rightEdges[rIdx][0].GetMinY()
                                endY = rightEdges[rIdx][0].GetMaxY()
                    closedEdge.sort(reverse=True)
                    for lIdx in closedEdge:
                        del leftEdges[lIdx]
                    #update leftEdge
                    for e in rightEdges:
                        if not e[1]:
                            leftEdges.append(e[0])
                    leftEdges.sort(key=lambda e: e.GetMinY())
                    rightEdges.clear()
                    yield leftEdges

            if i == len(xValues):
                continue

            x = xValues[i][0]
            bOpen = xValues[i][1]
            source = xValues[i][2]  #type:Obstacle

            if source != None:
                # middle edge
                start = Point2D(x, source.GetBounds().GetMinY())
                end = Point2D(x, source.GetBounds().GetMaxY())
                self._GetRightEdges(rightEdges, end, start, source, True,
                                    bOpen)
                # trace towards down
                start = Point2D(x, source.GetBounds().GetMinY())
                end = Point2D(x, bounds.GetMinY() - 1)
                self._GetRightEdges(rightEdges, end, start, source, False,
                                    False)
                # trace towards up
                start = Point2D(x, source.GetBounds().GetMaxY())
                end = Point2D(x, bounds.GetMaxY() + 1)
                self._GetRightEdges(rightEdges, end, start, source, False,
                                    False)
            else:
                start = Point2D(x, self.bounds.GetMinY())
                end = Point2D(x, self.bounds.GetMaxY())
                self._GetRightEdges(rightEdges, end, start, None, True, bOpen)

    def _SpliteVEdge(self, bounds: Box2D, end: Point2D, start: Point2D,
                     outSplitedEdge: List) -> bool:
        assert start.x == end.x and start.y != end.y
        bSplited = False
        bReverse = False

        if end.y < start.y:
            #swap start and end
            start.y, end.y = end.y, start.y
            bReverse = True

        if start.x >= bounds.GetMinX() and start.x <= bounds.GetMaxX():
            if end.y >= bounds.GetMinY() and start.y <= bounds.GetMaxY():
                if start.y < bounds.GetMinY():
                    newStart = Point2D(start.x, start.y)
                    newEnd = Point2D(start.x, bounds.GetMinY())
                    outSplitedEdge.append((newStart, newEnd))

                if end.y > bounds.GetMaxY():
                    newStart = Point2D(start.x, bounds.GetMaxY())
                    newEnd = Point2D(start.x, end.y)
                    outSplitedEdge.append((newStart, newEnd))
                bSplited = True

        #recover
        if bReverse:
            start.y, end.y = end.y, start.y
            bReverse = False
        return bSplited

    def _GetRightEdges(self, rightEdges: List, end: Point2D, start: Point2D,
                       source: Interface_QuadTreeDataSupptor,
                       bFromObstacle: bool, bIsOpen: bool):
        if bFromObstacle:
            lineTrace = CheckResult()
            self.sceneTree.LineCheck(lineTrace, end, start, source)
            splitedEdges = [(start, end)]
            if lineTrace.bHit:
                while lineTrace != None:
                    assert lineTrace.bHit and lineTrace.hitElement != None
                    currentEdgeNum = len(splitedEdges)
                    idx = 0
                    while idx < currentEdgeNum:
                        e = splitedEdges[idx]
                        if self._SpliteVEdge(lineTrace.hitElement.GetBounds(),
                                             e[1], e[0], splitedEdges):
                            del splitedEdges[idx]
                            currentEdgeNum -= 1
                            continue
                        idx += 1
                    lineTrace = lineTrace.next
            if len(splitedEdges) > 0:
                for e in splitedEdges:
                    rightEdges.append((Edge(e[0], e[1]), bIsOpen))
        else:
            checkResult = CheckResult()
            self.sceneTree.LineCheck(checkResult, end, start, source, True)
            if checkResult.bHit:
                if checkResult.hitTimer > 0.0:
                    #trace up
                    if end.y > start.y:
                        end.y = checkResult.hitElement.GetBounds().GetMinY()
                        if end.y != start.y:
                            rightEdges.append((Edge(start, end), bIsOpen))
                    #trace down
                    elif end.y < start.y:
                        end.y = checkResult.hitElement.GetBounds().GetMaxY()
                        if end.y != start.y:
                            rightEdges.append((Edge(end, start), bIsOpen))
            else:
                #trace up
                if end.y > start.y:
                    end.y = self.bounds.GetMaxY()
                    if end.y > start.y:
                        rightEdges.append((Edge(start, end), bIsOpen))
                #trace down
                elif end.y < start.y:
                    end.y = self.bounds.GetMinY()
                    if end.y != start.y:
                        rightEdges.append((Edge(end, start), bIsOpen))
Example #14
0
objs = []

# Sliders for parameter values
scale_align_slider = Slider("Align", scale_align, .4, 0, 10)
scale_cohesion_slider = Slider("Cohesion", scale_cohesion, .2, 0, 115)
scale_separation_slider = Slider("Separation", scale_separation, 1.6, 0, 220)
scale_noise_slider = Slider("Noise", scale_noise, .2, 0, 325)
scale_speed_slider = Slider("Speed", speed, 40, 1, 430)
scale_perception_slider = Slider("Perception", perception, 200, 0.1, 535)
slides = [
    scale_align_slider, scale_cohesion_slider, scale_separation_slider,
    scale_noise_slider, scale_speed_slider, scale_perception_slider
]

# Quad tree speed optimization
quad = QuadTree(npartitions, screen_size[0], screen)

while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = 0
        elif event.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            for s in slides:
                if s.button_rect.collidepoint(pos):
                    s.hit = True
            if (screen_size[0] - 10 > pos[0] > 10) and (screen_size[1] - 90 >
                                                        pos[1] > 10):
                objs.append(Avoid(pos[0], pos[1]))

        elif event.type == pygame.MOUSEBUTTONUP:
Example #15
0
            pygame.draw.rect(screen, (255, 0, 0),
                             [x, y + height1 + height2, 1, height3])
        x += 1


# Pygame initialization
screen_size = [600, 600]
pygame.init()
screen = pygame.display.set_mode((screen_size[0] + 400, screen_size[1]))
font = pygame.font.SysFont("Arial", 36)
font1 = pygame.font.SysFont("Arial", 18)
running = 1

# Quad tree initialization
npartitions = 2  # Default 2 must be nonzero
quad = QuadTree(npartitions, screen_size[0], screen)

# Set up variables for sim
spread_probability = probability / 100
people = []
infected = []
ID = 0
for i in range(npeople - 1):
    theta = random.random() * 2 * math.pi
    people.append(
        Person(random.random() * screen_size[0],
               random.random() * screen_size[1], math.cos(theta),
               math.sin(theta), False, ID))
    ID += 1
patient_zero = Person(random.random() * screen_size[0],
                      random.random() * screen_size[1], math.cos(theta),
Example #16
0
class GameWorld():

    ### screen: the screen
    ### background: the background surface
    ### agent: the player agent
    ### obstacles: obstacles
    ### sprites: all sprites (player and NPCs)
    ### npcs: the NPC agents
    ### dimensions: the size of the world (width, height)
    ### points: all the points of obstacles, plus screen corners
    ### lines: all the points of obstacles, plus screen edges
    ### bullets: all the bullets active
    ### resources: all the resources
    ### movers: all things that can collide with other things and implement collision()
    ### destinations: places that are not inside of obstacles.
    ### clock: elapsed time in game

    def __init__(self, seed, worlddimensions, screendimensions):
        #initialize random seed
        self.time = time.time()
        corerandom.seed(seed or self.time)
        random.seed(self.time)
        #initialize Pygame and set up screen and background surface
        pygame.init()
        self.font = pygame.font.SysFont("monospace", 15)
        screen = pygame.display.set_mode(screendimensions)
        # Background surface that will hold everything
        #		background = pygame.Surface(screen.get_size())
        background = pygame.Surface(worlddimensions)
        background = background.convert()
        background.fill((255, 255, 255))
        # Debug surface
        debug = pygame.Surface(worlddimensions)
        debug = debug.convert()
        debug.fill((255, 255, 255))
        background.blit(debug, (0, 0))
        screen.blit(background, (0, 0))
        pygame.display.flip()
        #store stuff
        self.screen = screen
        self.seed = seed or self.time
        self.background = background
        self.debug = debug
        self.obstacles = None
        self.sprites = None
        self.agent = None
        self.npcs = []
        self.dimensions = worlddimensions
        self.points = None
        self.lines = None
        self.bullets = []
        self.resources = []
        self.debugging = False
        self.movers = []
        self.clock = 0
        # camera
        self.camera = [0, 0]
        # unobstructed places
        self.destinations = {}

    def getPoints(self):
        return self.points

    def getLines(self):
        return self.lines

    def getLinesWithoutBorders(self):
        corners = [(0, 0), (self.dimensions[0], 0),
                   (self.dimensions[0], self.dimensions[1]),
                   (0, self.dimensions[1])]
        lines = []
        for l in self.getLines():
            if not (l[0] in corners and l[1] in corners):
                lines.append(l)
        return lines

    def getObstacles(self):
        return self.obstacles

    def getDimensions(self):
        return self.dimensions

    def setPlayerAgent(self, agent):
        self.agent = agent
        self.camera = agent.getLocation()
        self.movers.append(agent)
#		print agent.radius

# Make Random Terrain

    def initializeRandomTerrain(self, num, onum, radius, sigma, min):
        obstacles = []
        points = [(0, 0), (self.dimensions[0], 0),
                  (self.dimensions[0], self.dimensions[1]),
                  (0, self.dimensions[1])]
        lines = [((0, 0), (self.dimensions[0], 0)),
                 ((self.dimensions[0], 0), (self.dimensions[0],
                                            self.dimensions[1])),
                 ((self.dimensions[0], self.dimensions[1]),
                  (0, self.dimensions[1])), ((0, self.dimensions[1]), (0, 0))]
        for _ in xrange(num):
            pos = [0, 0]
            for _ in xrange(100):
                pos = [
                    corerandom.randint(0, self.dimensions[0] - radius),
                    corerandom.randint(0, self.dimensions[1] - radius)
                ]
                tooclose = False
                for o in obstacles:
                    if distance(pos, o.pos) < radius * 2:
                        tooclose = True
                if tooclose == False:
                    break
            o = RandomObstacle(onum, pos, radius, sigma, min)
            obstacles.append(o)
            points = points + o.getPoints()
            lines = lines + o.getLines()
        self.obstacles = obstacles
        self.points = points
        self.lines = lines

    # Make Terrain
    # polys = list of list points (poly1, poly2, ...) = ((p11, p12, ...), (p21, p22, ...), ...)
    def initializeTerrain(self,
                          polys,
                          color=(0, 0, 0),
                          linewidth=4,
                          sprite=None):
        obstacles = []
        points = [(0, 0), (self.dimensions[0], 0),
                  (self.dimensions[0], self.dimensions[1]),
                  (0, self.dimensions[1])]
        lines = [((0, 0), (self.dimensions[0], 0)),
                 ((self.dimensions[0], 0), (self.dimensions[0],
                                            self.dimensions[1])),
                 ((self.dimensions[0], self.dimensions[1]),
                  (0, self.dimensions[1])), ((0, self.dimensions[1]), (0, 0))]
        for poly in polys:
            #minpt = (min(map(lambda p: p[0], poly)), min(map(lambda p: p[1], poly)))
            #maxpt = (max(map(lambda p: p[0], poly)), max(map(lambda p: p[1], poly)))
            #center = [ (sum(map(lambda p: p[0], poly))/float(len(poly)))-((maxpt[0]-minpt[0])/2.0), (sum(map(lambda p: p[1], poly))/float(len(poly)))-((maxpt[1]-minpt[1])/2.0) ]
            #newpoly = map(lambda pt: (pt[0] - minpt[0], pt[1] - minpt[1]), poly)
            o = ManualObstacle(poly, color, linewidth, sprite)
            points = points + o.getPoints()
            lines = lines + o.getLines()
            obstacles.append(o)
        self.obstacles = obstacles
        self.quadTree = QuadTree(self.obstacles)
        self.points = points
        self.lines = lines

    def initializeResources(self, points, resource=RESOURCE):
        for point in points:
            r = SimpleResource(resource, point, 0, self)
            self.addResource(r)

    def initializeRandomResources(self, num, resource=RESOURCE):
        for _ in xrange(num):
            pos = (0, 0)
            while True:
                pos = (corerandom.randint(0, self.dimensions[0]),
                       corerandom.randint(0, self.dimensions[1]))
                inside = False
                for o in self.obstacles:
                    if pointInsidePolygonPoints(pos, o.getPoints()):
                        inside = True
                if inside == False:
                    break
            r = SimpleResource(resource, pos, 0, self)
            self.addResource(r)
#			self.resources.add(r)
#			self.movers.add(r)

    def run(self):
        self.sprites = pygame.sprite.RenderPlain((self.agent))
        #		for r in self.resources:
        #			self.sprites.add(r)
        #		for n in self.npcs:
        #			self.sprites.add(n)
        for m in self.movers:
            self.sprites.add(m)
        clock = pygame.time.Clock()

        # Draw obstacles. Only need to do this once
        for o in self.obstacles:
            o.draw(self.background)

        while True:
            clock.tick(TICK)
            delta = clock.get_rawtime()
            self.handleEvents()
            self.update(delta)
            self.sprites.update(delta)
            #print "obstacles"
            #for o in self.obstacles:
            #	print o.pos
            #	o.pos[0] = o.pos[0] + 1.0
            #	o.pos[1] = o.pos[1] + 1.0
            self.drawWorld()
            pygame.display.flip()

    def drawWorld(self):
        #self.screen.blit(self.background, (0, 0))
        offsetX = self.camera[0] - self.agent.rect.center[0]
        offsetY = self.camera[1] - self.agent.rect.center[1]
        self.screen.fill((255, 255, 255))
        self.screen.blit(self.background, [offsetX, offsetY])
        if self.debugging:
            self.background.blit(self.debug, (0, 0))
        self.sprites.draw(self.background)
        for o in self.obstacles:
            o.draw(self.background)
        self.drawMousePosition()
        #pygame.display.flip()

    def drawMousePosition(self):
        offsetX, offsetY = self.getWorldMousePosition()
        offsetX = int(round(offsetX))
        offsetY = int(round(offsetY))
        label = self.font.render("Mouse: " + str(offsetX) + "," + str(offsetY),
                                 True, (255, 0, 0))
        textPosition = (10, 10)
        self.screen.blit(label, textPosition)

    def handleEvents(self):
        events = pygame.event.get()
        for event in events:
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == MOUSEBUTTONUP:
                self.doMouseUp()
            elif event.type == KEYDOWN:
                self.doKeyDown(event.key)

    def doMouseUp(self):
        offsetX, offsetY = self.getWorldMousePosition()
        self.agent.navigateTo([offsetX, offsetY])

    def getWorldMousePosition(self):
        pos = pygame.mouse.get_pos()
        offsetX = pos[0] + self.agent.position[0] - self.camera[0]
        offsetY = pos[1] + self.agent.position[1] - self.camera[1]
        return offsetX, offsetY

    def doKeyDown(self, key):
        if key == 32:  #space
            self.agent.shoot()
        elif key == 100:  #d
            print "distance traveled", self.agent.distanceTraveled

    def worldCollisionTest(self):
        collisions = []
        for m1 in self.movers:
            if m1 in self.movers:
                # Collision against world boundaries
                if m1.position[0] < 0 or m1.position[0] > self.dimensions[
                        0] or m1.position[1] < 0 or m1.position[
                            1] > self.dimensions[1]:
                    collisions.append((m1, self))
                # Collision against obstacles
                for o in self.quadTree.hit(m1.rect):
                    c = False
                    for l in o.getLines():
                        if c:
                            break
                        for r in ((m1.rect.topleft, m1.rect.topright),
                                  (m1.rect.topright, m1.rect.bottomright),
                                  (m1.rect.bottomright, m1.rect.bottomleft),
                                  (m1.rect.bottomleft, m1.rect.topleft)):
                            hit = calculateIntersectPoint(
                                l[0], l[1], r[0], r[1])
                            if hit is not None:
                                c = True
                                break
                    if c:
                        collisions.append((m1, o))
                # Movers against movers
                for m2 in self.movers:
                    if m2 in self.movers:
                        if m1 != m2:
                            if (m1, m2) not in collisions and (
                                    m2, m1) not in collisions:
                                if m1.rect.colliderect(m2.rect):
                                    collisions.append((m1, m2))
        for c in collisions:
            c[0].collision(c[1])
            c[1].collision(c[0])

    def update(self, delta):
        self.clock = self.clock + delta
        self.worldCollisionTest()
        return None

    def collision(self, thing):
        return None

    def getLines(self):
        return self.lines[:]

    def getPoints(self):
        return self.points[:]

    def addBullet(self, bullet):
        self.bullets.append(bullet)
        if self.sprites is not None:
            self.sprites.add(bullet)
        self.movers.append(bullet)

    def deleteBullet(self, bullet):
        if bullet in self.bullets:
            self.bullets.remove(bullet)
            if self.sprites is not None:
                self.sprites.remove(bullet)
            self.movers.remove(bullet)

    def addResource(self, res):
        self.resources.append(res)
        if self.sprites is not None:
            self.sprites.add(res)
        self.movers.append(res)

    def deleteResource(self, res):
        self.resources.remove(res)
        if self.sprites is not None:
            self.sprites.remove(res)
        self.movers.remove(res)

    def addNPC(self, npc):
        self.npcs.append(npc)
        if self.sprites is not None:
            self.sprites.add(npc)
        self.movers.append(npc)

    def deleteNPC(self, npc):
        if npc in self.npcs:
            self.npcs.remove(npc)
            if self.sprites is not None:
                self.sprites.remove(npc)
            self.movers.remove(npc)

    def getVisible(self, position, orientation, viewangle, type=None):
        visible = []
        for m in self.movers:
            if type == None or isinstance(m, type):
                # m is the type that we are looking for
                other = m.getLocation()
                if other != position:
                    # other is not me
                    if viewangle < 360:
                        # viewangle less than 360
                        orient = (math.cos(math.radians(orientation)),
                                  -math.sin(math.radians(orientation)))
                        vect = (other[0] - position[0], other[1] - position[1])
                        x = dotProduct(orient, vect) / (
                            vectorMagnitude(orient) * vectorMagnitude(vect))
                        if x >= 1.0:
                            angle = 0.0
                        else:
                            angle = math.degrees(math.acos(x))
                        if angle < viewangle / 2.0:
                            hit = rayTraceWorld(position, other,
                                                self.getLines())
                            if hit == None:
                                visible.append(m)
                    else:
                        # viewangle is 360
                        hit = rayTraceWorld(position, other, self.getLines())
                        if hit == None:
                            visible.append(m)
        return visible

    def computeFreeLocations(self, agent):
        if type(agent) not in self.destinations:
            destinations = []
            grid = agent.getRadius() * 2.0
            for x in xrange(1, int(self.dimensions[0] / grid)):
                for y in xrange(1, int(self.dimensions[1] / grid)):
                    point = (x * grid, y * grid)
                    if isGood(point, self, grid):
                        destinations.append(point)
            self.destinations[type(agent)] = destinations

    def getFreeLocations(self, agent):
        if type(agent) in self.destinations:
            return self.destinations[type(agent)]
        else:
            return None

    def getNPCs(self):
        return self.npcs

    def getAgent(self):
        return self.agent

    def getBullets(self):
        return self.bullets
Example #17
0
	
	#screen settings
	screen = pygame.display.set_mode( ( int(WINDOW_X * 2), int(WINDOW_Y * 2) ) )

	done = False
	
	number_of_particles = 300
	
	#create list of particle
	my_particles = []
	my_particles.extend(addParticles(screen, number_of_particles, (255, 0 , 0)))
	my_particles.extend(addParticles(screen, number_of_particles, (0, 255 , 0)))
	my_particles.extend(addParticles(screen, number_of_particles, (0, 0 , 255)))
	
	#create quad tree
	quadtree = QuadTree( 0, Border( -WINDOW_X, -WINDOW_Y, WINDOW_X * 2, WINDOW_Y * 2 ) )

	#starting clock
	clock = pygame.time.Clock()
	
	#set time of first frame
	deltatime = 0.02

	while not done:
	
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				done = True

		#add all of particle to quad tree
		for element in my_particles:
Example #18
0
class Obstacles():
    def __init__(self, screen, obstacles, characters, items):
        self.screen = screen
        self.obstacles = obstacles
        self.characters = characters
        self.items = items

        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []

        self.selected = None
        self.screen_offset = [0, 0]
        self.properties_frame = None

    def save(self, path):
        final_characters = [
            character.get_dict() for character in self.charactermap
        ]
        final_items = [item.get_dict() for item in self.item_map]
        final_triggers = [trigger.get_dict() for trigger in self.triggers]
        final_obstacles = [[
            obstacle.get_dict()
            for obstacle in self.layers[0] + self.rect_obstacles
        ], [obstacle.get_dict() for obstacle in self.layers[1]]]
        with open(os.path.join(path, "characters.py"), "w") as f:
            f.write("characters = " + repr(final_characters))
        with open(os.path.join(path, "items.py"), "w") as f:
            f.write("items = " + repr(final_items))
        with open(os.path.join(path, "triggers.py"), "w") as f:
            f.write("triggers = " + repr(final_triggers))
        with open(os.path.join(path, "obstacles.py"), "w") as f:
            f.write("layers = " + repr(final_obstacles))

    def gen_real_rect(self, mapsize):
        self.mapsize = mapsize
        real_height = mapsize[1] * (ISOHEIGHT //
                                    2) + mapsize[0] * (ISOHEIGHT // 2)
        real_width = mapsize[1] * (ISOWIDTH // 2) + mapsize[0] * (ISOWIDTH //
                                                                  2)
        startx = -(mapsize[1] * (ISOWIDTH // 2))
        starty = 0
        return Rect(startx, starty, real_width, real_height)

    def create_map(self, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5,
                                          10, [], "realrect")
        self.floor_quadtree = QuadTree(
            Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10,
            [], "rect")
        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(
            math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))

    def load_map(self, path, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5,
                                          10, [], "realrect")
        self.floor_quadtree = QuadTree(
            Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10,
            [], "rect")
        self.load_obstaclemap(os.path.join(path, "obstacles.py"))
        self.load_charactermap(os.path.join(path, "characters.py"))
        self.load_triggermap(os.path.join(path, "triggers.py"))
        self.load_item_map(os.path.join(path, "items.py"))
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(
            math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))

    def change_size(self, size):
        self.mapsize = size
        self.realrect_quadtree = QuadTree(self.gen_real_rect(self.mapsize), 0,
                                          5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(
            Rect(0, 0, self.mapsize[0] * WIDTH, self.mapsize[1] * TILEHEIGHT),
            0, 5, 10, [], "rect")
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(
            math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))

    def delete_item(self, item):
        self.item_map.remove(item)

    def add_item(self, item):
        self.item_map.append(self.create_item(item))

    def create_item(self, info):
        item_info = self.items[info["type"]].copy()
        temp = item_info.copy()
        temp.update(info)
        temp.update({"item_info": item_info.copy()})
        return Item(self.screen, **temp)

    def refresh_realrect_quadtree(self):
        self.realrect_quadtree.clear()
        self.realrect_quadtree.particles = [
            j for i in self.layers for j in i
        ] + self.charactermap + self.item_map
        self.realrect_quadtree.update()

    def refresh_floor_quadtree(self):
        self.floor_quadtree.clear()
        self.floor_quadtree.particles = self.triggers + self.rect_obstacles
        self.floor_quadtree.update()

    def delete_obs(self, **kwargs):
        obs = kwargs.get("obstacle", None)
        for index, layer in enumerate(self.layers):
            try:
                layer.remove(obs)
                break
            except:
                continue

    def delete_trigger(self, trigger):
        try:
            self.triggers.remove(trigger)
        except:
            pass

    def delete_character(self, identifier):
        try:
            self.characters.remove(character)
        except:
            pass

    def create_obstacle(self, **info):
        if info["type"] == "RECT":
            return BasicObstacle(self.screen,
                                 x=info["x"],
                                 y=info["y"],
                                 width=info.get("width", 1),
                                 height=info.get("height", 1),
                                 type="RECT")
        else:
            tile_dict = self.obstacles[int(info["type"])]
            if type(tile_dict["images"]) == list:
                tile_dict["images"] = tile_dict["images"][0]
            complete_info = tile_dict.copy()
            complete_info.update(info)
            complete_info.update(
                {"orig_info": self.obstacles[int(info["type"])]})
            return Obstacle(self.screen, **complete_info)

    def spawn_character(self, **kwargs):
        if kwargs.get("info", None):
            self.charactermap.append(self.create_character(kwargs["info"]))
        else:
            self.charactermap.append(
                Character(self.screen,
                          x=kwargs.get("x", 0),
                          y=kwargs.get("y", 0),
                          name=kwargs["name"]))

    def load_obstaclemap(self, path):
        self.layers = []
        self.rect_obstacles = []
        temp = load_module(path)
        for layer in temp.layers:
            self.layers.append([])
            for obs in layer:
                new = self.create_obstacle(**obs)
                if type(new) == BasicObstacle:
                    self.rect_obstacles.append(new)
                else:
                    self.layers[-1].append(new)
        self.refresh_floor_quadtree()
        self.refresh_realrect_quadtree()

    def load_charactermap(self, path):
        self.charactermap = []
        temp = load_module(path)
        for character in temp.characters:
            self.charactermap.append(self.create_character(character))
        self.refresh_realrect_quadtree()

    def load_triggermap(self, path):
        self.triggers = []
        temp = load_module(path)
        for trigger in temp.triggers:
            self.triggers.append(Trigger(self.screen, **trigger))
        self.refresh_floor_quadtree()

    def load_item_map(self, path):
        self.item_map = []
        temp = load_module(path)
        for item in temp.items:
            self.item_map.append(self.create_item(item))
        self.refresh_realrect_quadtree()

    def create_character(self, info):
        temp = self.characters[info["name"]].copy()
        temp.update(info)
        temp.update({"orig_info": self.characters[info["name"]].copy()})
        return Character(self.screen, obstaclemap=self, **temp)

    def set_entry_value(self, entry, value):
        entry.delete(0, "end")
        entry.insert(0, value)

    def click(self, mouse_pos, tile_pos, mode, current_obs, current_layer,
              current_item, current_character, current_tab, properties_frame):
        for thing in [
                j for i in self.layers for j in i
        ] + self.charactermap + self.item_map + self.rect_obstacles + self.triggers:
            thing.deselect()
        self.selected = None
        if mode == 0:
            selected = self.realrect_quadtree.collidepoint(mouse_pos)
            selected1 = self.floor_quadtree.collidepoint(
                (tile_pos[0] * WIDTH, tile_pos[1] * HEIGHT))
            if selected or selected1:
                self.selected = max(selected + selected1,
                                    key=lambda x: (x.x, x.y))
                self.selected.select()
        elif mode == 1:
            if current_tab == "Obstacles":
                new_obs = self.create_obstacle(type=current_obs,
                                               x=tile_pos[0],
                                               y=tile_pos[1],
                                               width=1,
                                               height=1)
                if type(new_obs) == BasicObstacle:
                    self.rect_obstacles.append(new_obs)
                else:
                    self.layers[current_layer].append(new_obs)
            elif current_tab == "Items":
                new_obs = self.create_item({
                    "type": current_item,
                    "x": tile_pos[0],
                    "y": tile_pos[1]
                })
                self.item_map.append(new_obs)
            elif current_tab == "Characters":
                new_obs = self.create_character({
                    "name": current_character,
                    "x": tile_pos[0],
                    "y": tile_pos[1]
                })
                self.charactermap.append(new_obs)
            elif current_tab == "Triggers":
                new_obs = Trigger(self.screen,
                                  x=tile_pos[0],
                                  y=tile_pos[1],
                                  width=1,
                                  height=1)
                self.triggers.append(new_obs)
            self.selected = new_obs
            new_obs.select()
            self.refresh_realrect_quadtree()
            self.refresh_floor_quadtree()
        self.create_properties_widget(properties_frame)
        if self.selected:
            return True
        else:
            return False

    def destroy_properties_widget(self):
        if self.properties_frame:
            self.properties_frame.destroy()
            self.properties_frame = None
            self.widgets = {}

    def create_properties_widget(self, parent):
        self.destroy_properties_widget()
        if self.selected:
            obs_type = type(self.selected)
            if obs_type == BasicObstacle:
                possible_options = ["x", "y", "width", "height", "identifier"]
            elif obs_type == Trigger:
                possible_options = [
                    "x", "y", "width", "height", "deactivate_after_use",
                    "active", "identifier", "trigger"
                ]
            elif obs_type == Obstacle:
                possible_options = [
                    "x", "y", "identifier", "action", "after_looting", "items",
                    "animation", "label", "onclick"
                ]
            elif obs_type == Character:
                possible_options = [
                    "x", "y", "dead", "weapon", "label", "identifier",
                    "aggression_distance", "direction", "health",
                    "random_walk_area", "waypoints", "ondeath"
                ]
            elif obs_type == Item:
                possible_options = [
                    "x", "y", "label", "identifier", "onpickup"
                ]
            self.properties_frame = ttk.Frame(parent)
            self.widgets = {}
            for index, option in enumerate(possible_options):
                if option in [
                        "x", "y", "width", "height", "aggression_distance",
                        "health"
                ]:
                    if option in ["x", "width"]:
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame,
                            from_=0,
                            to=self.mapsize[0],
                            increment=0.1)
                    elif option in ["y", "height"]:
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame,
                            from_=0,
                            to=self.mapsize[1],
                            increment=0.1)
                    elif option == "aggression_distance":
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame,
                            from_=0,
                            to=self.map_diam,
                            increment=0.1)
                    elif option == "health":
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame, from_=0, to=1000)
                    self.set_entry_value(self.widgets[option],
                                         getattr(self.selected, option))
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in [
                        "action", "weapon", "label", "identifier", "direction",
                        "animation", "after_looting", "items"
                ]:
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    attr = getattr(self.selected, option)
                    if option == "items" and attr is not None:
                        attr = ";".join(attr)
                    if attr is None:
                        attr = ""
                    self.set_entry_value(self.widgets[option], attr)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in ["active", "deactivate_after_use", "dead"]:
                    variable = tk.IntVar()
                    variable.set(int(getattr(self.selected, option)))
                    self.widgets[option] = {
                        "widget":
                        ttk.Checkbutton(self.properties_frame,
                                        text=option,
                                        variable=variable),
                        "variable":
                        variable
                    }
                    self.widgets[option]["widget"].grid(row=index,
                                                        column=1,
                                                        sticky="w")
                elif option in ["onclick", "trigger", "ondeath", "onpickup"]:
                    self.widgets[option] = [
                        ttk.Combobox(self.properties_frame,
                                     values=("REPLACE", "DELETE", "ADD",
                                             "KILL", "KILLALL", "SPAWN",
                                             "OPEN", "CLOSE", "DEACTIVATE",
                                             "ACTIVATE", "WINGAME",
                                             "TRYWINGAME", "CHANGEMAP",
                                             "TRYCHANGEMAP")),
                        ttk.Combobox(self.properties_frame,
                                     values=("obstacle", "character", "item",
                                             "trigger")),
                        ttk.Entry(self.properties_frame),
                        ttk.Entry(self.properties_frame),
                        ttk.Entry(self.properties_frame)
                    ]
                    for widget_index, widget in enumerate(
                            self.widgets[option]):
                        try:
                            if type(widget) == ttk.Combobox:
                                widget.set(
                                    getattr(self.selected,
                                            option)[widget_index])
                            else:
                                self.set_entry_value(
                                    widget,
                                    getattr(self.selected,
                                            option)[widget_index])
                        except:
                            pass
                        widget.grid(row=index + widget_index,
                                    column=1,
                                    sticky="w")
                elif option == "waypoints":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(
                        self.widgets[option],
                        ";".join(",".join([str(y) for y in x])
                                 for x in getattr(self.selected, option)))
                elif option == "random_walk_area":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(
                        self.widgets[option], ";".join(
                            str(x) for x in getattr(self.selected, option)))
                if option not in ["deactivate_after_use", "dead", "active"]:
                    ttk.Label(self.properties_frame,
                              text=option).grid(row=index,
                                                column=0,
                                                sticky="w")
            self.properties_frame.grid(row=1, column=0, sticky="nswe")

    def mousedrag(self, mouse_pos, pos_change):
        if self.selected:
            self.set_attributes(x=self.selected.x + pos_change[0],
                                y=self.selected.y + pos_change[1])
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()

    def delete(self, *args):
        if self.selected:
            if type(self.selected) == Character:
                self.charactermap.remove(self.selected)
            elif type(self.selected) == Obstacle:
                try:
                    self.layers[0].remove(self.selected)
                except:
                    self.layers[1].remove(self.selected)
            elif type(self.selected) == Item:
                self.item_map.remove(self.selected)
            elif type(self.selected) == BasicObstacle:
                self.rect_obstacles.remove(self.selected)
            elif type(self.selected) == Trigger:
                self.triggers.remove(self.selected)
            self.selected = None
            self.refresh_floor_quadtree()
            self.refresh_realrect_quadtree()

    def set_attributes(self, **kwargs):
        if self.selected:
            if self.properties_frame:
                final_dict = {}
                for key, item in self.widgets.items():
                    if type(item) == dict:
                        value = bool(item["variable"].get())
                    elif type(item) == list:
                        value = []
                        for part in item:
                            temp_val = part.get()
                            if temp_val:
                                value.append(temp_val)
                    else:
                        value = item.get()
                        try:
                            if key in ["after_looting", "health"]:
                                value = int(value)
                            elif key in ["x", "y", "width", "height"]:
                                value = float(value)
                        except:
                            pass
                    if key in [
                            "x", "y", "width", "height", "aggression_distance"
                    ]:
                        try:
                            final_dict[key] = float(value)
                        except:
                            pass
                    elif key == "direction":
                        if value in [
                                "NW", "N", "NE", "E", "W", "SW", "SE", "S"
                        ]:
                            final_dict[key] = value
                    elif key == "items":
                        if value:
                            value = [x.strip() for x in value.split(";")]
                            final_dict[key] = value
                    elif key == "waypoints":
                        try:
                            if value:
                                value = [[float(y) for y in x.split(",")]
                                         for x in value.split(";")]
                            for x in value:
                                if len(x) < 2:
                                    break
                            else:
                                final_dict[key] = value
                        except:
                            pass
                    elif key == "random_walk_area":
                        try:
                            if value:
                                value = [float(x) for x in value.split(";")]
                            if len(value) == 4 or not value:
                                final_dict[key] = value
                        except:
                            pass
                    else:
                        final_dict[key] = value
                final_dict.update(kwargs)
                self.selected.set_values(**final_dict)
                for key, item in kwargs.items():
                    if key in ["x", "y"]:
                        self.set_entry_value(self.widgets[key], item)

    def draw_cursor(self, tile_pos, current_obs, current_item, current_char,
                    current_tab, screen_offset):
        if current_tab == "Obstacles":
            temp = self.create_obstacle(type=current_obs,
                                        x=tile_pos[0],
                                        y=tile_pos[1])
        elif current_tab == "Items":
            temp = self.create_item({
                "type": current_item,
                "x": tile_pos[0],
                "y": tile_pos[1]
            })
        elif current_tab == "Characters":
            temp = self.create_character({
                "name": current_char,
                "x": tile_pos[0],
                "y": tile_pos[1]
            })
        elif current_tab == "Triggers":
            temp = Trigger(self.screen, x=tile_pos[0], y=tile_pos[1])
        temp.draw(screen_offset)

    def draw(self, screen_offset):
        self.set_attributes()
        final = sorted(self.layers[1] + self.charactermap,
                       key=lambda x: (x.x, x.y))
        ground = sorted(self.layers[0] + self.triggers + self.rect_obstacles +
                        self.item_map,
                        key=lambda x: (x.x, x.y))
        for ground_obs in ground:
            ground_obs.draw(screen_offset)
        for thing in final:
            thing.draw(screen_offset)
Example #19
0
class Obstacles():
    def __init__(self, screen, obstacles, characters, items):
        self.screen = screen
        self.obstacles = obstacles
        self.characters = characters
        self.items = items
        
        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []
        
        self.selected = None
        self.screen_offset = [0, 0]
        self.properties_frame = None
    def save(self, path):
        final_characters = [character.get_dict() for character in self.charactermap]
        final_items = [item.get_dict() for item in self.item_map]
        final_triggers = [trigger.get_dict() for trigger in self.triggers]
        final_obstacles = [[obstacle.get_dict() for obstacle in self.layers[0] + self.rect_obstacles], [obstacle.get_dict() for obstacle in self.layers[1]]]
        with open(os.path.join(path, "characters.py"), "w") as f:
            f.write("characters = " + repr(final_characters))
        with open(os.path.join(path, "items.py"), "w") as f:
            f.write("items = " + repr(final_items))
        with open(os.path.join(path, "triggers.py"), "w") as f:
            f.write("triggers = " + repr(final_triggers))
        with open(os.path.join(path, "obstacles.py"), "w") as f:
            f.write("layers = " + repr(final_obstacles))
    def gen_real_rect(self, mapsize):
        self.mapsize = mapsize
        real_height = mapsize[1] * (ISOHEIGHT // 2) + mapsize[0] * (ISOHEIGHT // 2)
        real_width = mapsize[1] * (ISOWIDTH // 2) + mapsize[0] * (ISOWIDTH // 2)
        startx = -(mapsize[1] * (ISOWIDTH // 2))
        starty = 0
        return Rect(startx, starty, real_width, real_height)
    def create_map(self, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
    def load_map(self, path, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
        self.load_obstaclemap(os.path.join(path, "obstacles.py"))
        self.load_charactermap(os.path.join(path, "characters.py"))
        self.load_triggermap(os.path.join(path, "triggers.py"))
        self.load_item_map(os.path.join(path, "items.py"))
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
    def change_size(self, size):
        self.mapsize = size
        self.realrect_quadtree = QuadTree(self.gen_real_rect(self.mapsize), 0, 5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(Rect(0, 0, self.mapsize[0] * WIDTH, self.mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
    def delete_item(self, item):
        self.item_map.remove(item)
    def add_item(self, item):
        self.item_map.append(self.create_item(item))
    def create_item(self, info):
        item_info = self.items[info["type"]].copy()
        temp = item_info.copy()
        temp.update(info)
        temp.update({"item_info": item_info.copy()})
        return Item(self.screen, **temp)
    def refresh_realrect_quadtree(self):
        self.realrect_quadtree.clear()
        self.realrect_quadtree.particles = [j for i in self.layers for j in i] + self.charactermap + self.item_map
        self.realrect_quadtree.update()
    def refresh_floor_quadtree(self):
        self.floor_quadtree.clear()
        self.floor_quadtree.particles = self.triggers + self.rect_obstacles
        self.floor_quadtree.update()
    def delete_obs(self, **kwargs):
        obs = kwargs.get("obstacle", None)
        for index, layer in enumerate(self.layers):
            try:
                layer.remove(obs)
                break
            except:
                continue
    def delete_trigger(self, trigger):
        try:
            self.triggers.remove(trigger)
        except:
            pass
    def delete_character(self, identifier):
        try:
            self.characters.remove(character)
        except:
            pass
    def create_obstacle(self, **info):
        if info["type"] == "RECT":
            return BasicObstacle(self.screen, x=info["x"], y=info["y"], width=info.get("width", 1), height=info.get("height", 1), type="RECT")
        else:
            tile_dict = self.obstacles[int(info["type"])]
            if type(tile_dict["images"]) == list:
                tile_dict["images"] = tile_dict["images"][0]
            complete_info = tile_dict.copy()
            complete_info.update(info)
            return Obstacle(self.screen, **complete_info)
    def spawn_character(self, **kwargs):
        if kwargs.get("info", None):
            self.charactermap.append(self.create_character(kwargs["info"]))
        else:
            self.charactermap.append(Character(self.screen, x=kwargs.get("x", 0), y=kwargs.get("y", 0), name=kwargs["name"]))
    def load_obstaclemap(self, path):
        self.layers = []
        temp = load_module(path)
        for layer in temp.layers:
            self.layers.append([])
            for obs in layer:
                new = self.create_obstacle(**obs)
                if type(new) == BasicObstacle:
                    self.rect_obstacles.append(new)
                else:
                    self.layers[-1].append(new)
        self.refresh_floor_quadtree()
        self.refresh_realrect_quadtree()
    def load_charactermap(self, path):
        self.charactermap = []
        temp = load_module(path)
        for character in temp.characters:
            self.charactermap.append(self.create_character(character))
        self.refresh_realrect_quadtree()
    def load_triggermap(self, path):
        self.triggers = []
        temp = load_module(path)
        for trigger in temp.triggers:
            self.triggers.append(Trigger(self.screen, **trigger))
        self.refresh_floor_quadtree()
    def load_item_map(self, path):
        self.item_map = []
        temp = load_module(path)
        for item in temp.items:
            self.item_map.append(self.create_item(item))
        self.refresh_realrect_quadtree()
    def create_character(self, info):
        temp = self.characters[info["name"]].copy()
        temp.update(info)
        temp.update({"orig_info": self.characters[info["name"]].copy()})
        return Character(self.screen, obstaclemap=self, **temp)
    def set_entry_value(self, entry, value):
        entry.delete(0, "end")
        entry.insert(0, value)
    def click(self, mouse_pos, tile_pos, mode, current_obs, current_layer, current_item, current_character, current_tab, properties_frame):
        for thing in [j for i in self.layers for j in i] + self.charactermap + self.item_map + self.rect_obstacles + self.triggers:
            thing.deselect()
        self.selected = None
        if mode == 0:
            selected = self.realrect_quadtree.collidepoint(mouse_pos)
            selected1 = self.floor_quadtree.collidepoint((tile_pos[0] * WIDTH, tile_pos[1] * HEIGHT))
            if selected or selected1:
                self.selected = max(selected + selected1, key=lambda x: (x.x, x.y))
                self.selected.select()
        elif mode == 1:
            if current_tab == "Obstacles":
                new_obs = self.create_obstacle(type=current_obs, x=tile_pos[0], y=tile_pos[1], width=1, height=1)
                if type(new_obs) == BasicObstacle:
                    self.rect_obstacles.append(new_obs)
                else:
                    self.layers[current_layer].append(new_obs)
            elif current_tab == "Items":
                new_obs = self.create_item({"type": current_item, "x": tile_pos[0], "y": tile_pos[1]})
                self.item_map.append(new_obs)
            elif current_tab == "Characters":
                new_obs = self.create_character({"name": current_character, "x": tile_pos[0], "y": tile_pos[1]})
                self.charactermap.append(new_obs)
            elif current_tab == "Triggers":
                new_obs = Trigger(self.screen, x=tile_pos[0], y=tile_pos[1], width=1, height=1)
                self.triggers.append(new_obs)
            self.selected = new_obs
            new_obs.select()
            self.refresh_realrect_quadtree()
            self.refresh_floor_quadtree()
        self.create_properties_widget(properties_frame)
        if self.selected:
            return True
        else:
            return False
    def destroy_properties_widget(self):
        if self.properties_frame:
            self.properties_frame.destroy()
            self.properties_frame = None
            self.widgets = {}
    def create_properties_widget(self, parent):
        self.destroy_properties_widget()
        if self.selected:
            obs_type = type(self.selected)
            if obs_type == BasicObstacle:
                possible_options = ["x", "y", "width", "height", "identifier"]
            elif obs_type == Trigger:
                possible_options = ["x", "y", "width", "height", "deactivate_after_use", "active", "identifier", "trigger"]
            elif obs_type == Obstacle:
                possible_options = ["x", "y", "identifier", "action", "after_looting", "items", "animation", "label", "onclick"]
            elif obs_type == Character:
                possible_options = ["x", "y", "dead", "weapon", "label", "identifier", "aggression_distance", "direction", "health", "random_walk_area", "waypoints", "ondeath"]
            elif obs_type == Item:
                possible_options = ["x", "y", "label", "identifier"]
            self.properties_frame = ttk.Frame(parent)
            self.widgets = {}
            for index, option in enumerate(possible_options):
                if option in ["x", "y", "width", "height", "aggression_distance", "health"]:
                    if option in ["x", "width"]:
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=self.mapsize[0], increment=0.1)
                    elif option in ["y", "height"]:
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=self.mapsize[1], increment=0.1)
                    elif option == "aggression_distance":
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=self.map_diam, increment=0.1)
                    elif option == "health":
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=1000)
                    self.set_entry_value(self.widgets[option], getattr(self.selected, option))
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in ["action", "weapon", "label", "identifier", "direction", "animation", "after_looting", "items"]:
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    attr = getattr(self.selected, option)
                    if option == "items" and attr is not None:
                        attr = ";".join(attr)
                    if attr is None:
                        attr = ""
                    self.set_entry_value(self.widgets[option], attr)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in ["active", "deactivate_after_use", "dead"]:
                    variable = tk.IntVar()
                    variable.set(int(getattr(self.selected, option)))
                    self.widgets[option] = {"widget": ttk.Checkbutton(self.properties_frame, text=option, variable=variable), "variable": variable}
                    self.widgets[option]["widget"].grid(row=index, column=1, sticky="w")
                elif option in ["onclick", "trigger", "ondeath"]:
                    self.widgets[option] = [ttk.Combobox(self.properties_frame, values=("REPLACE", "DELETE", "ADD", "KILL", "KILLALL", "SPAWN", "OPEN", "CLOSE", "DEACTIVATE", "ACTIVATE", "WINGAME", "TRYWINGAME", "CHANGEMAP")), ttk.Combobox(self.properties_frame, values=("obstacle", "character", "item", "trigger")), ttk.Entry(self.properties_frame), ttk.Entry(self.properties_frame), ttk.Entry(self.properties_frame)]
                    for widget_index, widget in enumerate(self.widgets[option]):
                        try:
                            if type(widget) == ttk.Combobox:
                                widget.set(getattr(self.selected, option)[widget_index])
                            else:
                                self.set_entry_value(widget, getattr(self.selected, option)[widget_index])
                        except:
                            pass
                        widget.grid(row=index + widget_index, column=1, sticky="w")
                elif option == "waypoints":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(self.widgets[option], ";".join(",".join([str(y) for y in x]) for x in getattr(self.selected, option)))
                elif option == "random_walk_area":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(self.widgets[option], ";".join(str(x) for x in getattr(self.selected, option)))
                if option not in ["deactivate_after_use", "dead", "active"]:
                    ttk.Label(self.properties_frame, text=option).grid(row=index, column=0, sticky="w")
            self.properties_frame.grid(row=1, column=0, sticky="nswe")
    def mousedrag(self, mouse_pos, pos_change):
        if self.selected:
            self.set_attributes(x=self.selected.x + pos_change[0], y=self.selected.y + pos_change[1])
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
    def delete(self, *args):
        if self.selected:
            if type(self.selected) == Character:
                self.charactermap.remove(self.selected)
            elif type(self.selected) == Obstacle:
                try:
                    self.layers[0].remove(self.selected)
                except:
                    self.layers[1].remove(self.selected)
            elif type(self.selected) == Item:
                self.item_map.remove(self.selected)
            elif type(self.selected) == BasicObstacle:
                self.rect_obstacles.remove(self.selected)
            elif type(self.selected) == Trigger:
                self.triggers.remove(self.selected)
            self.selected = None
            self.refresh_floor_quadtree()
            self.refresh_realrect_quadtree()
    def set_attributes(self, **kwargs):
        if self.selected:
            if self.properties_frame:
                final_dict = {}
                for key, item in self.widgets.items():
                    if type(item) == dict:
                        value = bool(item["variable"].get())
                    elif type(item) == list:
                        value = []
                        for part in item:
                            temp_val = part.get()
                            if temp_val:
                                value.append(temp_val)
                    else:
                        value = item.get()
                        try:
                            if key in ["after_looting", "health"]:
                                value = int(value)
                            else:
                                value = float(value)
                        except:
                            pass
                    if key in ["x", "y", "width", "height"]:
                        try:
                            final_dict[key] = float(value)
                        except:
                            pass
                    elif key == "direction":
                        if value in ["NW", "N", "NE", "E", "W", "SW", "SE", "S"]:
                            final_dict[key] = value
                    elif key == "items":
                        if value:
                            value = [x.strip() for x in value.split(";")]
                            final_dict[key] = value
                    elif key == "waypoints":
                        try:
                            if value:
                                value = [[float(y) for y in x.split(",")] for x in value.split(";")]
                            for x in value:
                                if len(x) < 2:
                                    break
                            else:
                                final_dict[key] = value
                        except:
                            pass
                    elif key == "random_walk_area":
                        try:
                            if value:
                                value = [float(x) for x in value.split(";")]
                            if len(value) == 4 or not value:
                                final_dict[key] = value
                        except:
                            pass
                    else:
                        final_dict[key] = value
                final_dict.update(kwargs)
                self.selected.set_values(**final_dict)
                for key, item in kwargs.items():
                    if key in ["x", "y"]:
                        self.set_entry_value(self.widgets[key], item)
    def draw_cursor(self, tile_pos, current_obs, current_item, current_char,  current_tab, screen_offset):
        if current_tab == "Obstacles":
            temp = self.create_obstacle(type=current_obs, x=tile_pos[0], y=tile_pos[1])
        elif current_tab == "Items":
            temp = self.create_item({"type": current_item, "x": tile_pos[0], "y": tile_pos[1]})
        elif current_tab == "Characters":
            temp = self.create_character({"name": current_char, "x": tile_pos[0], "y": tile_pos[1]})
        elif current_tab == "Triggers":
            temp = Trigger(self.screen, x=tile_pos[0], y=tile_pos[1])
        temp.draw(screen_offset)
    def draw(self, screen_offset):
        self.set_attributes()
        final = sorted(self.layers[1] + self.charactermap, key=lambda x: (x.x, x.y))
        ground = sorted(self.layers[0] + self.triggers + self.rect_obstacles + self.item_map, key=lambda x: (x.x, x.y))
        for ground_obs in ground:
            ground_obs.draw(screen_offset)
        for thing in final:
            thing.draw(screen_offset)
Example #20
0
    def BuildMap(self, bounds: Box2D, obstacles: List[Obstacle]):
        self.sceneTree = QuadTree(bounds)
        self.bounds = bounds
        for ob in obstacles:
            self.sceneTree.AddElement(ob)

        xValues = []  #type:List[Tuple[int,bool,Obstacle]]

        xValues.append((bounds.GetMinX(), False, None))
        for ob in obstacles:
            xValues.append((ob.GetBounds().GetMinX(), True, ob))
            xValues.append((ob.GetBounds().GetMaxX(), False, ob))
        xValues.append((bounds.GetMaxX(), True, None))

        xValues.sort(key=lambda e: e[0])

        #leftEdges = [Edge(Point2D(bounds.GetMinX(),bounds.GetMinY()),Point2D(bounds.GetMinX(),bounds.GetMaxY()))]
        leftEdges = []  #type:List[Edge]

        rightEdges = []  #type:List[Tuple[Edge,bool]]
        for i in range(len(xValues) + 1):
            if i == len(xValues) or (i > 0
                                     and xValues[i - 1][0] != xValues[i][0]):
                if len(rightEdges) > 0:
                    x = xValues[i - 1][0]
                    # add non-existent edge to finish finding upper edge of new grid
                    rightEdges.append(
                        (Edge(Point2D(x,
                                      bounds.GetMaxY() + 1),
                              Point2D(x,
                                      bounds.GetMaxY() + 2)), True))
                    #sort
                    rightEdges.sort(key=lambda e: e[0].GetMinY())
                    # remove repeated edge
                    edgeNum = len(rightEdges)
                    idx = 1
                    while idx < edgeNum:
                        if rightEdges[idx][0] == rightEdges[idx - 1][0]:
                            del rightEdges[idx]
                            edgeNum -= 1
                            continue
                        idx += 1

                    #use right edges to close left edges and get grids
                    newGrid = Grid()
                    closedEdge = []

                    rIdx = 0
                    lIdx = 0
                    startY = rightEdges[rIdx][0].GetMinY()
                    endY = rightEdges[rIdx][0].GetMaxY()
                    bottomY = -1
                    upY = -1

                    #walk through edges from bottom to up
                    while rIdx < edgeNum - 1 and lIdx < len(leftEdges):
                        if leftEdges[lIdx].GetMaxY() <= startY:
                            # current right edge can not close this left edge,try next.
                            lIdx += 1
                            continue
                        if endY <= leftEdges[lIdx].GetMinY():
                            #no left edge can be closed by current right edge.
                            rIdx += 1
                            #update Y
                            startY = rightEdges[rIdx][0].GetMinY()
                            endY = rightEdges[rIdx][0].GetMaxY()
                            continue

                        if leftEdges[lIdx].GetMinY() <= startY:
                            if leftEdges[lIdx].GetMaxY() == endY:

                                newGrid.AddLeftEdge(leftEdges[lIdx])
                                newGrid.AddRightEdge(
                                    Edge(
                                        Point2D(x,
                                                rightEdges[rIdx][0].GetMinY()),
                                        Point2D(
                                            x, rightEdges[rIdx][0].GetMaxY())))
                                closedEdge.append(lIdx)

                                if bottomY == -1:
                                    bottomY = startY

                                if (rightEdges[rIdx][0].GetMaxY() <
                                        rightEdges[rIdx + 1][0].GetMinY()
                                        or lIdx == len(leftEdges)
                                        or leftEdges[lIdx].GetMaxY() <
                                        leftEdges[lIdx + 1].GetMinY()):
                                    #get new grid
                                    if upY == -1:
                                        upY = endY
                                        leftX = leftEdges[lIdx].GetMinX()
                                        rightX = x
                                        newGrid.SetBottomEdge(
                                            Edge(Point2D(leftX, bottomY),
                                                 Point2D(rightX, bottomY)))
                                        newGrid.SetUpperEdge(
                                            Edge(Point2D(leftX, upY),
                                                 Point2D(rightX, upY)))
                                        self.gridList.append(newGrid)
                                        # reset grid info to get next new grid
                                        newGrid = Grid()
                                        bottomY = -1
                                        upY = -1

                                lIdx += 1
                                rIdx += 1
                                #update Y
                                startY = rightEdges[rIdx][0].GetMinY()
                                endY = rightEdges[rIdx][0].GetMaxY()

                            elif leftEdges[lIdx].GetMaxY() < endY:

                                newGrid.AddLeftEdge(leftEdges[lIdx])
                                closedEdge.append(lIdx)

                                if bottomY == -1:
                                    bottomY = startY
                                #update Y
                                startY = leftEdges[lIdx].GetMaxY()
                                lIdx += 1

                            else:  #leftEdges[lIdx].GetMaxY() > endY:

                                newGrid.AddRightEdge(
                                    Edge(
                                        Point2D(x,
                                                rightEdges[rIdx][0].GetMinY()),
                                        Point2D(
                                            x, rightEdges[rIdx][0].GetMaxY())))

                                if bottomY == -1:
                                    bottomY = startY

                                if rightEdges[rIdx][0].GetMaxY() < rightEdges[
                                        rIdx + 1][0].GetMinY():
                                    #get new grid
                                    if upY == -1:
                                        upY = endY
                                        leftX = leftEdges[lIdx].GetMinX()
                                        rightX = x
                                        newGrid.SetBottomEdge(
                                            Edge(Point2D(leftX, bottomY),
                                                 Point2D(rightX, bottomY)))
                                        newGrid.SetUpperEdge(
                                            Edge(Point2D(leftX, upY),
                                                 Point2D(rightX, upY)))
                                        self.gridList.append(newGrid)
                                        # reset grid info to get next new grid
                                        newGrid = Grid()
                                        bottomY = -1
                                        upY = -1

                                rIdx += 1
                                #update Y
                                startY = rightEdges[rIdx][0].GetMinY()
                                endY = rightEdges[rIdx][0].GetMaxY()
                    closedEdge.sort(reverse=True)
                    for lIdx in closedEdge:
                        del leftEdges[lIdx]
                    #update leftEdge
                    for e in rightEdges:
                        if not e[1]:
                            leftEdges.append(e[0])
                    leftEdges.sort(key=lambda e: e.GetMinY())
                    rightEdges.clear()
                    yield leftEdges

            if i == len(xValues):
                continue

            x = xValues[i][0]
            bOpen = xValues[i][1]
            source = xValues[i][2]  #type:Obstacle

            if source != None:
                # middle edge
                start = Point2D(x, source.GetBounds().GetMinY())
                end = Point2D(x, source.GetBounds().GetMaxY())
                self._GetRightEdges(rightEdges, end, start, source, True,
                                    bOpen)
                # trace towards down
                start = Point2D(x, source.GetBounds().GetMinY())
                end = Point2D(x, bounds.GetMinY() - 1)
                self._GetRightEdges(rightEdges, end, start, source, False,
                                    False)
                # trace towards up
                start = Point2D(x, source.GetBounds().GetMaxY())
                end = Point2D(x, bounds.GetMaxY() + 1)
                self._GetRightEdges(rightEdges, end, start, source, False,
                                    False)
            else:
                start = Point2D(x, self.bounds.GetMinY())
                end = Point2D(x, self.bounds.GetMaxY())
                self._GetRightEdges(rightEdges, end, start, None, True, bOpen)