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 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 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
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 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 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 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 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 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()
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()
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()
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))
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:
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),
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
#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:
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)
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)
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)