コード例 #1
0
 def initialize_rivers(self):
     lm = self.lm
     img_fullsize = self.get_material_image("Shallow water")
     imgs = {}
     for dx in [-1,0,1]:
         for dy in[-1,0,1]:
             imgs = tm.build_tiles(img_fullsize, lm.cell_sizes,
                                             lm.nframes,
                                             dx*lm.nframes, dy*lm.nframes, #dx, dy
                                             sin=False)
             river_obj = MapObject(self, imgs[0], "river", 1.)
             river_obj.is_ground = True
             self.register_object_type(river_obj)
コード例 #2
0
def add_random_river(me, layer, material_dict,
                    imgs,
                    costs_materials, costs_objects,
                    possible_materials, possible_objects,
                    min_length, max_length):
    """Computes and draw a random river."""
    print("     Building random river...")
    lm = me.lm
    md = material_dict
    #1) pick one random end
    if "shallow water" in md:
        cell_end = random.choice(md["shallow water"])
    elif "grass" in md:
        cell_end = random.choice(md["grass"])
    elif "snow" in md:
        cell_end = random.choice(md["snow"])
    else:
        return
    #2) pick one random source
    if "snow" in md:
        cell_source = random.choice(md["snow"])
    elif "thin snow" in md:
        cell_source = random.choice(md["thin snow"])
    elif "rock" in md:
        cell_source = random.choice(md["rock"])
    else:
        return
    #3) verify distance
    cell_source = lm.cells[cell_source[0]][cell_source[1]]
    cell_end = lm.cells[cell_end[0]][cell_end[1]]
    if min_length <=  cell_source.distance_to(cell_end) <= max_length:
        pass
    else:
        return
    sp = BranchAndBoundForMap(lm, cell_source, cell_end,
                            costs_materials, costs_objects,
                            possible_materials, possible_objects)
    path = sp.solve()
    #4) change the end to first shallow shore cell
    actual_path = []
    for cell in path:
        if cell.name == "river":
            break
        actual_path.append(cell)
        if "water" in cell.material.name.lower():
            break
        else:
            next_to_water = False
            for neigh in cell.get_neighbors_von_neuman():
                if neigh:
                    if "water" in neigh.material.name.lower():
                        next_to_water = True
                        break
            if next_to_water:
                break
    #
    objs = {}
    for delta in imgs: #imgs[(dx,dy)][zoom]
        river_obj = MapObject(me, imgs[delta][0], "river", 1.)
        river_obj.is_ground = True
        objs[delta] = river_obj
    #5) add river cells to map and layer
    for i,cell in enumerate(actual_path):
        dx,dy = get_path_orientation(i, cell, actual_path)
        c = objs.get((dx,dy))
        if not c:
            raise Exception("No river object for delta", dx, dy)
        assert cell.name != "river"
        c = c.add_copy_on_cell(cell)
        cell.name = "river"
        layer.static_objects.append(c)
    if path:
        print("RIVER BUILT:", [cell.coord for cell in path])
    return objs
コード例 #3
0
    def add_static_objects(self, me):
        #1) We use another hmap to decide where we want trees (or any other object)
        S = len(me.hmap)
        self._forest_map = ng.generate_terrain(S, n_octaves=self.static_objects_n_octaves,
                                            persistance=self.static_objects_persistance,
                                            chunk=self.static_objects_chunk)
        ng.normalize(self._forest_map)
        #me.lm is a superimposed map on which we decide to blit some static objects:
        #3) We build the objects that we want.
        # its up to you to decide what should be the size of the object (3rd arg)
        tree = MapObject(me,self.tree,self.forest_text,self.tree_size)
        tree.max_relpos = [0., 0.]
        fir1 = MapObject(me,self.fir1,self.forest_text,self.fir1_size)
        fir1.max_relpos = [0., 0.]
        fir2 = MapObject(me,self.fir2,self.forest_text,self.fir2_size)
        fir2.max_relpos = [0., 0.]
        firsnow = MapObject(me,self.firsnow, self.forest_snow_text, self.firsnow_size)
        firsnow.max_relpos = [0., 0.]
        fir1.set_same_type([fir2, firsnow])
        palm = MapObject(me,self.palm,self.palm_text,self.palm_size)
        palm.max_relpos[0] = 0.1 #restrict because they are near to water
        palm.min_relpos[0] = -0.1
        bush = MapObject(me,self.bush,"bush",self.bush_size)
        village1 = MapObject(me,self.village1, "village",self.village1_size)
