└── Demo ├── assets ├── fonts │ ├── vonwaon_bitmap-12px.ttf │ └── vonwaon_bitmap-12px.ttf.import └── tileset │ ├── grass.png │ ├── grass.png.import │ ├── grassland1.png │ ├── grassland1.png.import │ ├── tile_set.tres │ ├── tree1.png │ ├── tree1.png.import │ ├── tree2.png │ ├── tree2.png.import │ ├── water_and_soil.png │ └── water_and_soil.png.import ├── icon.svg ├── icon.svg.import ├── project.godot ├── scenes ├── block_node.gd ├── block_node.tscn ├── demo_scene.gd ├── demo_scene.tscn ├── player.gd └── player.tscn ├── scripts ├── simple_terrain_system.gd └── terrain_tile.gd └── shaders └── grass.gdshader /Demo/assets/fonts/vonwaon_bitmap-12px.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/C-Wenge/TerrainDemo/b8939a45e99fa6f5b27e4d0b0a9c109cb1e81c83/Demo/assets/fonts/vonwaon_bitmap-12px.ttf -------------------------------------------------------------------------------- /Demo/assets/fonts/vonwaon_bitmap-12px.ttf.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_dynamic" 4 | type="FontFile" 5 | uid="uid://3nm64q3y2x5h" 6 | path="res://.godot/imported/vonwaon_bitmap-12px.ttf-a36088d64cd457fda9d8056e3a0e9cf6.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://assets/fonts/vonwaon_bitmap-12px.ttf" 11 | dest_files=["res://.godot/imported/vonwaon_bitmap-12px.ttf-a36088d64cd457fda9d8056e3a0e9cf6.fontdata"] 12 | 13 | [params] 14 | 15 | Rendering=null 16 | antialiasing=0 17 | generate_mipmaps=false 18 | multichannel_signed_distance_field=true 19 | msdf_pixel_range=8 20 | msdf_size=48 21 | allow_system_fallback=true 22 | force_autohinter=false 23 | hinting=1 24 | subpixel_positioning=1 25 | oversampling=0.0 26 | Fallbacks=null 27 | fallbacks=[] 28 | Compress=null 29 | compress=true 30 | preload=[{ 31 | "chars": [], 32 | "glyphs": [], 33 | "name": "新建配置", 34 | "size": Vector2i(16, 0) 35 | }] 36 | language_support={} 37 | script_support={} 38 | opentype_features={} 39 | -------------------------------------------------------------------------------- /Demo/assets/tileset/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/C-Wenge/TerrainDemo/b8939a45e99fa6f5b27e4d0b0a9c109cb1e81c83/Demo/assets/tileset/grass.png -------------------------------------------------------------------------------- /Demo/assets/tileset/grass.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c5w76yalor1m7" 6 | path="res://.godot/imported/grass.png-355e53ad8482e8f903f80acd13964c27.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://assets/tileset/grass.png" 14 | dest_files=["res://.godot/imported/grass.png-355e53ad8482e8f903f80acd13964c27.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Demo/assets/tileset/grassland1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/C-Wenge/TerrainDemo/b8939a45e99fa6f5b27e4d0b0a9c109cb1e81c83/Demo/assets/tileset/grassland1.png -------------------------------------------------------------------------------- /Demo/assets/tileset/grassland1.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cdxspll1kcm06" 6 | path="res://.godot/imported/grassland1.png-54d3b8444d507b9ed32b4f8b6dabcc03.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://assets/tileset/grassland1.png" 14 | dest_files=["res://.godot/imported/grassland1.png-54d3b8444d507b9ed32b4f8b6dabcc03.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Demo/assets/tileset/tile_set.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="TileSet" load_steps=17 format=3 uid="uid://2pc3ylacfkgq"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://df0vhe6cu1cim" path="res://assets/tileset/water_and_soil.png" id="1_k2ea7"] 4 | [ext_resource type="Texture2D" uid="uid://c5w76yalor1m7" path="res://assets/tileset/grass.png" id="2_ejj0s"] 5 | [ext_resource type="Shader" path="res://shaders/grass.gdshader" id="2_ollag"] 6 | [ext_resource type="Texture2D" uid="uid://cdxspll1kcm06" path="res://assets/tileset/grassland1.png" id="3_uj5n4"] 7 | [ext_resource type="Texture2D" uid="uid://bekpixqdyfpwx" path="res://assets/tileset/tree1.png" id="5_hojho"] 8 | [ext_resource type="Texture2D" uid="uid://c8b8dw3ustgn6" path="res://assets/tileset/tree2.png" id="6_05526"] 9 | 10 | [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_756qy"] 11 | texture = ExtResource("1_k2ea7") 12 | 0:0/0 = 0 13 | 1:0/0 = 0 14 | 1:0/0/terrain_set = 0 15 | 1:0/0/terrain = 0 16 | 1:0/0/terrains_peering_bit/right_side = 0 17 | 1:0/0/terrains_peering_bit/bottom_right_corner = 0 18 | 1:0/0/terrains_peering_bit/bottom_side = 0 19 | 2:0/0 = 0 20 | 2:0/0/terrain_set = 0 21 | 2:0/0/terrain = 0 22 | 2:0/0/terrains_peering_bit/right_side = 0 23 | 2:0/0/terrains_peering_bit/bottom_right_corner = 0 24 | 2:0/0/terrains_peering_bit/bottom_side = 0 25 | 2:0/0/terrains_peering_bit/bottom_left_corner = 0 26 | 2:0/0/terrains_peering_bit/left_side = 0 27 | 3:0/0 = 0 28 | 3:0/0/terrain_set = 0 29 | 3:0/0/terrain = 0 30 | 3:0/0/terrains_peering_bit/bottom_side = 0 31 | 3:0/0/terrains_peering_bit/bottom_left_corner = 0 32 | 3:0/0/terrains_peering_bit/left_side = 0 33 | 4:0/0 = 0 34 | 4:0/0/terrain_set = 0 35 | 4:0/0/terrain = 0 36 | 4:0/0/terrains_peering_bit/bottom_side = 0 37 | 5:0/0 = 0 38 | 5:0/0/terrain_set = 0 39 | 5:0/0/terrain = 0 40 | 5:0/0/terrains_peering_bit/right_side = 0 41 | 5:0/0/terrains_peering_bit/bottom_side = 0 42 | 6:0/0 = 0 43 | 6:0/0/terrain_set = 0 44 | 6:0/0/terrain = 0 45 | 6:0/0/terrains_peering_bit/right_side = 0 46 | 6:0/0/terrains_peering_bit/bottom_side = 0 47 | 6:0/0/terrains_peering_bit/bottom_left_corner = 0 48 | 6:0/0/terrains_peering_bit/left_side = 0 49 | 7:0/0 = 0 50 | 7:0/0/terrain_set = 0 51 | 7:0/0/terrain = 0 52 | 7:0/0/terrains_peering_bit/right_side = 0 53 | 7:0/0/terrains_peering_bit/bottom_right_corner = 0 54 | 7:0/0/terrains_peering_bit/bottom_side = 0 55 | 7:0/0/terrains_peering_bit/left_side = 0 56 | 8:0/0 = 0 57 | 8:0/0/terrain_set = 0 58 | 8:0/0/terrain = 0 59 | 8:0/0/terrains_peering_bit/bottom_side = 0 60 | 8:0/0/terrains_peering_bit/left_side = 0 61 | 9:0/0 = 0 62 | 9:0/0/terrain_set = 0 63 | 9:0/0/terrain = 0 64 | 9:0/0/terrains_peering_bit/right_side = 0 65 | 9:0/0/terrains_peering_bit/bottom_side = 0 66 | 9:0/0/terrains_peering_bit/left_side = 0 67 | 10:0/0 = 0 68 | 10:0/0/terrain_set = 0 69 | 10:0/0/terrain = 0 70 | 10:0/0/terrains_peering_bit/right_side = 0 71 | 10:0/0/terrains_peering_bit/bottom_right_corner = 0 72 | 10:0/0/terrains_peering_bit/bottom_side = 0 73 | 10:0/0/terrains_peering_bit/left_side = 0 74 | 10:0/0/terrains_peering_bit/top_left_corner = 0 75 | 10:0/0/terrains_peering_bit/top_side = 0 76 | 1:1/0 = 0 77 | 1:1/0/terrain_set = 0 78 | 1:1/0/terrain = 0 79 | 1:1/0/terrains_peering_bit/right_side = 0 80 | 1:1/0/terrains_peering_bit/bottom_right_corner = 0 81 | 1:1/0/terrains_peering_bit/bottom_side = 0 82 | 1:1/0/terrains_peering_bit/top_side = 0 83 | 1:1/0/terrains_peering_bit/top_right_corner = 0 84 | 2:1/0 = 0 85 | 2:1/0/terrain_set = 0 86 | 2:1/0/terrain = 0 87 | 2:1/0/terrains_peering_bit/right_side = 0 88 | 2:1/0/terrains_peering_bit/bottom_right_corner = 0 89 | 2:1/0/terrains_peering_bit/bottom_side = 0 90 | 2:1/0/terrains_peering_bit/bottom_left_corner = 0 91 | 2:1/0/terrains_peering_bit/left_side = 0 92 | 2:1/0/terrains_peering_bit/top_left_corner = 0 93 | 2:1/0/terrains_peering_bit/top_side = 0 94 | 2:1/0/terrains_peering_bit/top_right_corner = 0 95 | 3:1/0 = 0 96 | 3:1/0/terrain_set = 0 97 | 3:1/0/terrain = 0 98 | 3:1/0/terrains_peering_bit/bottom_side = 0 99 | 3:1/0/terrains_peering_bit/bottom_left_corner = 0 100 | 3:1/0/terrains_peering_bit/left_side = 0 101 | 3:1/0/terrains_peering_bit/top_left_corner = 0 102 | 3:1/0/terrains_peering_bit/top_side = 0 103 | 4:1/0 = 0 104 | 4:1/0/terrain_set = 0 105 | 4:1/0/terrain = 0 106 | 4:1/0/terrains_peering_bit/bottom_side = 0 107 | 4:1/0/terrains_peering_bit/top_side = 0 108 | 5:1/0 = 0 109 | 5:1/0/terrain_set = 0 110 | 5:1/0/terrain = 0 111 | 5:1/0/terrains_peering_bit/right_side = 0 112 | 5:1/0/terrains_peering_bit/bottom_side = 0 113 | 5:1/0/terrains_peering_bit/top_side = 0 114 | 5:1/0/terrains_peering_bit/top_right_corner = 0 115 | 6:1/0 = 0 116 | 6:1/0/terrain_set = 0 117 | 6:1/0/terrain = 0 118 | 6:1/0/terrains_peering_bit/right_side = 0 119 | 6:1/0/terrains_peering_bit/bottom_side = 0 120 | 6:1/0/terrains_peering_bit/bottom_left_corner = 0 121 | 6:1/0/terrains_peering_bit/left_side = 0 122 | 6:1/0/terrains_peering_bit/top_left_corner = 0 123 | 6:1/0/terrains_peering_bit/top_side = 0 124 | 6:1/0/terrains_peering_bit/top_right_corner = 0 125 | 7:1/0 = 0 126 | 7:1/0/terrain_set = 0 127 | 7:1/0/terrain = 0 128 | 7:1/0/terrains_peering_bit/right_side = 0 129 | 7:1/0/terrains_peering_bit/bottom_right_corner = 0 130 | 7:1/0/terrains_peering_bit/bottom_side = 0 131 | 7:1/0/terrains_peering_bit/left_side = 0 132 | 7:1/0/terrains_peering_bit/top_left_corner = 0 133 | 7:1/0/terrains_peering_bit/top_side = 0 134 | 7:1/0/terrains_peering_bit/top_right_corner = 0 135 | 8:1/0 = 0 136 | 8:1/0/terrain_set = 0 137 | 8:1/0/terrain = 0 138 | 8:1/0/terrains_peering_bit/bottom_side = 0 139 | 8:1/0/terrains_peering_bit/left_side = 0 140 | 8:1/0/terrains_peering_bit/top_left_corner = 0 141 | 8:1/0/terrains_peering_bit/top_side = 0 142 | 9:1/0 = 0 143 | 9:1/0/terrain_set = 0 144 | 9:1/0/terrain = 0 145 | 9:1/0/terrains_peering_bit/right_side = 0 146 | 9:1/0/terrains_peering_bit/bottom_side = 0 147 | 9:1/0/terrains_peering_bit/left_side = 0 148 | 9:1/0/terrains_peering_bit/top_left_corner = 0 149 | 9:1/0/terrains_peering_bit/top_side = 0 150 | 9:1/0/terrains_peering_bit/top_right_corner = 0 151 | 10:1/0 = 0 152 | 10:1/0/terrain_set = 0 153 | 10:1/0/terrain = 0 154 | 10:1/0/terrains_peering_bit/right_side = 0 155 | 10:1/0/terrains_peering_bit/bottom_side = 0 156 | 10:1/0/terrains_peering_bit/bottom_left_corner = 0 157 | 10:1/0/terrains_peering_bit/left_side = 0 158 | 10:1/0/terrains_peering_bit/top_side = 0 159 | 10:1/0/terrains_peering_bit/top_right_corner = 0 160 | 1:2/0 = 0 161 | 1:2/0/terrain_set = 0 162 | 1:2/0/terrain = 0 163 | 1:2/0/terrains_peering_bit/right_side = 0 164 | 1:2/0/terrains_peering_bit/top_side = 0 165 | 1:2/0/terrains_peering_bit/top_right_corner = 0 166 | 2:2/0 = 0 167 | 2:2/0/terrain_set = 0 168 | 2:2/0/terrain = 0 169 | 2:2/0/terrains_peering_bit/right_side = 0 170 | 2:2/0/terrains_peering_bit/left_side = 0 171 | 2:2/0/terrains_peering_bit/top_left_corner = 0 172 | 2:2/0/terrains_peering_bit/top_side = 0 173 | 2:2/0/terrains_peering_bit/top_right_corner = 0 174 | 3:2/0 = 0 175 | 3:2/0/terrain_set = 0 176 | 3:2/0/terrain = 0 177 | 3:2/0/terrains_peering_bit/left_side = 0 178 | 3:2/0/terrains_peering_bit/top_left_corner = 0 179 | 3:2/0/terrains_peering_bit/top_side = 0 180 | 4:2/0 = 0 181 | 4:2/0/terrain_set = 0 182 | 4:2/0/terrain = 0 183 | 4:2/0/terrains_peering_bit/top_side = 0 184 | 5:2/0 = 0 185 | 5:2/0/terrain_set = 0 186 | 5:2/0/terrain = 0 187 | 5:2/0/terrains_peering_bit/right_side = 0 188 | 5:2/0/terrains_peering_bit/bottom_right_corner = 0 189 | 5:2/0/terrains_peering_bit/bottom_side = 0 190 | 5:2/0/terrains_peering_bit/top_side = 0 191 | 6:2/0 = 0 192 | 6:2/0/terrain_set = 0 193 | 6:2/0/terrain = 0 194 | 6:2/0/terrains_peering_bit/right_side = 0 195 | 6:2/0/terrains_peering_bit/bottom_right_corner = 0 196 | 6:2/0/terrains_peering_bit/bottom_side = 0 197 | 6:2/0/terrains_peering_bit/bottom_left_corner = 0 198 | 6:2/0/terrains_peering_bit/left_side = 0 199 | 6:2/0/terrains_peering_bit/top_left_corner = 0 200 | 6:2/0/terrains_peering_bit/top_side = 0 201 | 7:2/0 = 0 202 | 7:2/0/terrain_set = 0 203 | 7:2/0/terrain = 0 204 | 7:2/0/terrains_peering_bit/right_side = 0 205 | 7:2/0/terrains_peering_bit/bottom_right_corner = 0 206 | 7:2/0/terrains_peering_bit/bottom_side = 0 207 | 7:2/0/terrains_peering_bit/bottom_left_corner = 0 208 | 7:2/0/terrains_peering_bit/left_side = 0 209 | 7:2/0/terrains_peering_bit/top_side = 0 210 | 7:2/0/terrains_peering_bit/top_right_corner = 0 211 | 8:2/0 = 0 212 | 8:2/0/terrain_set = 0 213 | 8:2/0/terrain = 0 214 | 8:2/0/terrains_peering_bit/bottom_side = 0 215 | 8:2/0/terrains_peering_bit/bottom_left_corner = 0 216 | 8:2/0/terrains_peering_bit/left_side = 0 217 | 8:2/0/terrains_peering_bit/top_side = 0 218 | 9:2/0 = 0 219 | 9:2/0/terrain_set = 0 220 | 9:2/0/terrain = 0 221 | 9:2/0/terrains_peering_bit/right_side = 0 222 | 9:2/0/terrains_peering_bit/bottom_right_corner = 0 223 | 9:2/0/terrains_peering_bit/bottom_side = 0 224 | 9:2/0/terrains_peering_bit/bottom_left_corner = 0 225 | 9:2/0/terrains_peering_bit/left_side = 0 226 | 9:2/0/terrains_peering_bit/top_side = 0 227 | 10:2/0 = 0 228 | 10:2/0/terrain_set = 0 229 | 10:2/0/terrain = 0 230 | 10:2/0/terrains_peering_bit/right_side = 0 231 | 10:2/0/terrains_peering_bit/bottom_right_corner = 0 232 | 10:2/0/terrains_peering_bit/bottom_side = 0 233 | 10:2/0/terrains_peering_bit/left_side = 0 234 | 10:2/0/terrains_peering_bit/top_side = 0 235 | 11:2/0 = 0 236 | 11:2/0/terrain_set = 0 237 | 11:2/0/terrain = 0 238 | 11:2/0/terrains_peering_bit/right_side = 0 239 | 11:2/0/terrains_peering_bit/bottom_side = 0 240 | 11:2/0/terrains_peering_bit/bottom_left_corner = 0 241 | 11:2/0/terrains_peering_bit/left_side = 0 242 | 11:2/0/terrains_peering_bit/top_side = 0 243 | 1:3/0 = 0 244 | 1:3/0/terrain_set = 0 245 | 1:3/0/terrain = 0 246 | 1:3/0/terrains_peering_bit/right_side = 0 247 | 2:3/0 = 0 248 | 2:3/0/terrain_set = 0 249 | 2:3/0/terrain = 0 250 | 2:3/0/terrains_peering_bit/right_side = 0 251 | 2:3/0/terrains_peering_bit/left_side = 0 252 | 3:3/0 = 0 253 | 3:3/0/terrain_set = 0 254 | 3:3/0/terrain = 0 255 | 3:3/0/terrains_peering_bit/left_side = 0 256 | 4:3/0 = 0 257 | 4:3/0/terrain_set = 0 258 | 4:3/0/terrain = 0 259 | 5:3/0 = 0 260 | 5:3/0/terrain_set = 0 261 | 5:3/0/terrain = 0 262 | 5:3/0/terrains_peering_bit/right_side = 0 263 | 5:3/0/terrains_peering_bit/top_side = 0 264 | 6:3/0 = 0 265 | 6:3/0/terrain_set = 0 266 | 6:3/0/terrain = 0 267 | 6:3/0/terrains_peering_bit/right_side = 0 268 | 6:3/0/terrains_peering_bit/left_side = 0 269 | 6:3/0/terrains_peering_bit/top_left_corner = 0 270 | 6:3/0/terrains_peering_bit/top_side = 0 271 | 7:3/0 = 0 272 | 7:3/0/terrain_set = 0 273 | 7:3/0/terrain = 0 274 | 7:3/0/terrains_peering_bit/right_side = 0 275 | 7:3/0/terrains_peering_bit/left_side = 0 276 | 7:3/0/terrains_peering_bit/top_side = 0 277 | 7:3/0/terrains_peering_bit/top_right_corner = 0 278 | 8:3/0 = 0 279 | 8:3/0/terrain_set = 0 280 | 8:3/0/terrain = 0 281 | 8:3/0/terrains_peering_bit/left_side = 0 282 | 8:3/0/terrains_peering_bit/top_side = 0 283 | 9:3/0 = 0 284 | 9:3/0/terrain_set = 0 285 | 9:3/0/terrain = 0 286 | 9:3/0/terrains_peering_bit/right_side = 0 287 | 9:3/0/terrains_peering_bit/left_side = 0 288 | 9:3/0/terrains_peering_bit/top_side = 0 289 | 10:3/0 = 0 290 | 10:3/0/terrain_set = 0 291 | 10:3/0/terrain = 0 292 | 10:3/0/terrains_peering_bit/right_side = 0 293 | 10:3/0/terrains_peering_bit/bottom_side = 0 294 | 10:3/0/terrains_peering_bit/left_side = 0 295 | 10:3/0/terrains_peering_bit/top_side = 0 296 | 10:3/0/terrains_peering_bit/top_right_corner = 0 297 | 11:3/0 = 0 298 | 11:3/0/terrain_set = 0 299 | 11:3/0/terrain = 0 300 | 11:3/0/terrains_peering_bit/right_side = 0 301 | 11:3/0/terrains_peering_bit/bottom_side = 0 302 | 11:3/0/terrains_peering_bit/left_side = 0 303 | 11:3/0/terrains_peering_bit/top_left_corner = 0 304 | 11:3/0/terrains_peering_bit/top_side = 0 305 | 5:4/0 = 0 306 | 5:4/0/terrain_set = 0 307 | 5:4/0/terrain = 0 308 | 5:4/0/terrains_peering_bit/right_side = 0 309 | 5:4/0/terrains_peering_bit/bottom_side = 0 310 | 5:4/0/terrains_peering_bit/top_side = 0 311 | 6:4/0 = 0 312 | 6:4/0/terrain_set = 0 313 | 6:4/0/terrain = 0 314 | 6:4/0/terrains_peering_bit/right_side = 0 315 | 6:4/0/terrains_peering_bit/bottom_side = 0 316 | 6:4/0/terrains_peering_bit/bottom_left_corner = 0 317 | 6:4/0/terrains_peering_bit/left_side = 0 318 | 6:4/0/terrains_peering_bit/top_left_corner = 0 319 | 6:4/0/terrains_peering_bit/top_side = 0 320 | 7:4/0 = 0 321 | 7:4/0/terrain_set = 0 322 | 7:4/0/terrain = 0 323 | 7:4/0/terrains_peering_bit/right_side = 0 324 | 7:4/0/terrains_peering_bit/bottom_right_corner = 0 325 | 7:4/0/terrains_peering_bit/bottom_side = 0 326 | 7:4/0/terrains_peering_bit/left_side = 0 327 | 7:4/0/terrains_peering_bit/top_side = 0 328 | 7:4/0/terrains_peering_bit/top_right_corner = 0 329 | 8:4/0 = 0 330 | 8:4/0/terrain_set = 0 331 | 8:4/0/terrain = 0 332 | 8:4/0/terrains_peering_bit/bottom_side = 0 333 | 8:4/0/terrains_peering_bit/left_side = 0 334 | 8:4/0/terrains_peering_bit/top_side = 0 335 | 9:4/0 = 0 336 | 9:4/0/terrain_set = 0 337 | 9:4/0/terrain = 0 338 | 9:4/0/terrains_peering_bit/right_side = 0 339 | 9:4/0/terrains_peering_bit/bottom_side = 0 340 | 9:4/0/terrains_peering_bit/left_side = 0 341 | 9:4/0/terrains_peering_bit/top_side = 0 342 | 343 | [sub_resource type="ShaderMaterial" id="ShaderMaterial_0dlfh"] 344 | shader = ExtResource("2_ollag") 345 | shader_parameter/y_start = 0.8 346 | shader_parameter/speed = 2.0 347 | shader_parameter/range = 1.0 348 | 349 | [sub_resource type="ShaderMaterial" id="ShaderMaterial_e7fgx"] 350 | shader = ExtResource("2_ollag") 351 | shader_parameter/y_start = 0.8 352 | shader_parameter/speed = 1.5 353 | shader_parameter/range = 1.3 354 | 355 | [sub_resource type="ShaderMaterial" id="ShaderMaterial_d4u5r"] 356 | shader = ExtResource("2_ollag") 357 | shader_parameter/y_start = 0.6 358 | shader_parameter/speed = 2.4 359 | shader_parameter/range = 2.0 360 | 361 | [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_uvbis"] 362 | texture = ExtResource("2_ejj0s") 363 | 0:0/0 = 0 364 | 0:0/0/material = SubResource("ShaderMaterial_0dlfh") 365 | 0:0/0/y_sort_origin = 6 366 | 1:0/0 = 0 367 | 1:0/0/material = SubResource("ShaderMaterial_e7fgx") 368 | 1:0/0/y_sort_origin = 7 369 | 2:0/size_in_atlas = Vector2i(1, 2) 370 | 2:0/0 = 0 371 | 2:0/0/material = SubResource("ShaderMaterial_d4u5r") 372 | 2:0/0/y_sort_origin = 14 373 | 374 | [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_nopne"] 375 | texture = ExtResource("3_uj5n4") 376 | 0:0/0 = 0 377 | 0:0/0/terrain_set = 0 378 | 0:0/0/terrain = 1 379 | 0:0/0/terrains_peering_bit/right_side = 1 380 | 0:0/0/terrains_peering_bit/bottom_right_corner = 1 381 | 0:0/0/terrains_peering_bit/bottom_side = 1 382 | 1:0/0 = 0 383 | 1:0/0/terrain_set = 0 384 | 1:0/0/terrain = 1 385 | 1:0/0/terrains_peering_bit/right_side = 1 386 | 1:0/0/terrains_peering_bit/bottom_right_corner = 1 387 | 1:0/0/terrains_peering_bit/bottom_side = 1 388 | 1:0/0/terrains_peering_bit/bottom_left_corner = 1 389 | 1:0/0/terrains_peering_bit/left_side = 1 390 | 2:0/0 = 0 391 | 2:0/0/terrain_set = 0 392 | 2:0/0/terrain = 1 393 | 2:0/0/terrains_peering_bit/bottom_side = 1 394 | 2:0/0/terrains_peering_bit/bottom_left_corner = 1 395 | 2:0/0/terrains_peering_bit/left_side = 1 396 | 3:0/0 = 0 397 | 3:0/0/terrain_set = 0 398 | 3:0/0/terrain = 1 399 | 3:0/0/terrains_peering_bit/bottom_side = 1 400 | 4:0/0 = 0 401 | 4:0/0/terrain_set = 0 402 | 4:0/0/terrain = 1 403 | 4:0/0/terrains_peering_bit/right_side = 1 404 | 4:0/0/terrains_peering_bit/bottom_side = 1 405 | 5:0/0 = 0 406 | 5:0/0/terrain_set = 0 407 | 5:0/0/terrain = 1 408 | 5:0/0/terrains_peering_bit/right_side = 1 409 | 5:0/0/terrains_peering_bit/bottom_side = 1 410 | 5:0/0/terrains_peering_bit/bottom_left_corner = 1 411 | 5:0/0/terrains_peering_bit/left_side = 1 412 | 6:0/0 = 0 413 | 6:0/0/terrain_set = 0 414 | 6:0/0/terrain = 1 415 | 6:0/0/terrains_peering_bit/right_side = 1 416 | 6:0/0/terrains_peering_bit/bottom_right_corner = 1 417 | 6:0/0/terrains_peering_bit/bottom_side = 1 418 | 6:0/0/terrains_peering_bit/left_side = 1 419 | 7:0/0 = 0 420 | 7:0/0/terrain_set = 0 421 | 7:0/0/terrain = 1 422 | 7:0/0/terrains_peering_bit/bottom_side = 1 423 | 7:0/0/terrains_peering_bit/left_side = 1 424 | 8:0/0 = 0 425 | 8:0/0/terrain_set = 0 426 | 8:0/0/terrain = 1 427 | 8:0/0/terrains_peering_bit/right_side = 1 428 | 8:0/0/terrains_peering_bit/bottom_side = 1 429 | 8:0/0/terrains_peering_bit/left_side = 1 430 | 9:0/0 = 0 431 | 9:0/0/terrain_set = 0 432 | 9:0/0/terrain = 1 433 | 9:0/0/terrains_peering_bit/right_side = 1 434 | 9:0/0/terrains_peering_bit/bottom_right_corner = 1 435 | 9:0/0/terrains_peering_bit/bottom_side = 1 436 | 9:0/0/terrains_peering_bit/left_side = 1 437 | 9:0/0/terrains_peering_bit/top_left_corner = 1 438 | 9:0/0/terrains_peering_bit/top_side = 1 439 | 0:1/0 = 0 440 | 0:1/0/terrain_set = 0 441 | 0:1/0/terrain = 1 442 | 0:1/0/terrains_peering_bit/right_side = 1 443 | 0:1/0/terrains_peering_bit/bottom_right_corner = 1 444 | 0:1/0/terrains_peering_bit/bottom_side = 1 445 | 0:1/0/terrains_peering_bit/top_side = 1 446 | 0:1/0/terrains_peering_bit/top_right_corner = 1 447 | 1:1/0 = 0 448 | 1:1/0/terrain_set = 0 449 | 1:1/0/terrain = 1 450 | 1:1/0/terrains_peering_bit/right_side = 1 451 | 1:1/0/terrains_peering_bit/bottom_right_corner = 1 452 | 1:1/0/terrains_peering_bit/bottom_side = 1 453 | 1:1/0/terrains_peering_bit/bottom_left_corner = 1 454 | 1:1/0/terrains_peering_bit/left_side = 1 455 | 1:1/0/terrains_peering_bit/top_left_corner = 1 456 | 1:1/0/terrains_peering_bit/top_side = 1 457 | 1:1/0/terrains_peering_bit/top_right_corner = 1 458 | 2:1/0 = 0 459 | 2:1/0/terrain_set = 0 460 | 2:1/0/terrain = 1 461 | 2:1/0/terrains_peering_bit/bottom_side = 1 462 | 2:1/0/terrains_peering_bit/bottom_left_corner = 1 463 | 2:1/0/terrains_peering_bit/left_side = 1 464 | 2:1/0/terrains_peering_bit/top_left_corner = 1 465 | 2:1/0/terrains_peering_bit/top_side = 1 466 | 3:1/0 = 0 467 | 3:1/0/terrain_set = 0 468 | 3:1/0/terrain = 1 469 | 3:1/0/terrains_peering_bit/bottom_side = 1 470 | 3:1/0/terrains_peering_bit/top_side = 1 471 | 4:1/0 = 0 472 | 4:1/0/terrain_set = 0 473 | 4:1/0/terrain = 1 474 | 4:1/0/terrains_peering_bit/right_side = 1 475 | 4:1/0/terrains_peering_bit/bottom_side = 1 476 | 4:1/0/terrains_peering_bit/top_side = 1 477 | 4:1/0/terrains_peering_bit/top_right_corner = 1 478 | 5:1/0 = 0 479 | 5:1/0/terrain_set = 0 480 | 5:1/0/terrain = 1 481 | 5:1/0/terrains_peering_bit/right_side = 1 482 | 5:1/0/terrains_peering_bit/bottom_side = 1 483 | 5:1/0/terrains_peering_bit/bottom_left_corner = 1 484 | 5:1/0/terrains_peering_bit/left_side = 1 485 | 5:1/0/terrains_peering_bit/top_left_corner = 1 486 | 5:1/0/terrains_peering_bit/top_side = 1 487 | 5:1/0/terrains_peering_bit/top_right_corner = 1 488 | 6:1/0 = 0 489 | 6:1/0/terrain_set = 0 490 | 6:1/0/terrain = 1 491 | 6:1/0/terrains_peering_bit/right_side = 1 492 | 6:1/0/terrains_peering_bit/bottom_right_corner = 1 493 | 6:1/0/terrains_peering_bit/bottom_side = 1 494 | 6:1/0/terrains_peering_bit/left_side = 1 495 | 6:1/0/terrains_peering_bit/top_left_corner = 1 496 | 6:1/0/terrains_peering_bit/top_side = 1 497 | 6:1/0/terrains_peering_bit/top_right_corner = 1 498 | 7:1/0 = 0 499 | 7:1/0/terrain_set = 0 500 | 7:1/0/terrain = 1 501 | 7:1/0/terrains_peering_bit/bottom_side = 1 502 | 7:1/0/terrains_peering_bit/left_side = 1 503 | 7:1/0/terrains_peering_bit/top_left_corner = 1 504 | 7:1/0/terrains_peering_bit/top_side = 1 505 | 8:1/0 = 0 506 | 8:1/0/terrain_set = 0 507 | 8:1/0/terrain = 1 508 | 8:1/0/terrains_peering_bit/right_side = 1 509 | 8:1/0/terrains_peering_bit/bottom_side = 1 510 | 8:1/0/terrains_peering_bit/left_side = 1 511 | 8:1/0/terrains_peering_bit/top_left_corner = 1 512 | 8:1/0/terrains_peering_bit/top_side = 1 513 | 8:1/0/terrains_peering_bit/top_right_corner = 1 514 | 9:1/0 = 0 515 | 9:1/0/terrain_set = 0 516 | 9:1/0/terrain = 1 517 | 9:1/0/terrains_peering_bit/right_side = 1 518 | 9:1/0/terrains_peering_bit/bottom_side = 1 519 | 9:1/0/terrains_peering_bit/bottom_left_corner = 1 520 | 9:1/0/terrains_peering_bit/left_side = 1 521 | 9:1/0/terrains_peering_bit/top_side = 1 522 | 9:1/0/terrains_peering_bit/top_right_corner = 1 523 | 0:2/0 = 0 524 | 0:2/0/terrain_set = 0 525 | 0:2/0/terrain = 1 526 | 0:2/0/terrains_peering_bit/right_side = 1 527 | 0:2/0/terrains_peering_bit/top_side = 1 528 | 0:2/0/terrains_peering_bit/top_right_corner = 1 529 | 1:2/0 = 0 530 | 1:2/0/terrain_set = 0 531 | 1:2/0/terrain = 1 532 | 1:2/0/terrains_peering_bit/right_side = 1 533 | 1:2/0/terrains_peering_bit/left_side = 1 534 | 1:2/0/terrains_peering_bit/top_left_corner = 1 535 | 1:2/0/terrains_peering_bit/top_side = 1 536 | 1:2/0/terrains_peering_bit/top_right_corner = 1 537 | 2:2/0 = 0 538 | 2:2/0/terrain_set = 0 539 | 2:2/0/terrain = 1 540 | 2:2/0/terrains_peering_bit/left_side = 1 541 | 2:2/0/terrains_peering_bit/top_left_corner = 1 542 | 2:2/0/terrains_peering_bit/top_side = 1 543 | 3:2/0 = 0 544 | 3:2/0/terrain_set = 0 545 | 3:2/0/terrain = 1 546 | 3:2/0/terrains_peering_bit/top_side = 1 547 | 4:2/0 = 0 548 | 4:2/0/terrain_set = 0 549 | 4:2/0/terrain = 1 550 | 4:2/0/terrains_peering_bit/right_side = 1 551 | 4:2/0/terrains_peering_bit/bottom_right_corner = 1 552 | 4:2/0/terrains_peering_bit/bottom_side = 1 553 | 4:2/0/terrains_peering_bit/top_side = 1 554 | 5:2/0 = 0 555 | 5:2/0/terrain_set = 0 556 | 5:2/0/terrain = 1 557 | 5:2/0/terrains_peering_bit/right_side = 1 558 | 5:2/0/terrains_peering_bit/bottom_right_corner = 1 559 | 5:2/0/terrains_peering_bit/bottom_side = 1 560 | 5:2/0/terrains_peering_bit/bottom_left_corner = 1 561 | 5:2/0/terrains_peering_bit/left_side = 1 562 | 5:2/0/terrains_peering_bit/top_left_corner = 1 563 | 5:2/0/terrains_peering_bit/top_side = 1 564 | 6:2/0 = 0 565 | 6:2/0/terrain_set = 0 566 | 6:2/0/terrain = 1 567 | 6:2/0/terrains_peering_bit/right_side = 1 568 | 6:2/0/terrains_peering_bit/bottom_right_corner = 1 569 | 6:2/0/terrains_peering_bit/bottom_side = 1 570 | 6:2/0/terrains_peering_bit/bottom_left_corner = 1 571 | 6:2/0/terrains_peering_bit/left_side = 1 572 | 6:2/0/terrains_peering_bit/top_side = 1 573 | 6:2/0/terrains_peering_bit/top_right_corner = 1 574 | 7:2/0 = 0 575 | 7:2/0/terrain_set = 0 576 | 7:2/0/terrain = 1 577 | 7:2/0/terrains_peering_bit/bottom_side = 1 578 | 7:2/0/terrains_peering_bit/bottom_left_corner = 1 579 | 7:2/0/terrains_peering_bit/left_side = 1 580 | 7:2/0/terrains_peering_bit/top_side = 1 581 | 8:2/0 = 0 582 | 8:2/0/terrain_set = 0 583 | 8:2/0/terrain = 1 584 | 8:2/0/terrains_peering_bit/right_side = 1 585 | 8:2/0/terrains_peering_bit/bottom_right_corner = 1 586 | 8:2/0/terrains_peering_bit/bottom_side = 1 587 | 8:2/0/terrains_peering_bit/bottom_left_corner = 1 588 | 8:2/0/terrains_peering_bit/left_side = 1 589 | 8:2/0/terrains_peering_bit/top_side = 1 590 | 9:2/0 = 0 591 | 9:2/0/terrain_set = 0 592 | 9:2/0/terrain = 1 593 | 9:2/0/terrains_peering_bit/right_side = 1 594 | 9:2/0/terrains_peering_bit/bottom_right_corner = 1 595 | 9:2/0/terrains_peering_bit/bottom_side = 1 596 | 9:2/0/terrains_peering_bit/left_side = 1 597 | 9:2/0/terrains_peering_bit/top_side = 1 598 | 10:2/0 = 0 599 | 10:2/0/terrain_set = 0 600 | 10:2/0/terrain = 1 601 | 10:2/0/terrains_peering_bit/right_side = 1 602 | 10:2/0/terrains_peering_bit/bottom_side = 1 603 | 10:2/0/terrains_peering_bit/bottom_left_corner = 1 604 | 10:2/0/terrains_peering_bit/left_side = 1 605 | 10:2/0/terrains_peering_bit/top_side = 1 606 | 0:3/0 = 0 607 | 0:3/0/terrain_set = 0 608 | 0:3/0/terrain = 1 609 | 0:3/0/terrains_peering_bit/right_side = 1 610 | 1:3/0 = 0 611 | 1:3/0/terrain_set = 0 612 | 1:3/0/terrain = 1 613 | 1:3/0/terrains_peering_bit/right_side = 1 614 | 1:3/0/terrains_peering_bit/left_side = 1 615 | 2:3/0 = 0 616 | 2:3/0/terrain_set = 0 617 | 2:3/0/terrain = 1 618 | 2:3/0/terrains_peering_bit/left_side = 1 619 | 3:3/0 = 0 620 | 3:3/0/terrain_set = 0 621 | 3:3/0/terrain = 1 622 | 4:3/0 = 0 623 | 4:3/0/terrain_set = 0 624 | 4:3/0/terrain = 1 625 | 4:3/0/terrains_peering_bit/right_side = 1 626 | 4:3/0/terrains_peering_bit/top_side = 1 627 | 5:3/0 = 0 628 | 5:3/0/terrain_set = 0 629 | 5:3/0/terrain = 1 630 | 5:3/0/terrains_peering_bit/right_side = 1 631 | 5:3/0/terrains_peering_bit/left_side = 1 632 | 5:3/0/terrains_peering_bit/top_left_corner = 1 633 | 5:3/0/terrains_peering_bit/top_side = 1 634 | 6:3/0 = 0 635 | 6:3/0/terrain_set = 0 636 | 6:3/0/terrain = 1 637 | 6:3/0/terrains_peering_bit/right_side = 1 638 | 6:3/0/terrains_peering_bit/left_side = 1 639 | 6:3/0/terrains_peering_bit/top_side = 1 640 | 6:3/0/terrains_peering_bit/top_right_corner = 1 641 | 7:3/0 = 0 642 | 7:3/0/terrain_set = 0 643 | 7:3/0/terrain = 1 644 | 7:3/0/terrains_peering_bit/left_side = 1 645 | 7:3/0/terrains_peering_bit/top_side = 1 646 | 8:3/0 = 0 647 | 8:3/0/terrain_set = 0 648 | 8:3/0/terrain = 1 649 | 8:3/0/terrains_peering_bit/right_side = 1 650 | 8:3/0/terrains_peering_bit/left_side = 1 651 | 8:3/0/terrains_peering_bit/top_side = 1 652 | 9:3/0 = 0 653 | 9:3/0/terrain_set = 0 654 | 9:3/0/terrain = 1 655 | 9:3/0/terrains_peering_bit/right_side = 1 656 | 9:3/0/terrains_peering_bit/bottom_side = 1 657 | 9:3/0/terrains_peering_bit/left_side = 1 658 | 9:3/0/terrains_peering_bit/top_side = 1 659 | 9:3/0/terrains_peering_bit/top_right_corner = 1 660 | 10:3/0 = 0 661 | 10:3/0/terrain_set = 0 662 | 10:3/0/terrain = 1 663 | 10:3/0/terrains_peering_bit/right_side = 1 664 | 10:3/0/terrains_peering_bit/bottom_side = 1 665 | 10:3/0/terrains_peering_bit/left_side = 1 666 | 10:3/0/terrains_peering_bit/top_left_corner = 1 667 | 10:3/0/terrains_peering_bit/top_side = 1 668 | 4:4/0 = 0 669 | 4:4/0/terrain_set = 0 670 | 4:4/0/terrain = 1 671 | 4:4/0/terrains_peering_bit/right_side = 1 672 | 4:4/0/terrains_peering_bit/bottom_side = 1 673 | 4:4/0/terrains_peering_bit/top_side = 1 674 | 5:4/0 = 0 675 | 5:4/0/terrain_set = 0 676 | 5:4/0/terrain = 1 677 | 5:4/0/terrains_peering_bit/right_side = 1 678 | 5:4/0/terrains_peering_bit/bottom_side = 1 679 | 5:4/0/terrains_peering_bit/bottom_left_corner = 1 680 | 5:4/0/terrains_peering_bit/left_side = 1 681 | 5:4/0/terrains_peering_bit/top_left_corner = 1 682 | 5:4/0/terrains_peering_bit/top_side = 1 683 | 6:4/0 = 0 684 | 6:4/0/terrain_set = 0 685 | 6:4/0/terrain = 1 686 | 6:4/0/terrains_peering_bit/right_side = 1 687 | 6:4/0/terrains_peering_bit/bottom_right_corner = 1 688 | 6:4/0/terrains_peering_bit/bottom_side = 1 689 | 6:4/0/terrains_peering_bit/left_side = 1 690 | 6:4/0/terrains_peering_bit/top_side = 1 691 | 6:4/0/terrains_peering_bit/top_right_corner = 1 692 | 7:4/0 = 0 693 | 7:4/0/terrain_set = 0 694 | 7:4/0/terrain = 1 695 | 7:4/0/terrains_peering_bit/bottom_side = 1 696 | 7:4/0/terrains_peering_bit/left_side = 1 697 | 7:4/0/terrains_peering_bit/top_side = 1 698 | 8:4/0 = 0 699 | 8:4/0/terrain_set = 0 700 | 8:4/0/terrain = 1 701 | 8:4/0/terrains_peering_bit/right_side = 1 702 | 8:4/0/terrains_peering_bit/bottom_side = 1 703 | 8:4/0/terrains_peering_bit/left_side = 1 704 | 8:4/0/terrains_peering_bit/top_side = 1 705 | 706 | [sub_resource type="ShaderMaterial" id="ShaderMaterial_o5sfd"] 707 | shader = ExtResource("2_ollag") 708 | shader_parameter/y_start = null 709 | shader_parameter/speed = 1.2 710 | shader_parameter/range = 3.0 711 | 712 | [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_5t3be"] 713 | texture = ExtResource("5_hojho") 714 | 0:0/size_in_atlas = Vector2i(4, 6) 715 | 0:0/0 = 0 716 | 0:0/0/texture_origin = Vector2i(0, 38) 717 | 0:0/0/material = SubResource("ShaderMaterial_o5sfd") 718 | 0:0/0/y_sort_origin = 2 719 | 720 | [sub_resource type="ShaderMaterial" id="ShaderMaterial_oumlc"] 721 | shader = ExtResource("2_ollag") 722 | shader_parameter/y_start = null 723 | shader_parameter/speed = 1.8 724 | shader_parameter/range = 2.0 725 | 726 | [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_tog3n"] 727 | texture = ExtResource("6_05526") 728 | 0:0/size_in_atlas = Vector2i(4, 6) 729 | 0:0/0 = 0 730 | 0:0/0/texture_origin = Vector2i(0, 39) 731 | 0:0/0/material = SubResource("ShaderMaterial_oumlc") 732 | 733 | [resource] 734 | terrain_set_0/mode = 0 735 | terrain_set_0/terrain_0/name = "soil" 736 | terrain_set_0/terrain_0/color = Color(0.945098, 0.403922, 0.176471, 1) 737 | terrain_set_0/terrain_1/name = "grassland" 738 | terrain_set_0/terrain_1/color = Color(0.14902, 0.466667, 0.898039, 1) 739 | sources/0 = SubResource("TileSetAtlasSource_756qy") 740 | sources/2 = SubResource("TileSetAtlasSource_nopne") 741 | sources/1 = SubResource("TileSetAtlasSource_uvbis") 742 | sources/3 = SubResource("TileSetAtlasSource_5t3be") 743 | sources/4 = SubResource("TileSetAtlasSource_tog3n") 744 | -------------------------------------------------------------------------------- /Demo/assets/tileset/tree1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/C-Wenge/TerrainDemo/b8939a45e99fa6f5b27e4d0b0a9c109cb1e81c83/Demo/assets/tileset/tree1.png -------------------------------------------------------------------------------- /Demo/assets/tileset/tree1.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bekpixqdyfpwx" 6 | path="res://.godot/imported/tree1.png-69b74199e20b861b518bad0f80567222.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://assets/tileset/tree1.png" 14 | dest_files=["res://.godot/imported/tree1.png-69b74199e20b861b518bad0f80567222.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Demo/assets/tileset/tree2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/C-Wenge/TerrainDemo/b8939a45e99fa6f5b27e4d0b0a9c109cb1e81c83/Demo/assets/tileset/tree2.png -------------------------------------------------------------------------------- /Demo/assets/tileset/tree2.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c8b8dw3ustgn6" 6 | path="res://.godot/imported/tree2.png-5a91b15a3a2a3cf4cdae1ffb1209a83c.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://assets/tileset/tree2.png" 14 | dest_files=["res://.godot/imported/tree2.png-5a91b15a3a2a3cf4cdae1ffb1209a83c.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Demo/assets/tileset/water_and_soil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/C-Wenge/TerrainDemo/b8939a45e99fa6f5b27e4d0b0a9c109cb1e81c83/Demo/assets/tileset/water_and_soil.png -------------------------------------------------------------------------------- /Demo/assets/tileset/water_and_soil.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://df0vhe6cu1cim" 6 | path="res://.godot/imported/water_and_soil.png-0cdfde423b648bc6846d35d7a3fda6bd.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://assets/tileset/water_and_soil.png" 14 | dest_files=["res://.godot/imported/water_and_soil.png-0cdfde423b648bc6846d35d7a3fda6bd.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Demo/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Demo/icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cqn3pdd4a2lx0" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /Demo/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="动态加载演示" 14 | run/main_scene="res://scenes/demo_scene.tscn" 15 | config/features=PackedStringArray("4.2", "Forward Plus") 16 | config/icon="res://icon.svg" 17 | 18 | [display] 19 | 20 | window/size/mode=2 21 | window/stretch/mode="canvas_items" 22 | window/stretch/aspect="keep_height" 23 | 24 | [input] 25 | 26 | move_left={ 27 | "deadzone": 0.5, 28 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) 29 | ] 30 | } 31 | move_right={ 32 | "deadzone": 0.5, 33 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) 34 | ] 35 | } 36 | move_up={ 37 | "deadzone": 0.5, 38 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) 39 | ] 40 | } 41 | move_down={ 42 | "deadzone": 0.5, 43 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /Demo/scenes/block_node.gd: -------------------------------------------------------------------------------- 1 | # ---------->>> 2 | # @Author: 文雨 3 | # @Date: 2023-12-27 22:49:38 4 | # @LastEditTime: 2023-12-31 14:42:21 5 | # @Description: 地图区块节点 6 | # ---------->>> 7 | 8 | extends Node2D 9 | class_name BlockNode 10 | 11 | # 演示场景 12 | var demo_scene : DemoScene 13 | 14 | # 水图块 15 | var water_tile : TerrainTile 16 | # 草图块 17 | var grass_tiles := [] 18 | # 树图块 19 | var tree_tiles := [] 20 | 21 | # 区块坐标 22 | var block_coords : Vector2i 23 | # 开始图块坐标 24 | var start_tile_coords : Vector2i 25 | # 区块大小 26 | var block_size : Vector2i 27 | 28 | # 线程任务id 29 | var task_id : int 30 | # 是否退出 31 | var block_exit := false 32 | 33 | func _ready() -> void: 34 | 35 | init_tile() 36 | 37 | start_tile_coords = demo_scene.block_to_tile(block_coords) 38 | block_size = demo_scene.get_block_size() 39 | 40 | task_id = WorkerThreadPool.add_task(thread_generate,true) 41 | 42 | func init_tile() -> void: 43 | 44 | # 水的图块 45 | water_tile = TerrainTile.new() 46 | water_tile.source_id = 0 47 | water_tile.atlas_coords = Vector2i(0,0) 48 | water_tile.alternative_tile = 0 49 | 50 | var grass1 := TerrainTile.new() 51 | grass1.source_id = 1 52 | grass1.atlas_coords = Vector2i.ZERO 53 | grass1.alternative_tile = 0 54 | 55 | grass_tiles.append(grass1) 56 | 57 | var grass2 := TerrainTile.new() 58 | grass2.source_id = 1 59 | grass2.atlas_coords = Vector2i(1,0) 60 | grass2.alternative_tile = 0 61 | 62 | grass_tiles.append(grass2) 63 | 64 | var grass3 := TerrainTile.new() 65 | grass3.source_id = 1 66 | grass3.atlas_coords = Vector2i(2,0) 67 | grass3.alternative_tile = 0 68 | 69 | grass_tiles.append(grass3) 70 | 71 | var tree1 := TerrainTile.new() 72 | tree1.source_id = 3 73 | tree1.atlas_coords =Vector2i.ZERO 74 | tree1.alternative_tile = 0 75 | 76 | tree_tiles.append(tree1) 77 | 78 | var tree2 := TerrainTile.new() 79 | tree2.source_id = 4 80 | tree2.atlas_coords =Vector2i.ZERO 81 | tree2.alternative_tile = 0 82 | 83 | tree_tiles.append(tree2) 84 | 85 | func _process(_delta: float) -> void: 86 | 87 | if block_exit and WorkerThreadPool.is_task_completed(task_id) and not is_queued_for_deletion(): 88 | queue_free() 89 | 90 | # 使用线程生成地图数据,注意线程安全 91 | func thread_generate() -> void: 92 | 93 | var all_coords := [] 94 | 95 | var water_layer := {} 96 | var soil_layer := {} 97 | var grassland1_layer := {} 98 | var grass_layer := {} 99 | 100 | for x : int in range(-1,block_size.x+1): 101 | for y : int in range(-1,block_size.y+1): 102 | 103 | var coords := Vector2i(x,y) 104 | var noise_coords := coords + start_tile_coords 105 | 106 | all_coords.append(coords) 107 | 108 | # 按照不同的噪声值绘制不同的地形 109 | var main_value :float = demo_scene.main_noise.get_noise_2dv(noise_coords) 110 | 111 | if main_value < 0.0: 112 | water_layer[coords] = water_tile 113 | 114 | if main_value >= 0.0 and main_value<0.3: 115 | demo_scene.terrain_system.draw_terrain(soil_layer,coords,0) 116 | 117 | if main_value >= 0.1: 118 | demo_scene.terrain_system.draw_terrain(grassland1_layer,coords,1) 119 | 120 | if main_value >= 0.2: 121 | 122 | var tree_value := demo_scene.tree_noise.get_noise_2dv(coords) 123 | if tree_value<=0.2 and randf() < 0.03: 124 | var tree_tile :TerrainTile = tree_tiles[randi()%tree_tiles.size()] 125 | grass_layer[coords] = tree_tile 126 | elif randf() < 0.3: 127 | var tile :TerrainTile = grass_tiles[randi()%grass_tiles.size()] 128 | grass_layer[coords] = tile 129 | 130 | 131 | # 转化为TileMap使用的tile data 132 | var tile_datas :Array[PackedInt32Array] = [ 133 | PackedInt32Array(), 134 | PackedInt32Array(), 135 | PackedInt32Array(), 136 | PackedInt32Array() 137 | ] 138 | 139 | for coords : Vector2i in all_coords: 140 | 141 | if coords.x<0 or coords.x>=block_size.x or \ 142 | coords.y<0 or coords.y>=block_size.y: 143 | continue 144 | 145 | if water_layer.has(coords): 146 | var tile :TerrainTile = water_layer[coords] 147 | add_tile_data(tile_datas[0],coords,tile) 148 | 149 | if soil_layer.has(coords): 150 | var tile :TerrainTile = soil_layer[coords] 151 | add_tile_data(tile_datas[1],coords,tile) 152 | 153 | if grassland1_layer.has(coords): 154 | var tile :TerrainTile = grassland1_layer[coords] 155 | add_tile_data(tile_datas[2],coords,tile) 156 | 157 | if grass_layer.has(coords): 158 | var tile :TerrainTile = grass_layer[coords] 159 | add_tile_data(tile_datas[3],coords,tile) 160 | 161 | # 生成完成,下一帧由主线程将tile data传递给TileMap 162 | call_deferred("generate_finish",tile_datas) 163 | 164 | 165 | func add_tile_data(array: PackedInt32Array, coords: Vector2i, tile: TerrainTile) -> void: 166 | 167 | array.append_array(demo_scene.terrain_system.to_tile_data( 168 | coords, 169 | tile.source_id, 170 | tile.atlas_coords, 171 | tile.alternative_tile, 172 | false,false,false 173 | )) 174 | 175 | # 由主线程设置TileMap的tile data 176 | func generate_finish(tile_datas: Array[PackedInt32Array]) -> void: 177 | 178 | for layer : int in tile_datas.size(): 179 | var tile_data :PackedInt32Array = tile_datas[layer] 180 | set("layer_"+str(layer)+"/tile_data",tile_data) 181 | 182 | # 退出 183 | func exit_block() -> void: 184 | block_exit = true 185 | -------------------------------------------------------------------------------- /Demo/scenes/block_node.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://c4l2nc4i6pvq7"] 2 | 3 | [ext_resource type="TileSet" uid="uid://2pc3ylacfkgq" path="res://assets/tileset/tile_set.tres" id="1_0i2k0"] 4 | [ext_resource type="Script" path="res://scenes/block_node.gd" id="2_0u71e"] 5 | 6 | [node name="BlockNode" type="TileMap"] 7 | y_sort_enabled = true 8 | texture_filter = 1 9 | tile_set = ExtResource("1_0i2k0") 10 | format = 2 11 | layer_0/name = "water" 12 | layer_0/z_index = -1 13 | layer_0/navigation_enabled = false 14 | layer_1/name = "soil" 15 | layer_1/z_index = -1 16 | layer_1/navigation_enabled = false 17 | layer_1/tile_data = PackedInt32Array() 18 | layer_2/name = "grassland" 19 | layer_2/z_index = -1 20 | layer_2/navigation_enabled = false 21 | layer_2/tile_data = PackedInt32Array() 22 | layer_3/name = "grass" 23 | layer_3/y_sort_enabled = true 24 | layer_3/navigation_enabled = false 25 | layer_3/tile_data = PackedInt32Array() 26 | script = ExtResource("2_0u71e") 27 | -------------------------------------------------------------------------------- /Demo/scenes/demo_scene.gd: -------------------------------------------------------------------------------- 1 | # ---------->>> 2 | # @Author: 文雨 3 | # @Date: 2023-12-27 22:12:20 4 | # @LastEditTime: 2023-12-31 14:34:19 5 | # @Description: 演示场景 6 | # ---------->>> 7 | 8 | extends Node2D 9 | class_name DemoScene 10 | 11 | @onready var fps_label :Label = $"CanvasLayer/Background/Mc/Vbc/FpsLabel" 12 | 13 | # 主地图噪声 14 | @export var main_noise : FastNoiseLite 15 | # 树木噪声 16 | @export var tree_noise : FastNoiseLite 17 | 18 | @export var tile_set : TileSet 19 | 20 | # 区块节点 21 | @export var block_node : PackedScene 22 | # 区块大小 23 | @export var block_size : Vector2i 24 | 25 | # 区块的父节点 26 | @export var block_parent : Node2D 27 | 28 | # 玩家 29 | @export var player : Player 30 | 31 | # 已加载的区块 32 | var blocks :Array[Vector2i] = [] 33 | # 当前区块坐标 34 | var current_block_coords : Vector2i 35 | 36 | # 加载范围半径 37 | @export var load_range_radius := 1 38 | 39 | # 加载位置 40 | var load_position : Vector2 41 | 42 | # 在场景中的区块节点 43 | var scene_block_nodes := {} 44 | 45 | var terrain_system : SimpleTerrainSystem 46 | 47 | func _ready() -> void: 48 | 49 | randomize() 50 | 51 | terrain_system = SimpleTerrainSystem.new(tile_set) 52 | 53 | main_noise.seed = randi() 54 | tree_noise.seed = randi() 55 | 56 | generate_block() 57 | 58 | func _process(_delta: float) -> void: 59 | 60 | fps_label.text = "FPS:"+str(Engine.get_frames_per_second()) 61 | 62 | load_position = player.position 63 | update_block_coords() 64 | 65 | # 更新区块坐标 66 | func update_block_coords() -> void: 67 | 68 | # 区块坐标 69 | var block_coords := tile_to_block(to_tile(load_position)) 70 | 71 | # 如果区块坐标发生改变就更新 72 | if current_block_coords!=block_coords: 73 | current_block_coords = block_coords 74 | generate_block() 75 | 76 | # 生成区块 77 | func generate_block() -> void: 78 | 79 | var start_coords := current_block_coords - Vector2i(load_range_radius,load_range_radius) 80 | var end_coords := current_block_coords + Vector2i(load_range_radius,load_range_radius) + Vector2i.ONE 81 | 82 | # 基于当前坐标的所有区块坐标 83 | var array :Array[Vector2i] = [] 84 | 85 | for x:int in range(start_coords.x,end_coords.x): 86 | for y:int in range(start_coords.y,end_coords.y): 87 | array.append(Vector2i(x,y)) 88 | 89 | # 将不需要的区块卸载 90 | var removes :Array[Vector2i] = [] 91 | 92 | for coords:Vector2i in blocks: 93 | if not array.has(coords): 94 | removes.append(coords) 95 | remove_block_node(coords) 96 | 97 | # 移除 98 | for coords:Vector2i in removes: 99 | blocks.erase(coords) 100 | 101 | # 加载 102 | for coords:Vector2i in array: 103 | if not blocks.has(coords): 104 | blocks.append(coords) 105 | add_block_node(coords) 106 | 107 | # 添加区块节点 108 | func add_block_node(coords: Vector2i) -> void: 109 | 110 | assert(not scene_block_nodes.has(coords), "要添加的区块节点已经存在!") 111 | 112 | var block :BlockNode = block_node.instantiate() 113 | 114 | block.block_coords = coords 115 | block.demo_scene = self 116 | block.position = block_to_tile(tile_to_global(coords)) 117 | 118 | block_parent.add_child(block) 119 | scene_block_nodes[coords] = block 120 | 121 | # 移除区块节点 122 | func remove_block_node(coords: Vector2i) -> void: 123 | 124 | if scene_block_nodes.has(coords): 125 | var block :BlockNode = scene_block_nodes[coords] 126 | block.exit_block() 127 | scene_block_nodes.erase(coords) 128 | 129 | # 获取图块大小 130 | func get_tile_size() -> Vector2i: 131 | return tile_set.tile_size 132 | 133 | # 获取区块大小 134 | func get_block_size() -> Vector2i: 135 | return block_size 136 | 137 | # 将全局坐标转换为图块坐标 138 | func to_tile(global:Vector2) -> Vector2i: 139 | var vec := (global/Vector2(get_tile_size())).floor() 140 | return Vector2i(vec) 141 | 142 | # 将图块坐标转换为区块坐标 143 | func tile_to_block(tile:Vector2i) -> Vector2i: 144 | var vec := Vector2(tile)/Vector2(get_block_size()) 145 | return Vector2i(vec.floor()) 146 | 147 | # 将图块坐标转换为全局坐标 148 | func tile_to_global(tile:Vector2i) -> Vector2: 149 | return Vector2(tile)*Vector2(get_tile_size()) 150 | 151 | # 将区块坐标转换为图块坐标 152 | func block_to_tile(block:Vector2i) -> Vector2i: 153 | return block * get_block_size() 154 | -------------------------------------------------------------------------------- /Demo/scenes/demo_scene.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=3 uid="uid://pbkwhy3b5bey"] 2 | 3 | [ext_resource type="Script" path="res://scenes/demo_scene.gd" id="1_wlbae"] 4 | [ext_resource type="TileSet" uid="uid://2pc3ylacfkgq" path="res://assets/tileset/tile_set.tres" id="2_e7g81"] 5 | [ext_resource type="PackedScene" uid="uid://c4l2nc4i6pvq7" path="res://scenes/block_node.tscn" id="3_44g3d"] 6 | [ext_resource type="PackedScene" uid="uid://cs5245kakxnpt" path="res://scenes/player.tscn" id="4_5j87r"] 7 | [ext_resource type="FontFile" uid="uid://3nm64q3y2x5h" path="res://assets/fonts/vonwaon_bitmap-12px.ttf" id="5_0iequ"] 8 | 9 | [sub_resource type="FastNoiseLite" id="FastNoiseLite_48fyg"] 10 | frequency = 0.02 11 | 12 | [sub_resource type="FastNoiseLite" id="FastNoiseLite_puwa6"] 13 | frequency = 0.02 14 | 15 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7les5"] 16 | bg_color = Color(0, 0, 0, 0.392157) 17 | border_width_top = 10 18 | border_color = Color(1, 1, 1, 0.784314) 19 | corner_radius_bottom_right = 4 20 | corner_radius_bottom_left = 4 21 | shadow_color = Color(0, 0, 0, 0.196078) 22 | shadow_size = 4 23 | shadow_offset = Vector2(2, 2) 24 | 25 | [node name="DemoScene" type="Node2D" node_paths=PackedStringArray("block_parent", "player")] 26 | script = ExtResource("1_wlbae") 27 | main_noise = SubResource("FastNoiseLite_48fyg") 28 | tree_noise = SubResource("FastNoiseLite_puwa6") 29 | tile_set = ExtResource("2_e7g81") 30 | block_node = ExtResource("3_44g3d") 31 | block_size = Vector2i(20, 20) 32 | block_parent = NodePath("World/Blocks") 33 | player = NodePath("World/Player") 34 | load_range_radius = 3 35 | 36 | [node name="World" type="Node2D" parent="."] 37 | y_sort_enabled = true 38 | 39 | [node name="Blocks" type="Node2D" parent="World"] 40 | y_sort_enabled = true 41 | 42 | [node name="Player" parent="World" node_paths=PackedStringArray("camera") instance=ExtResource("4_5j87r")] 43 | y_sort_enabled = true 44 | move_speed = 500.0 45 | camera = NodePath("Camera2D") 46 | 47 | [node name="Camera2D" type="Camera2D" parent="World/Player"] 48 | process_callback = 0 49 | position_smoothing_enabled = true 50 | position_smoothing_speed = 10.0 51 | 52 | [node name="CanvasLayer" type="CanvasLayer" parent="."] 53 | 54 | [node name="Background" type="PanelContainer" parent="CanvasLayer"] 55 | offset_left = 10.0 56 | offset_top = 10.0 57 | offset_right = 130.0 58 | offset_bottom = 110.0 59 | theme_override_styles/panel = SubResource("StyleBoxFlat_7les5") 60 | 61 | [node name="Mc" type="MarginContainer" parent="CanvasLayer/Background"] 62 | layout_mode = 2 63 | theme_override_constants/margin_top = 8 64 | 65 | [node name="Vbc" type="VBoxContainer" parent="CanvasLayer/Background/Mc"] 66 | layout_mode = 2 67 | theme_override_constants/separation = 16 68 | 69 | [node name="FpsLabel" type="Label" parent="CanvasLayer/Background/Mc/Vbc"] 70 | layout_mode = 2 71 | theme_override_fonts/font = ExtResource("5_0iequ") 72 | text = "FPS:60" 73 | horizontal_alignment = 1 74 | 75 | [node name="DesLabel" type="Label" parent="CanvasLayer/Background/Mc/Vbc"] 76 | layout_mode = 2 77 | theme_override_fonts/font = ExtResource("5_0iequ") 78 | theme_override_font_sizes/font_size = 12 79 | text = "W,S,A,D移动 80 | 鼠标滚轮控制视角 81 | 大小" 82 | horizontal_alignment = 1 83 | -------------------------------------------------------------------------------- /Demo/scenes/player.gd: -------------------------------------------------------------------------------- 1 | # ---------->>> 2 | # @Author: 文雨 3 | # @Date: 2023-12-27 23:11:59 4 | # @LastEditTime: 2023-12-27 23:53:11 5 | # @Description: 玩家 6 | # ---------->>> 7 | 8 | extends CharacterBody2D 9 | class_name Player 10 | 11 | # 移动速度 12 | @export var move_speed := 200.0 13 | 14 | # 相机 15 | @export var camera : Camera2D 16 | 17 | func _input(event: InputEvent) -> void: 18 | 19 | if event is InputEventMouseButton: 20 | 21 | if event.button_index == MOUSE_BUTTON_WHEEL_DOWN: 22 | camera.zoom.x = max(0.5,camera.zoom.x-0.01) 23 | 24 | if event.button_index == MOUSE_BUTTON_WHEEL_UP: 25 | camera.zoom.x = min(3.0,camera.zoom.x+0.01) 26 | 27 | camera.zoom.y = camera.zoom.x 28 | 29 | func _physics_process(_delta: float) -> void: 30 | 31 | var vec := Input.get_vector("move_left","move_right","move_up","move_down") 32 | velocity = vec * move_speed 33 | move_and_slide() -------------------------------------------------------------------------------- /Demo/scenes/player.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://cs5245kakxnpt"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://cqn3pdd4a2lx0" path="res://icon.svg" id="1_eh8xf"] 4 | [ext_resource type="Script" path="res://scenes/player.gd" id="1_k61wf"] 5 | 6 | [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_veb7v"] 7 | radius = 4.0 8 | height = 34.0 9 | 10 | [node name="Player" type="CharacterBody2D"] 11 | motion_mode = 1 12 | script = ExtResource("1_k61wf") 13 | 14 | [node name="Icon" type="Sprite2D" parent="."] 15 | scale = Vector2(0.2, 0.2) 16 | texture = ExtResource("1_eh8xf") 17 | offset = Vector2(2.08165e-12, -64) 18 | 19 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 20 | rotation = 1.5708 21 | shape = SubResource("CapsuleShape2D_veb7v") 22 | -------------------------------------------------------------------------------- /Demo/scripts/simple_terrain_system.gd: -------------------------------------------------------------------------------- 1 | # ---------->>> 2 | # @Author: 文雨 3 | # @Date: 2023-12-27 01:41:31 4 | # @LastEditTime: 2023-12-31 13:17:11 5 | # @Description: 简单的地形系统,仅支持3x3的单一地形匹配 6 | # ---------->>> 7 | 8 | extends RefCounted 9 | class_name SimpleTerrainSystem 10 | 11 | # 八个方向的向量 12 | const DIRECTIONS := [ 13 | Vector2i.RIGHT, 14 | Vector2i(1,1), 15 | Vector2i.DOWN, 16 | Vector2i(-1,1), 17 | Vector2i.LEFT, 18 | Vector2i(-1,-1), 19 | Vector2i.UP, 20 | Vector2i(1,-1) 21 | ] 22 | 23 | 24 | # 所有地形图块 25 | var terrain_tiles := {} 26 | 27 | # 构建需要一个TileSet 28 | func _init(tile_set: TileSet) -> void: 29 | 30 | for i : int in tile_set.get_source_count(): 31 | 32 | var source_id :int = tile_set.get_source_id(i) 33 | 34 | if not tile_set.get_source(source_id) is TileSetAtlasSource: 35 | continue 36 | 37 | var source :TileSetAtlasSource = tile_set.get_source(source_id) 38 | 39 | _handle_source(source,source_id) 40 | 41 | func _handle_source(source: TileSetAtlasSource,source_id: int) -> void: 42 | 43 | for j : int in source.get_tiles_count(): 44 | 45 | var atlas_coords :Vector2i = source.get_tile_id(j) 46 | for k : int in source.get_alternative_tiles_count(atlas_coords): 47 | 48 | var alternative_tile :int = source.get_alternative_tile_id(atlas_coords,k) 49 | 50 | var tile_data :TileData = source.get_tile_data(atlas_coords,alternative_tile) 51 | 52 | # 目前仅支持一个地形集 53 | if tile_data.terrain_set>0: 54 | push_warning("地形集%s将被忽略,仅支持第一个地形集"% tile_data.terrain_set) 55 | continue 56 | 57 | if tile_data.terrain < 0: 58 | continue 59 | 60 | var terrain_tile := TerrainTile.new() 61 | terrain_tile.source_id = source_id 62 | terrain_tile.atlas_coords = atlas_coords 63 | terrain_tile.alternative_tile = alternative_tile 64 | 65 | terrain_tile.terrain = tile_data.terrain 66 | 67 | terrain_tile.bit_right = tile_data.get_terrain_peering_bit( 68 | TileSet.CELL_NEIGHBOR_RIGHT_SIDE) == terrain_tile.terrain 69 | 70 | terrain_tile.bit_right_down = tile_data.get_terrain_peering_bit( 71 | TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER) == terrain_tile.terrain 72 | 73 | terrain_tile.bit_down = tile_data.get_terrain_peering_bit( 74 | TileSet.CELL_NEIGHBOR_BOTTOM_SIDE) == terrain_tile.terrain 75 | 76 | terrain_tile.bit_left_down = tile_data.get_terrain_peering_bit( 77 | TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER) == terrain_tile.terrain 78 | 79 | terrain_tile.bit_left = tile_data.get_terrain_peering_bit( 80 | TileSet.CELL_NEIGHBOR_LEFT_SIDE) == terrain_tile.terrain 81 | 82 | terrain_tile.bit_left_up = tile_data.get_terrain_peering_bit( 83 | TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER) == terrain_tile.terrain 84 | 85 | terrain_tile.bit_up = tile_data.get_terrain_peering_bit( 86 | TileSet.CELL_NEIGHBOR_TOP_SIDE) == terrain_tile.terrain 87 | 88 | terrain_tile.bit_right_up = tile_data.get_terrain_peering_bit( 89 | TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER) == terrain_tile.terrain 90 | 91 | add_terrain_tile(terrain_tile) 92 | 93 | # 添加一个地形图块 94 | func add_terrain_tile(tile: TerrainTile) -> void: 95 | 96 | var tiles :Dictionary = terrain_tiles[tile.terrain] \ 97 | if terrain_tiles.has(tile.terrain) else {} 98 | 99 | var id := get_terrain_tile_id(tile) 100 | tiles[id] = tile 101 | 102 | if not terrain_tiles.has(tile.terrain): 103 | terrain_tiles[tile.terrain] = tiles 104 | 105 | # 获取一个地形图块,如果没有就返回null 106 | func get_terrain_tile(terrain: int, id: int) -> TerrainTile: 107 | 108 | var tiles :Dictionary = terrain_tiles[terrain] \ 109 | if terrain_tiles.has(terrain) else {} 110 | 111 | if tiles.has(id): 112 | return tiles[id].duplicate() 113 | 114 | return null 115 | 116 | # 获取地形图块的id 117 | func get_terrain_tile_id(tile: TerrainTile) -> int: 118 | 119 | var id :int = (0 | int(tile.bit_right)) << 1 120 | id = (id | int(tile.bit_right_down)) << 1 121 | id = (id | int(tile.bit_down)) << 1 122 | id = (id | int(tile.bit_left_down)) << 1 123 | id = (id | int(tile.bit_left)) << 1 124 | id = (id | int(tile.bit_left_up)) << 1 125 | id = (id | int(tile.bit_up)) << 1 126 | id = (id | int(tile.bit_right_up)) << 7 127 | 128 | return id 129 | 130 | # 转换为TileMap使用的tile data 131 | func to_tile_data(coords:Vector2i, source_id:int, atlas_coords:Vector2i, 132 | alternative_tile:int,transpose:bool, flip_v:bool, flip_h:bool) -> PackedInt32Array: 133 | 134 | var array := PackedInt32Array() 135 | 136 | # 第1位32位整数前16位表示坐标的y,后16位表示坐标x 137 | var coords_32 :int = int(coords.y) << 16 | int(coords.x) 138 | array.append(coords_32) 139 | 140 | # 第2位32位整数前16位表示图集坐标的x,后16位表示源id 141 | var atlas_source_32 :int = int(atlas_coords.x) << 16 | int(source_id) 142 | array.append(atlas_source_32) 143 | 144 | # 第3位32位整数的第1位是0,因为这是一个整数,如果转置是true第2位是1否则位0 145 | var int_32 :int = (1 if transpose else 0) << 1 146 | # 如果垂直翻转为true则第3位为1否则为0 147 | int_32 = (int_32 | (1 if flip_v else 0)) << 1 148 | # 如果水平翻转为true则第4位为1否则为0 149 | int_32 = (int_32 | (1 if flip_h else 0)) << 28 150 | # 后12位表示备选 151 | int_32 = int_32 | (alternative_tile << 16) 152 | # 最后的16位是图集坐标y 153 | int_32 = int_32 | int(atlas_coords.y) 154 | 155 | array.append(int_32) 156 | 157 | return array 158 | 159 | # 标准化地形图块 160 | func norm_terrain_tile(terrain_tile: TerrainTile) -> TerrainTile: 161 | 162 | if terrain_tile.bit_right_down: 163 | terrain_tile.bit_right_down = terrain_tile.bit_right and terrain_tile.bit_down 164 | if terrain_tile.bit_right_up: 165 | terrain_tile.bit_right_up = terrain_tile.bit_right and terrain_tile.bit_up 166 | if terrain_tile.bit_left_down: 167 | terrain_tile.bit_left_down = terrain_tile.bit_left and terrain_tile.bit_down 168 | if terrain_tile.bit_left_up: 169 | terrain_tile.bit_left_up = terrain_tile.bit_left and terrain_tile.bit_up 170 | 171 | return terrain_tile 172 | 173 | # 绘制地形 174 | func draw_terrain(map_dict: Dictionary, coords: Vector2i, terrain: int) -> void: 175 | 176 | var terrain_tile := TerrainTile.new() 177 | terrain_tile.terrain = terrain 178 | 179 | var update_coords := [] 180 | 181 | for dir : Vector2i in DIRECTIONS: 182 | 183 | var neighbour := coords + dir 184 | 185 | if map_dict.has(neighbour): 186 | 187 | var tile :TerrainTile = map_dict[neighbour] 188 | if tile.terrain == terrain: 189 | 190 | terrain_tile.set_direction_bit(dir,true) 191 | update_coords.append(neighbour) 192 | 193 | terrain_tile = norm_terrain_tile(terrain_tile) 194 | 195 | var id := get_terrain_tile_id(terrain_tile) 196 | 197 | var target_tile := get_terrain_tile(terrain,id) 198 | 199 | if not is_instance_valid(target_tile): 200 | print(terrain_tile) 201 | else : 202 | map_dict[coords] = target_tile 203 | 204 | for u_coords : Vector2i in update_coords: 205 | update_terrain(map_dict,u_coords) 206 | 207 | # 更新地形 208 | func update_terrain(map_dict: Dictionary, coords: Vector2i) -> void: 209 | 210 | if not map_dict.has(coords): 211 | return 212 | 213 | var terrain_tile :TerrainTile = map_dict[coords].duplicate() 214 | 215 | for dir : Vector2i in DIRECTIONS: 216 | 217 | var neighbour := coords + dir 218 | 219 | if map_dict.has(neighbour): 220 | var tile :TerrainTile = map_dict[neighbour] 221 | 222 | if tile.terrain == terrain_tile.terrain: 223 | terrain_tile.set_direction_bit(dir,true) 224 | 225 | terrain_tile = norm_terrain_tile(terrain_tile) 226 | 227 | var id := get_terrain_tile_id(terrain_tile) 228 | 229 | var target_tile := get_terrain_tile(terrain_tile.terrain,id) 230 | 231 | if not is_instance_valid(target_tile): 232 | print(terrain_tile) 233 | return 234 | 235 | map_dict[coords] = target_tile -------------------------------------------------------------------------------- /Demo/scripts/terrain_tile.gd: -------------------------------------------------------------------------------- 1 | # ---------->>> 2 | # @Author: 文雨 3 | # @Date: 2023-12-27 01:47:49 4 | # @LastEditTime: 2023-12-27 05:24:46 5 | # @Description: 地形图块 6 | # ---------->>> 7 | 8 | extends RefCounted 9 | class_name TerrainTile 10 | 11 | var source_id : int 12 | var atlas_coords : Vector2i 13 | var alternative_tile : int 14 | 15 | # 所属地形 16 | var terrain : int 17 | 18 | # 位右 19 | var bit_right := false 20 | # 位右下 21 | var bit_right_down := false 22 | # 位下 23 | var bit_down := false 24 | # 位左下 25 | var bit_left_down := false 26 | # 位左 27 | var bit_left := false 28 | # 位左上 29 | var bit_left_up := false 30 | # 位上 31 | var bit_up := false 32 | # 位右上 33 | var bit_right_up := false 34 | 35 | # 设置指定方向的位 36 | func set_direction_bit(dir: Vector2i, value: bool) -> void: 37 | 38 | match dir: 39 | Vector2i.RIGHT: 40 | bit_right = value 41 | Vector2i(1,1): 42 | bit_right_down = value 43 | Vector2i.DOWN: 44 | bit_down = value 45 | Vector2i(-1,1): 46 | bit_left_down = value 47 | Vector2i.LEFT: 48 | bit_left = value 49 | Vector2i(-1,-1): 50 | bit_left_up = value 51 | Vector2i.UP: 52 | bit_up = value 53 | Vector2i(1,-1): 54 | bit_right_up = value 55 | _: 56 | push_warning("不存在方向%s"%dir) 57 | 58 | # 获取这个图块副本 59 | func duplicate() -> TerrainTile: 60 | 61 | var terrain_tile := TerrainTile.new() 62 | 63 | terrain_tile.source_id = source_id 64 | terrain_tile.atlas_coords = atlas_coords 65 | terrain_tile.alternative_tile = alternative_tile 66 | 67 | terrain_tile.terrain = terrain 68 | 69 | terrain_tile.bit_right = bit_right 70 | terrain_tile.bit_right_down = bit_right_down 71 | terrain_tile.bit_down = bit_down 72 | terrain_tile.bit_left_down = bit_left_down 73 | terrain_tile.bit_left = bit_left 74 | terrain_tile.bit_left_up = bit_left_up 75 | terrain_tile.bit_up = bit_up 76 | terrain_tile.bit_right_up = bit_right_up 77 | 78 | return terrain_tile 79 | 80 | func _to_string() -> String: 81 | 82 | return "地形:"+str(terrain)+\ 83 | "右:"+str(bit_right)+\ 84 | "右下:"+str(bit_right_down)+\ 85 | "下:"+str(bit_down)+\ 86 | "左下:"+str(bit_left_down)+\ 87 | "左:"+str(bit_left)+\ 88 | "左上:"+str(bit_left_up)+\ 89 | "上:"+str(bit_up)+\ 90 | "右上:"+str(bit_right_up) -------------------------------------------------------------------------------- /Demo/shaders/grass.gdshader: -------------------------------------------------------------------------------- 1 | shader_type canvas_item; 2 | 3 | uniform float y_start:hint_range(0.0, 1.0, 0.01); 4 | uniform float speed:hint_range(0.1, 5.0, 0.1) = 1.0; 5 | uniform float range:hint_range(0.1, 5.0, 0.1) = 1.0; 6 | 7 | void vertex(){ 8 | if((1.0-y_start)>UV.y){ 9 | VERTEX.x += sin(TIME*speed)*(1.0-UV.y)*range; 10 | } 11 | } --------------------------------------------------------------------------------