##        village2 = MapObject(me,self.village2, "village",self.village2_size)
##        village3 = MapObject(me,self.village3, "village",self.village3_size)
##        all_villages = [village1,village2,village3]
        all_villages = [village1]
        for v in all_villages:
            v.max_relpos = [0, 0.15]
            v.min_relpos = [0, 0.1]
        #
        cobble = MapObject(me,self.cobble,"cobblestone",self.cobble_size)
        cobble.is_ground = True
        self.cobblestone = cobble
        bridge_h = MapObject(me,self.bridge_h,"bridge",self.bridge_h_size,
                                str_type="bridge_h")
        bridge_h.is_ground = True
        bridge_h.max_relpos = [0., 0.]
        bridge_h.min_relpos = [0., 0.]
        bridge_v = MapObject(me,self.bridge_v,"bridge",self.bridge_v_size,
                                str_type="bridge_v")
        bridge_v.is_ground = True
        bridge_v.max_relpos = [0.,0.]
        bridge_v.min_relpos = [0., 0.]
        self.bridge_h_mapobject = bridge_h
        self.bridge_v_mapobject = bridge_v
        self._objects = {"oak":tree, "fir1":fir1, "fir2":fir2, "firsnow":firsnow,
                        "palm":palm, "bush":bush, "village":village1,
                        "cobble":cobble, "bridge_h":bridge_h, "bridge_v":bridge_v,
                        "road":cobble}
        #4) we add the objects via distributors, to add them randomly in a nice way
        #normal forest
##        print("LALA 1", tree.relpos, tree.max_relpos, tree.min_relpos)
        all_forest = [fir1, fir2, tree]
        distributor = objs.get_distributor(me, all_forest,
                                            self._forest_map, ["Grass","Rock"])
##        print("LALA 2", tree.relpos, tree.max_relpos, tree.min_relpos)
        for obj in distributor.objs:
            obj.max_relpos[1] *= self.forest_relposy_multiplier
##        print("LALA 3", tree.relpos, tree.max_relpos, tree.min_relpos)
##        tree.max_relpos = [0., -0.25] #!!!!!!!!!!!!!!!!!
##        tree.max_relpos = list(tree.min_relpos)
##        tree.randomize_relpos()
        distributor.max_density = self.forest_max_density
        distributor.homogeneity = self.forest_homogeneity
        distributor.zones_spread = self.forest_zones_spread
        distributor.distribute_objects(me.lm, exclusive=True) #here, relpos is randomized for each object distributed
        #more trees in plains
        distributor = objs.get_distributor(me, [tree], self._forest_map, ["Grass"])
        for obj in distributor.objs:
            obj.max_relpos[1] *= self.forest_relposy_multiplier
        distributor.max_density = self.forest_max_density
        distributor.homogeneity = self.forest_homogeneity
        distributor.zones_spread = self.forest_zones_spread
        distributor.distribute_objects(me.lm, exclusive=True)
        #snow forest
        distributor = objs.get_distributor(me, [firsnow, firsnow.flip()],
                                        self._forest_map, ["Thin snow","Snow"])
        for obj in distributor.objs:
            obj.max_relpos[1] *= self.forest_relposy_multiplier
        distributor.max_density = self.forest_snow_max_density
        distributor.homogeneity = self.forest_snow_homogeneity
        distributor.zones_spread = self.forest_snow_zones_spread
        distributor.distribute_objects(me.lm, exclusive=True)
        #palm forest
        distributor = objs.get_distributor(me, [palm, palm.flip()], self._forest_map, ["Sand"])
        for obj in distributor.objs:
            obj.max_relpos[1] *= self.forest_relposy_multiplier
        distributor.max_density = self.palm_max_density
        distributor.homogeneity = self.palm_homogeneity
        distributor.zones_spread = self.palm_zones_spread
        distributor.distribute_objects(me.lm, exclusive=True)
        #bushes
        distributor = objs.get_distributor(me, [bush], self._forest_map, ["Grass"])
        distributor.max_density = 2
        distributor.homogeneity = 0.2
        distributor.zones_spread = [(0., 0.05), (0.3,0.05), (0.6,0.05)]
        distributor.distribute_objects(me.lm)
        #villages
        distributor = objs.get_distributor(me, [village1, village1.flip()],
                            self._forest_map, ["Grass"], limit_relpos_y=False)
        distributor.max_density = 1
        distributor.homogeneity = self.village_homogeneity
        distributor.zones_spread = [(0.1, 0.02), (0.2,0.02), (0.4,0.02), (0.5,0.02)]
##        distributor.distribute_objects(me.lm, exclusive=True)
        village_mat = list(me.materials.keys())
        village_mat = [n for n in village_mat if not("water" in n.lower())]
        village_mat.remove("outside")
        objs.simple_distribution(me, [village1, village1.flip()], village_mat, 6)
        cobbles = [cobble, cobble.flip(True,False),
                    cobble.flip(False,True), cobble.flip(True,True)]
        ############################################################################
        #Here we show how to use the path finder for a given unit of the game
        #Actually, we use it here in order to build cobblestone roads on the map
        me.initialize_rivers()
        costs_materials_road = {name:1. for name in me.materials}
        costs_materials_road["Snow"] = 10. #unit is 10 times slower in snow
        costs_materials_road["Thin snow"] = 2. #twice slower on thin snow...
        costs_materials_road["Sand"] = 2.
##        for name in me.materials:
##            if "water" in name.lower():
##                costs_materials_road[name] = 10
        print("     COST SHALLOW WATER", costs_materials_road)
        river_type = me.object_types["river"]
        costs_objects_road = {bush.int_type: 2., #unit is 2 times slower in bushes
                                cobble.int_type: 0.9,
                                river_type:2.}
        #Materials allowed (here we allow water because we add bridges)
        possible_materials_road=list(me.materials)
        for name in me.materials:
            if "water" in name.lower():
                possible_materials_road.remove(name)
        possible_objects_road=[cobble.int_type, bush.int_type,
                                village1.int_type, river_type]
        ########################################################################
        #now we build a path for rivers, just like we did with roads.
        costs_materials_river = {name:1. for name in me.materials}
        #Materials allowed (here we allow water because we add bridges)
        possible_materials_river=list(me.materials)
        possible_objects_river=[]
        river_img = me.get_material_image("Shallow water")
        random.seed(self.seed_static_objects)
        n_roads = 0
        n_rivers = 0
        imgs_river = {}
        lm = me.lm
        for dx in [-1,0,1]:
            for dy in[-1,0,1]:
                imgs_river[(dx,dy)] = tm.build_tiles(river_img, lm.cell_sizes,
                                            lm.nframes,
                                            dx*lm.nframes, dy*lm.nframes, #dx, dy
                                            sin=False)
        self.imgs_river = imgs_river
        material_dict = get_materials_dict(lm)
        self.update_loading_bar("Finding paths for rivers and roads...",0.6)
        while n_roads < self.max_number_of_roads or n_rivers < self.max_number_of_rivers:
            if n_rivers < self.max_number_of_rivers:
                n_rivers += 1
                self.rivers = add_random_river(me, me.lm, material_dict, imgs_river,
                                    costs_materials_river,
                                    costs_objects_road,
                                    possible_materials_river,
                                    possible_objects_river,
                                    min_length=self.min_river_length,
                                    max_length=self.max_river_length)
            if n_roads < self.max_number_of_roads:
                n_roads += 1
                add_random_road(me.lm, me.lm, cobbles,
                                    (bridge_h,bridge_v),
                                    costs_materials_road,
                                    costs_objects_road,
                                    possible_materials_road,
                                    possible_objects_road,
                                    min_length=self.min_road_length,
                                    max_length=self.max_road_length)