prototype

This commit is contained in:
Chris Cromer 2022-04-05 14:51:59 -04:00
parent 4599cff7b3
commit a2ad48e900
Signed by: cromer
GPG Key ID: FA91071797BEEEC2
64 changed files with 7353 additions and 44 deletions

50
.gitignore vendored
View File

@ -1,26 +1,38 @@
# godot related files
.godot/
.import/
*.translation
# SConstruct db
*.dblite
# this config file contains sensitive content and should not be commited
export_presets.cfg
# Godot Serialisations
api.json
# mono files
.mono/
# Visual Studio Cache
.vs/
# the output binaries
# VSCode Cache
.vscode/
# Mac stuff
.DS_Store
# Binaries
build/
#android build files
android/
# object files
*.o
*.os
*.dll
*.so
*.a
# other random files
.sconsign.dblite
# Godot
godot/.import/
godot/*.translation
godot/export_presets.cfg
godot/.mono/
godot/android/
# tiled session
*.tiled-session
# Gdnative libs
godot/gdnative/linux.*
godot/gdnative/windows.*
# compile commands
compile_commands.json
# docs
docs/

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "godot-cpp"]
path = godot-cpp
url = https://github.com/godotengine/godot-cpp
branch = 3.4

62
Makefile Normal file
View File

@ -0,0 +1,62 @@
# This makefile is used to compile the project
SHELL := /bin/bash
PROCS := $(shell nproc)
USE_LLVM := "yes"
RELEASE_TYPE := "debug"
all: godot-cpp game docs
linux: game-linux
# Only needs to be run once after cloning
init:
pushd godot-cpp; git submodule update --init --recursive
# This needs to be run to create all the libraries for godot-cpp
godot-cpp: godot-cpp-linux godot-cpp-windows
godot-cpp-linux:
pushd godot-cpp; scons use_llvm=$(USE_LLVM) target=$(RELEASE_TYPE) platform=linux generate_bindings=yes bits=64 -j $(PROCS)
godot-cpp-windows:
pushd godot-cpp; scons target=$(RELEASE_TYPE) platform=windows generate_bindings=yes bits=64 -j $(PROCS)
game: game-linux game-windows
game-linux:
scons use_llvm=$(USE_LLVM) target=$(RELEASE_TYPE) target_path=godot/gdnative/ target_name=libjuego platform=linux bits=64 -j $(PROCS)
game-windows:
scons target=$(RELEASE_TYPE) target_name=libjuego target_path=godot/gdnative/ platform=windows bits=64 -j $(PROCS)
docs:
# if doxygen and bear are installed create the code documentation
ifneq (, $(shell which bear))
ifeq (, $(wildcard ./compile_commands.json))
$(MAKE) clean-docs
$(MAKE) bear
endif
ifneq (, $(shell which doxygen))
doxygen doxygen.conf
make -C docs/latex
endif
endif
bear:
bear make linux
clean: clean-godot-cpp clean-game clean-docs
clean-godot-cpp:
pushd godot-cpp; scons -c
rm -f godot-cpp/bin/*
clean-game:
find ./src -name "*.os" -type f -delete
rm -rf gdnative/{linux,windows}.*
clean-docs:
rm -rf docs
rm -rf compile_commands.json
.PHONY: all linux init godot-cpp godot-cpp-linux godot-cpp-windows game game-linux game-windows clean clean-godot-cpp clean-game clean-docs clean-docs docs bear

126
SConstruct Normal file
View File

@ -0,0 +1,126 @@
#!python
import os
import sys
import glob
opts = Variables([], ARGUMENTS)
# Gets the standard flags CC, CCX, etc.
env = DefaultEnvironment()
if sys.platform.startswith('linux'):
host_platform = 'linux'
elif sys.platform == 'win32' or sys.platform == 'msys':
host_platform = 'windows'
else:
raise ValueError(
'Could not detect platform automatically, please specify with '
'platform=<platform>'
)
# Define our options
opts.Add(EnumVariable('target', "Compilation target", 'debug', ['debug', 'release']))
opts.Add(EnumVariable('platform', "Compilation platform", host_platform, ['windows', 'linux']))
opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no'))
opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'gdnative/'))
opts.Add(PathVariable('target_name', 'The library name.', 'libgdnative', PathVariable.PathAccept))
opts.Add(EnumVariable(
'bits',
'Target platform bits',
'64',
['64']
))
# Local dependency paths, adapt them to your setup
godot_headers_path = "godot-cpp/godot-headers/"
cpp_bindings_path = "godot-cpp/"
cpp_library = "libgodot-cpp"
# Updates the environment with the option variables.
opts.Update(env)
# Process some arguments
if env['use_llvm']:
env['CC'] = 'clang'
env['CXX'] = 'clang++'
# For the reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
# - CXXFLAGS are for C++-specific compilation flags
# - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
# Check our platform specifics
if env['platform'] == 'linux':
env['target_path'] += 'linux.' + env['bits'] + '/'
cpp_library += '.linux'
env.Append(CCFLAGS=['-fPIC'])
env.Append(CXXFLAGS=['-std=c++17'])
if env['target'] == 'debug':
env.Append(CCFLAGS=['-g3', '-Og'])
else:
env.Append(CCFLAGS=['-g', '-O3'])
env.Append(CCFLAGS=['-m64'])
env.Append(LINKFLAGS=['-m64'])
env['target_name'] += '.so'
elif env['platform'] == "windows":
env['CC'] = 'x86_64-w64-mingw32-gcc'
env['CXX'] = 'x86_64-w64-mingw32-g++'
env['AR'] = "x86_64-w64-mingw32-ar"
env['RANLIB'] = "x86_64-w64-mingw32-ranlib"
env['LINK'] = "x86_64-w64-mingw32-g++"
env['target_path'] += 'windows.' + env['bits'] + '/'
cpp_library += '.windows'
# This makes sure to keep the session environment variables on windows,
# that way you can run scons in a vs 2017 prompt and it will find all the required tools
env.Append(ENV=os.environ)
env.Append(LINKFLAGS=[
'--static',
'-Wl,--no-undefined',
'-static-libgcc',
'-static-libstdc++',
])
env.Append(CPPDEFINES=['WIN32', '_WIN32', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS'])
#env.Append(CCFLAGS=['-W3', '-GR'])
if env['target'] == 'debug':
env.Append(CPPDEFINES=['_DEBUG'])
#env.Append(CCFLAGS=['-EHsc', '-MDd', '-ZI'])
env.Append(LINKFLAGS=['-DEBUG'])
else:
env.Append(CPPDEFINES=['NDEBUG'])
#env.Append(CCFLAGS=['-O2', '-EHsc', '-MD'])
env.Append(CCFLAGS=['-O2'])
env['target_name'] += '.dll'
if env['target'] == 'debug':
cpp_library += '.debug'
else:
cpp_library += '.release'
cpp_library += '.' + str(env['bits'])
# make sure our binding library is properly includes
env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', 'src/include/', 'lib/include'])
env.Append(LIBPATH=[cpp_bindings_path + 'bin/'])
env.Append(LIBS=[cpp_library])
# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=['src/'])
sources = glob.glob('src/**/*.cpp', recursive=True)
sources += glob.glob('src/**/*.c', recursive=True)
library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)
Default(library)
# Generates help for the -h scons option.
Help(opts.GenerateHelpText(env))

2579
doxygen.conf Normal file

File diff suppressed because it is too large Load Diff

1
godot-cpp Submodule

@ -0,0 +1 @@
Subproject commit ced274fbe62c07dd9bb6791a77392f4bdc625152

42
godot/Level 1.tscn Normal file
View File

@ -0,0 +1,42 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/backgrounds/mountains.png" type="Texture" id=1]
[ext_resource path="res://levels/level01.tmx" type="PackedScene" id=3]
[ext_resource path="res://characters/player/Player.tscn" type="PackedScene" id=4]
[node name="Level 1" type="Node2D"]
[node name="Player" parent="." instance=ExtResource( 4 )]
position = Vector2( 8, 5 )
[node name="Camera2D" type="Camera2D" parent="Player"]
current = true
limit_left = 0
limit_top = 0
limit_right = 2304
limit_bottom = 576
drag_margin_h_enabled = true
drag_margin_v_enabled = true
editor_draw_limits = true
editor_draw_drag_margin = true
__meta__ = {
"_edit_bone_": true
}
[node name="VisibilityNotifier2D" type="VisibilityNotifier2D" parent="Player/Camera2D"]
rect = Rect2( 0, 0, 24, 24 )
[node name="ParallaxBackground" type="ParallaxBackground" parent="."]
[node name="ParallaxLayer" type="ParallaxLayer" parent="ParallaxBackground"]
motion_scale = Vector2( 0.2, 1 )
motion_mirroring = Vector2( 528, 0 )
[node name="Sprite" type="Sprite" parent="ParallaxBackground/ParallaxLayer"]
texture = ExtResource( 1 )
centered = false
[node name="Map" type="Node2D" parent="."]
position = Vector2( 0, 18 )
[node name="level01" parent="Map" instance=ExtResource( 3 )]

8
godot/Main.gdns Normal file
View File

@ -0,0 +1,8 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://gdnative/libjuego.tres" type="GDNativeLibrary" id=1]
[resource]
resource_name = "Main"
class_name = "Main"
library = ExtResource( 1 )

10
godot/Main.tscn Normal file
View File

@ -0,0 +1,10 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://Main.gdns" type="Script" id=1]
[ext_resource path="res://Level 1.tscn" type="PackedScene" id=2]
[node name="Main" type="Node"]
script = ExtResource( 1 )
launch_screen = 0
[node name="Level 1" parent="." instance=ExtResource( 2 )]

View File

@ -0,0 +1,8 @@
config_version=3
[plugin]
name="Tiled Map Importer"
description="Importer for TileMaps and TileSets made on Tiled Map Editor"
version="2.3"
author="George Marques"
script="vnen.tiled_importer.gd"

View File

@ -0,0 +1,67 @@
# The MIT License (MIT)
#
# Copyright (c) 2018 George Marques
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Sorter for polygon vertices
tool
extends Reference
var center
# Sort the vertices of a convex polygon to clockwise order
# Receives a PoolVector2Array and returns a new one
func sort_polygon(vertices):
vertices = Array(vertices)
var centroid = Vector2()
var size = vertices.size()
for i in range(0, size):
centroid += vertices[i]
centroid /= size
center = centroid
vertices.sort_custom(self, "is_less")
return PoolVector2Array(vertices)
# Sorter function, determines which of the poins should come first
func is_less(a, b):
if a.x - center.x >= 0 and b.x - center.x < 0:
return false
elif a.x - center.x < 0 and b.x - center.x >= 0:
return true
elif a.x - center.x == 0 and b.x - center.x == 0:
if a.y - center.y >= 0 or b.y - center.y >= 0:
return a.y < b.y
return a.y > b.y
var det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y)
if det > 0:
return true
elif det < 0:
return false
var d1 = (a - center).length_squared()
var d2 = (b - center).length_squared()
return d1 < d2

BIN
godot/addons/vnen.tiled_importer/tiled.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/tiled.png-dbbabe58e4f927769540a522a2073689.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/vnen.tiled_importer/tiled.png"
dest_files=[ "res://.import/tiled.png-dbbabe58e4f927769540a522a2073689.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -0,0 +1,141 @@
# The MIT License (MIT)
#
# Copyright (c) 2018 George Marques
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
tool
extends EditorImportPlugin
enum { PRESET_DEFAULT, PRESET_PIXEL_ART }
const TiledMapReader = preload("tiled_map_reader.gd")
func get_importer_name():
return "vnen.tiled_importer"
func get_visible_name():
return "Scene from Tiled"
func get_recognized_extensions():
if ProjectSettings.get_setting("tiled_importer/enable_json_format"):
return ["json", "tmx"]
else:
return ["tmx"]
func get_save_extension():
return "scn"
func get_priority():
return 1
func get_import_order():
return 100
func get_resource_type():
return "PackedScene"
func get_preset_count():
return 2
func get_preset_name(preset):
match preset:
PRESET_DEFAULT: return "Default"
PRESET_PIXEL_ART: return "Pixel Art"
func get_import_options(preset):
return [
{
"name": "custom_properties",
"default_value": true
},
{
"name": "tile_metadata",
"default_value": false
},
{
"name": "uv_clip",
"default_value": true
},
{
"name": "image_flags",
"default_value": 0 if preset == PRESET_PIXEL_ART else Texture.FLAGS_DEFAULT,
"property_hint": PROPERTY_HINT_FLAGS,
"hint_string": "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"
},
{
"name": "collision_layer",
"default_value": 1,
"property_hint": PROPERTY_HINT_LAYERS_2D_PHYSICS
},
{
"name": "embed_internal_images",
"default_value": true if preset == PRESET_PIXEL_ART else false
},
{
"name": "save_tiled_properties",
"default_value": false
},
{
"name": "add_background",
"default_value": true
},
{
"name": "post_import_script",
"default_value": "",
"property_hint": PROPERTY_HINT_FILE,
"hint_string": "*.gd;GDScript"
}
]
func get_option_visibility(option, options):
return true
func import(source_file, save_path, options, r_platform_variants, r_gen_files):
var map_reader = TiledMapReader.new()
# Offset is only optional for importing TileSets
options.apply_offset = true
var scene = map_reader.build(source_file, options)
if typeof(scene) != TYPE_OBJECT:
# Error happened
return scene
# Post imports script
if not options.post_import_script.empty():
var script = load(options.post_import_script)
if not script or not script is GDScript:
printerr("Post import script is not a GDScript.")
return ERR_INVALID_PARAMETER
script = script.new()
if not script.has_method("post_import"):
printerr("Post import script does not have a 'post_import' method.")
return ERR_INVALID_PARAMETER
scene = script.post_import(scene)
if not scene or not scene is Node2D:
printerr("Invalid scene returned from post import script.")
return ERR_INVALID_DATA
var packed_scene = PackedScene.new()
packed_scene.pack(scene)
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], packed_scene)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
# The MIT License (MIT)
#
# Copyright (c) 2018 George Marques
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
tool
extends EditorImportPlugin
enum { PRESET_DEFAULT, PRESET_PIXEL_ART }
const TiledMapReader = preload("tiled_map_reader.gd")
func get_importer_name():
return "vnen.tiled_tileset_importer"
func get_visible_name():
return "TileSet from Tiled"
func get_recognized_extensions():
if ProjectSettings.get_setting("tiled_importer/enable_json_format"):
return ["json", "tsx"]
else:
return ["tsx"]
func get_save_extension():
return "res"
func get_resource_type():
return "TileSet"
func get_preset_count():
return 2
func get_preset_name(preset):
match preset:
PRESET_DEFAULT: return "Default"
PRESET_PIXEL_ART: return "Pixel Art"
func get_import_options(preset):
return [
{
"name": "custom_properties",
"default_value": true
},
{
"name": "tile_metadata",
"default_value": false
},
{
"name": "image_flags",
"default_value": 0 if preset == PRESET_PIXEL_ART else Texture.FLAGS_DEFAULT,
"property_hint": PROPERTY_HINT_FLAGS,
"hint_string": "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"
},
{
"name": "embed_internal_images",
"default_value": true if preset == PRESET_PIXEL_ART else false
},
{
"name": "save_tiled_properties",
"default_value": false
},
{
"name": "apply_offset",
"default_value": false
},
{
"name": "post_import_script",
"default_value": "",
"property_hint": PROPERTY_HINT_FILE,
"hint_string": "*.gd;GDScript"
}
]
func get_option_visibility(option, options):
return true
func import(source_file, save_path, options, r_platform_variants, r_gen_files):
var map_reader = TiledMapReader.new()
var tileset = map_reader.build_tileset(source_file, options)
if typeof(tileset) != TYPE_OBJECT:
# Error happened
return tileset
# Post imports script
if not options.post_import_script.empty():
var script = load(options.post_import_script)
if not script or not script is GDScript:
printerr("Post import script is not a GDScript.")
return ERR_INVALID_PARAMETER
script = script.new()
if not script.has_method("post_import"):
printerr("Post import script does not have a 'post_import' method.")
return ERR_INVALID_PARAMETER
tileset = script.post_import(tileset)
if not tileset or not tileset is TileSet:
printerr("Invalid TileSet returned from post import script.")
return ERR_INVALID_DATA
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], tileset)

View File

@ -0,0 +1,571 @@
# The MIT License (MIT)
#
# Copyright (c) 2018 George Marques
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
tool
extends Reference
# Reads a TMX file from a path and return a Dictionary with the same structure
# as the JSON map format
# Returns an error code if failed
func read_tmx(path):
var parser = XMLParser.new()
var err = parser.open(path)
if err != OK:
printerr("Error opening TMX file '%s'." % [path])
return err
while parser.get_node_type() != XMLParser.NODE_ELEMENT:
err = parser.read()
if err != OK:
printerr("Error parsing TMX file '%s' (around line %d)." % [path, parser.get_current_line()])
return err
if parser.get_node_name().to_lower() != "map":
printerr("Error parsing TMX file '%s'. Expected 'map' element.")
return ERR_INVALID_DATA
var data = attributes_to_dict(parser)
if not "infinite" in data:
data.infinite = false
data.type = "map"
data.tilesets = []
data.layers = []
err = parser.read()
if err != OK:
printerr("Error parsing TMX file '%s' (around line %d)." % [path, parser.get_current_line()])
return err
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "map":
break
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "tileset":
# Empty element means external tileset
if not parser.is_empty():
var tileset = parse_tileset(parser)
if typeof(tileset) != TYPE_DICTIONARY:
# Error happened
return err
data.tilesets.push_back(tileset)
else:
var tileset_data = attributes_to_dict(parser)
if not "source" in tileset_data:
printerr("Error parsing TMX file '%s'. Missing tileset source (around line %d)." % [path, parser.get_current_line()])
return ERR_INVALID_DATA
data.tilesets.push_back(tileset_data)
elif parser.get_node_name() == "layer":
var layer = parse_tile_layer(parser, data.infinite)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file '%s'. Invalid tile layer data (around line %d)." % [path, parser.get_current_line()])
return ERR_INVALID_DATA
data.layers.push_back(layer)
elif parser.get_node_name() == "imagelayer":
var layer = parse_image_layer(parser)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file '%s'. Invalid image layer data (around line %d)." % [path, parser.get_current_line()])
return ERR_INVALID_DATA
data.layers.push_back(layer)
elif parser.get_node_name() == "objectgroup":
var layer = parse_object_layer(parser)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file '%s'. Invalid object layer data (around line %d)." % [path, parser.get_current_line()])
return ERR_INVALID_DATA
data.layers.push_back(layer)
elif parser.get_node_name() == "group":
var layer = parse_group_layer(parser, data.infinite)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file '%s'. Invalid group layer data (around line %d)." % [path, parser.get_current_line()])
return ERR_INVALID_DATA
data.layers.push_back(layer)
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
if typeof(prop_data) == TYPE_STRING:
return prop_data
data.properties = prop_data.properties
data.propertytypes = prop_data.propertytypes
err = parser.read()
return data
# Reads a TSX and return a tileset dictionary
# Returns an error code if fails
func read_tsx(path):
var parser = XMLParser.new()
var err = parser.open(path)
if err != OK:
printerr("Error opening TSX file '%s'." % [path])
return err
while parser.get_node_type() != XMLParser.NODE_ELEMENT:
err = parser.read()
if err != OK:
printerr("Error parsing TSX file '%s' (around line %d)." % [path, parser.get_current_line()])
return err
if parser.get_node_name().to_lower() != "tileset":
printerr("Error parsing TMX file '%s'. Expected 'map' element.")
return ERR_INVALID_DATA
var tileset = parse_tileset(parser)
return tileset
# Parses a tileset element from the XML and return a dictionary
# Return an error code if fails
func parse_tileset(parser):
var err = OK
var data = attributes_to_dict(parser)
data.tiles = {}
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "tileset":
break
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "tile":
var attr = attributes_to_dict(parser)
var tile_data = parse_tile_data(parser)
if typeof(tile_data) != TYPE_DICTIONARY:
# Error happened
return tile_data
if "properties" in tile_data and "propertytypes" in tile_data:
if not "tileproperties" in data:
data.tileproperties = {}
data.tilepropertytypes = {}
data.tileproperties[str(attr.id)] = tile_data.properties
data.tilepropertytypes[str(attr.id)] = tile_data.propertytypes
tile_data.erase("tileproperties")
tile_data.erase("tilepropertytypes")
data.tiles[str(attr.id)] = tile_data
elif parser.get_node_name() == "image":
var attr = attributes_to_dict(parser)
if not "source" in attr:
printerr("Error loading image tag. No source attribute found (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
data.image = attr.source
if "width" in attr:
data.imagewidth = attr.width
if "height" in attr:
data.imageheight = attr.height
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
if typeof(prop_data) != TYPE_DICTIONARY:
# Error happened
return prop_data
data.properties = prop_data.properties
data.propertytypes = prop_data.propertytypes
err = parser.read()
return data
# Parses the data of a single tile from the XML and return a dictionary
# Returns an error code if fails
func parse_tile_data(parser):
var err = OK
var data = {}
var obj_group = {}
if parser.is_empty():
return data
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "tile":
return data
elif parser.get_node_name() == "objectgroup":
data.objectgroup = obj_group
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "image":
# If there are multiple images in one tile we only use the last one.
var attr = attributes_to_dict(parser)
if not "source" in attr:
printerr("Error loading image tag. No source attribute found (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
data.image = attr.source
data.imagewidth = attr.width
data.imageheight = attr.height
elif parser.get_node_name() == "objectgroup":
obj_group = attributes_to_dict(parser)
for attr in ["width", "height", "offsetx", "offsety"]:
if not attr in obj_group:
data[attr] = 0
if not "opacity" in data:
data.opacity = 1
if not "visible" in data:
data.visible = true
if parser.is_empty():
data.objectgroup = obj_group
elif parser.get_node_name() == "object":
if not "objects" in obj_group:
obj_group.objects = []
var obj = parse_object(parser)
if typeof(obj) != TYPE_DICTIONARY:
# Error happened
return obj
obj_group.objects.push_back(obj)
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
data["properties"] = prop_data.properties
data["propertytypes"] = prop_data.propertytypes
elif parser.get_node_name() == "animation":
var frame_list = []
var err2 = parser.read()
while err2 == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "frame":
var frame = {"tileid": 0, "duration": 0}
for i in parser.get_attribute_count():
if parser.get_attribute_name(i) == "tileid":
frame["tileid"] = parser.get_attribute_value(i)
if parser.get_attribute_name(i) == "duration":
frame["duration"] = parser.get_attribute_value(i)
frame_list.push_back(frame)
elif parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "animation":
break
err2 = parser.read()
data["animation"] = frame_list
err = parser.read()
return data
# Parses the data of a single object from the XML and return a dictionary
# Returns an error code if fails
static func parse_object(parser):
var err = OK
var data = attributes_to_dict(parser)
if not parser.is_empty():
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "object":
break
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
data["properties"] = prop_data.properties
data["propertytypes"] = prop_data.propertytypes
elif parser.get_node_name() == "point":
data.point = true
elif parser.get_node_name() == "ellipse":
data.ellipse = true
elif parser.get_node_name() == "polygon" or parser.get_node_name() == "polyline":
var points = []
var points_raw = parser.get_named_attribute_value("points").split(" ", false, 0)
for pr in points_raw:
points.push_back({
"x": float(pr.split(",")[0]),
"y": float(pr.split(",")[1]),
})
data[parser.get_node_name()] = points
err = parser.read()
return data
# Parses a tile layer from the XML and return a dictionary
# Returns an error code if fails
func parse_tile_layer(parser, infinite):
var err = OK
var data = attributes_to_dict(parser)
data.type = "tilelayer"
if not "x" in data:
data.x = 0
if not "y" in data:
data.y = 0
if infinite:
data.chunks = []
else:
data.data = []
var current_chunk = null
var encoding = ""
if not parser.is_empty():
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "layer":
break
elif parser.get_node_name() == "chunk":
data.chunks.push_back(current_chunk)
current_chunk = null
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "data":
var attr = attributes_to_dict(parser)
if "compression" in attr:
data.compression = attr.compression
if "encoding" in attr:
encoding = attr.encoding
if attr.encoding != "csv":
data.encoding = attr.encoding
if not infinite:
err = parser.read()
if err != OK:
return err
if attr.encoding != "csv":
data.data = parser.get_node_data().strip_edges()
else:
var csv = parser.get_node_data().split(",", false)
for v in csv:
data.data.push_back(int(v.strip_edges()))
elif parser.get_node_name() == "tile":
var gid = int(parser.get_named_attribute_value_safe("gid"))
if infinite:
current_chunk.data.push_back(gid)
else:
data.data.push_back(gid)
elif parser.get_node_name() == "chunk":
current_chunk = attributes_to_dict(parser)
current_chunk.data = []
if encoding != "":
err = parser.read()
if err != OK:
return err
if encoding != "csv":
current_chunk.data = parser.get_node_data().strip_edges()
else:
var csv = parser.get_node_data().split(",", false)
for v in csv:
current_chunk.data.push_back(int(v.strip_edges()))
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
if typeof(prop_data) == TYPE_STRING:
return prop_data
data.properties = prop_data.properties
data.propertytypes = prop_data.propertytypes
err = parser.read()
return data
# Parses an object layer from the XML and return a dictionary
# Returns an error code if fails
func parse_object_layer(parser):
var err = OK
var data = attributes_to_dict(parser)
data.type = "objectgroup"
data.objects = []
if not parser.is_empty():
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "objectgroup":
break
if parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "object":
data.objects.push_back(parse_object(parser))
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
if typeof(prop_data) != TYPE_DICTIONARY:
# Error happened
return prop_data
data.properties = prop_data.properties
data.propertytypes = prop_data.propertytypes
err = parser.read()
return data
# Parses an image layer from the XML and return a dictionary
# Returns an error code if fails
func parse_image_layer(parser):
var err = OK
var data = attributes_to_dict(parser)
data.type = "imagelayer"
data.image = ""
if not parser.is_empty():
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name().to_lower() == "imagelayer":
break
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name().to_lower() == "image":
var image = attributes_to_dict(parser)
if not image.has("source"):
printerr("Missing source attribute in imagelayer (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
data.image = image.source
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
if typeof(prop_data) != TYPE_DICTIONARY:
# Error happened
return prop_data
data.properties = prop_data.properties
data.propertytypes = prop_data.propertytypes
err = parser.read()
return data
# Parses a group layer from the XML and return a dictionary
# Returns an error code if fails
func parse_group_layer(parser, infinite):
var err = OK
var result = attributes_to_dict(parser)
result.type = "group"
result.layers = []
if not parser.is_empty():
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name().to_lower() == "group":
break
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "layer":
var layer = parse_tile_layer(parser, infinite)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file. Invalid tile layer data (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
result.layers.push_back(layer)
elif parser.get_node_name() == "imagelayer":
var layer = parse_image_layer(parser)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file. Invalid image layer data (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
result.layers.push_back(layer)
elif parser.get_node_name() == "objectgroup":
var layer = parse_object_layer(parser)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file. Invalid object layer data (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
result.layers.push_back(layer)
elif parser.get_node_name() == "group":
var layer = parse_group_layer(parser, infinite)
if typeof(layer) != TYPE_DICTIONARY:
printerr("Error parsing TMX file. Invalid group layer data (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
result.layers.push_back(layer)
elif parser.get_node_name() == "properties":
var prop_data = parse_properties(parser)
if typeof(prop_data) == TYPE_STRING:
return prop_data
result.properties = prop_data.properties
result.propertytypes = prop_data.propertytypes
err = parser.read()
return result
# Parses properties data from the XML and return a dictionary
# Returns an error code if fails
static func parse_properties(parser):
var err = OK
var data = {
"properties": {},
"propertytypes": {},
}
if not parser.is_empty():
err = parser.read()
while err == OK:
if parser.get_node_type() == XMLParser.NODE_ELEMENT_END:
if parser.get_node_name() == "properties":
break
elif parser.get_node_type() == XMLParser.NODE_ELEMENT:
if parser.get_node_name() == "property":
var prop_data = attributes_to_dict(parser)
if not (prop_data.has("name") and prop_data.has("value")):
printerr("Missing information in custom properties (around line %d)." % [parser.get_current_line()])
return ERR_INVALID_DATA
data.properties[prop_data.name] = prop_data.value
if prop_data.has("type"):
data.propertytypes[prop_data.name] = prop_data.type
else:
data.propertytypes[prop_data.name] = "string"
err = parser.read()
return data
# Reads the attributes of the current element and return them as a dictionary
static func attributes_to_dict(parser):
var data = {}
for i in range(parser.get_attribute_count()):
var attr = parser.get_attribute_name(i)
var val = parser.get_attribute_value(i)
if val.is_valid_integer():
val = int(val)
elif val.is_valid_float():
val = float(val)
elif val == "true":
val = true
elif val == "false":
val = false
data[attr] = val
return data

View File

@ -0,0 +1,45 @@
# The MIT License (MIT)
#
# Copyright (c) 2018 George Marques
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
tool
extends EditorPlugin
var import_plugin = null
var tileset_import_plugin = null
func get_name():
return "Tiled Map Importer"
func _enter_tree():
if not ProjectSettings.has_setting("tiled_importer/enable_json_format"):
ProjectSettings.set_setting("tiled_importer/enable_json_format", true)
import_plugin = preload("tiled_import_plugin.gd").new()
tileset_import_plugin = preload("tiled_tileset_import_plugin.gd").new()
add_import_plugin(import_plugin)
add_import_plugin(tileset_import_plugin)
func _exit_tree():
remove_import_plugin(import_plugin)
remove_import_plugin(tileset_import_plugin)
import_plugin = null
tileset_import_plugin = null

BIN
godot/assets/backgrounds/backgrounds.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/backgrounds.png-cc89c89c97d5c98a98850451c0fa7edd.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/backgrounds/backgrounds.png"
dest_files=[ "res://.import/backgrounds.png-cc89c89c97d5c98a98850451c0fa7edd.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
godot/assets/backgrounds/clouds.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/clouds.png-fe4f96696b832900798d087a161278ef.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/backgrounds/clouds.png"
dest_files=[ "res://.import/clouds.png-fe4f96696b832900798d087a161278ef.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
godot/assets/backgrounds/hills.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/hills.png-9e8a68b5d948be00b7e490843ae82144.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/backgrounds/hills.png"
dest_files=[ "res://.import/hills.png-9e8a68b5d948be00b7e490843ae82144.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
godot/assets/backgrounds/mountains.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/mountains.png-96679ccef90f2ee3cba491525d7105a8.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/backgrounds/mountains.png"
dest_files=[ "res://.import/mountains.png-96679ccef90f2ee3cba491525d7105a8.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
godot/assets/backgrounds/snow.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/snow.png-4b17f212ca9744d6969afa2c14de7569.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/backgrounds/snow.png"
dest_files=[ "res://.import/snow.png-4b17f212ca9744d6969afa2c14de7569.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
godot/assets/characters/characters.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/characters.png-d7b5ef72f573868f6fc3e4ed116a4ea7.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/characters/characters.png"
dest_files=[ "res://.import/characters.png-d7b5ef72f573868f6fc3e4ed116a4ea7.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
godot/assets/tiles/tiles.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/tiles.png-5543c94a7422728438498b2cd4eb36c8.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/tiles/tiles.png"
dest_files=[ "res://.import/tiles.png-5543c94a7422728438498b2cd4eb36c8.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@ -0,0 +1,8 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://gdnative/libjuego.tres" type="GDNativeLibrary" id=1]
[resource]
resource_name = "Player"
class_name = "Player"
library = ExtResource( 1 )

View File

@ -0,0 +1,22 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://characters/player/sprites/green.tres" type="SpriteFrames" id=1]
[ext_resource path="res://characters/player/Player.gdns" type="Script" id=2]
[sub_resource type="CapsuleShape2D" id=1]
radius = 6.0
height = 12.0
[node name="Player" type="KinematicBody2D"]
script = ExtResource( 2 )
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
frames = ExtResource( 1 )
animation = "idle"
centered = false
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2( 12, 12 )
shape = SubResource( 1 )
[connection signal="player_moved" from="." to="." method="_on_Player_player_moved"]

View File

@ -0,0 +1,37 @@
[gd_resource type="SpriteFrames" load_steps=6 format=2]
[ext_resource path="res://assets/characters/characters.png" type="Texture" id=1]
[sub_resource type="AtlasTexture" id=1]
atlas = ExtResource( 1 )
region = Rect2( 0, 24, 24, 24 )
[sub_resource type="AtlasTexture" id=2]
atlas = ExtResource( 1 )
region = Rect2( 24, 24, 24, 24 )
[sub_resource type="AtlasTexture" id=4]
atlas = ExtResource( 1 )
region = Rect2( 24, 24, 24, 24 )
[sub_resource type="AtlasTexture" id=3]
atlas = ExtResource( 1 )
region = Rect2( 0, 24, 24, 24 )
[resource]
animations = [ {
"frames": [ SubResource( 1 ) ],
"loop": true,
"name": "idle",
"speed": 5.0
}, {
"frames": [ SubResource( 2 ) ],
"loop": true,
"name": "air",
"speed": 5.0
}, {
"frames": [ SubResource( 4 ), SubResource( 3 ) ],
"loop": true,
"name": "move",
"speed": 3.0
} ]

View File

@ -0,0 +1,37 @@
[gd_resource type="SpriteFrames" load_steps=6 format=2]
[ext_resource path="res://assets/characters/characters.png" type="Texture" id=1]
[sub_resource type="AtlasTexture" id=5]
atlas = ExtResource( 1 )
region = Rect2( 48, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=4]
atlas = ExtResource( 1 )
region = Rect2( 72, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=7]
atlas = ExtResource( 1 )
region = Rect2( 72, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=6]
atlas = ExtResource( 1 )
region = Rect2( 48, 0, 24, 24 )
[resource]
animations = [ {
"frames": [ SubResource( 5 ) ],
"loop": true,
"name": "idle",
"speed": 5.0
}, {
"frames": [ SubResource( 4 ) ],
"loop": true,
"name": "air",
"speed": 5.0
}, {
"frames": [ SubResource( 7 ), SubResource( 6 ) ],
"loop": true,
"name": "move",
"speed": 3.0
} ]

View File

@ -0,0 +1,37 @@
[gd_resource type="SpriteFrames" load_steps=6 format=2]
[ext_resource path="res://assets/characters/characters.png" type="Texture" id=1]
[sub_resource type="AtlasTexture" id=3]
atlas = ExtResource( 1 )
region = Rect2( 0, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=4]
atlas = ExtResource( 1 )
region = Rect2( 24, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=2]
atlas = ExtResource( 1 )
region = Rect2( 24, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=1]
atlas = ExtResource( 1 )
region = Rect2( 0, 0, 24, 24 )
[resource]
animations = [ {
"frames": [ SubResource( 3 ) ],
"loop": true,
"name": "idle",
"speed": 5.0
}, {
"frames": [ SubResource( 4 ) ],
"loop": true,
"name": "air",
"speed": 5.0
}, {
"frames": [ SubResource( 2 ), SubResource( 1 ) ],
"loop": true,
"name": "move",
"speed": 3.0
} ]

View File

@ -0,0 +1,37 @@
[gd_resource type="SpriteFrames" load_steps=6 format=2]
[ext_resource path="res://assets/characters/characters.png" type="Texture" id=1]
[sub_resource type="AtlasTexture" id=1]
atlas = ExtResource( 1 )
region = Rect2( 96, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=2]
atlas = ExtResource( 1 )
region = Rect2( 120, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=4]
atlas = ExtResource( 1 )
region = Rect2( 120, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=3]
atlas = ExtResource( 1 )
region = Rect2( 96, 0, 24, 24 )
[resource]
animations = [ {
"frames": [ SubResource( 1 ) ],
"loop": true,
"name": "idle",
"speed": 5.0
}, {
"frames": [ SubResource( 2 ) ],
"loop": true,
"name": "air",
"speed": 5.0
}, {
"frames": [ SubResource( 4 ), SubResource( 3 ) ],
"loop": true,
"name": "move",
"speed": 3.0
} ]

View File

@ -0,0 +1,37 @@
[gd_resource type="SpriteFrames" load_steps=6 format=2]
[ext_resource path="res://assets/characters/characters.png" type="Texture" id=1]
[sub_resource type="AtlasTexture" id=1]
atlas = ExtResource( 1 )
region = Rect2( 144, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=2]
atlas = ExtResource( 1 )
region = Rect2( 168, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=4]
atlas = ExtResource( 1 )
region = Rect2( 168, 0, 24, 24 )
[sub_resource type="AtlasTexture" id=3]
atlas = ExtResource( 1 )
region = Rect2( 144, 0, 24, 24 )
[resource]
animations = [ {
"frames": [ SubResource( 1 ) ],
"loop": true,
"name": "idle",
"speed": 5.0
}, {
"frames": [ SubResource( 2 ) ],
"loop": true,
"name": "air",
"speed": 5.0
}, {
"frames": [ SubResource( 4 ), SubResource( 3 ) ],
"loop": true,
"name": "move",
"speed": 3.0
} ]

View File

@ -1,5 +1,7 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

View File

@ -0,0 +1,7 @@
[gd_resource type="GDNativeLibrary" format=2]
[resource]
entry/Windows.64 = "res://gdnative/windows.64/libjuego.dll"
entry/X11.64 = "res://gdnative/linux.64/libjuego.so"
dependency/Windows.64 = [ ]
dependency/X11.64 = [ ]

BIN
godot/icon.png (Stored with Git LFS) Normal file

Binary file not shown.

12
godot/juego.tiled-project Normal file
View File

@ -0,0 +1,12 @@
{
"automappingRulesFile": "",
"commands": [
],
"extensionsPath": "extensions",
"folders": [
"."
],
"objectTypesFile": "",
"propertyTypes": [
]
}

285
godot/juego.tiled-session Normal file
View File

@ -0,0 +1,285 @@
{
"Map/SizeTest": {
"height": 4300,
"width": 2
},
"activeFile": "levels/level01.tmx",
"expandedProjectPaths": [
"tilesets",
"levels",
".",
"parallax"
],
"exportAsImage.useCurrentScale": false,
"file.lastUsedOpenFilter": "All Files (*)",
"fileStates": {
"": {
"scaleInDock": 1
},
"#backgrounds": {
"scaleInDock": 1
},
"/home/cromer/projects/edx/games/azaraka/misc/new-graphics/tf_darkdimension_updated2020/RMMV/tf_dd_B_3.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/home/cromer/projects/edx/games/azaraka/misc/new-graphics/tf_darkdimension_updated2020/dd_waterfall_sheet.tsx": {
"scaleInDock": 1,
"scaleInEditor": 2
},
"/home/cromer/projects/edx/games/azaraka/misc/new-graphics/tf_darkdimension_updated2020/tf_darkdimension_sheet.tsx": {
"scaleInDock": 2,
"scaleInEditor": 2
},
"/home/cromer/projects/edx/games/azaraka/misc/new-graphics/tf_darkdimension_updated2020/untitled.tmx": {
"scale": 2,
"selectedLayer": 3,
"viewCenter": {
"x": 465.75,
"y": 233.5
}
},
"/home/cromer/tilemaps/Dungeon.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/home/cromer/tilemaps/Grassland.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/home/cromer/tilemaps/dungeon_entrance.tmx": {
"scale": 0.53140625,
"selectedLayer": 0,
"viewCenter": {
"x": 902.3228462216996,
"y": 825.1690679211997
}
},
"/home/cromer/tilemaps/untitled.tmx": {
"scale": 0.53140625,
"selectedLayer": 1,
"viewCenter": {
"x": 798.8238753307851,
"y": 798.8238753307851
}
},
"/mnt/data/godot/projects/Azaraka/maps/cloud_city.tsx": {
"scaleInDock": 0.5
},
"/mnt/data/godot/projects/Azaraka/maps/dungeon1.tmx": {
"scale": 0.75,
"selectedLayer": 0,
"viewCenter": {
"x": 1209.3333333333333,
"y": 672
}
},
"/mnt/data/godot/projects/Azaraka/maps/shadowset.tsx": {
"scaleInDock": 1
},
"/mnt/data/godot/projects/Azaraka/maps/terrain.tsx": {
"scaleInDock": 0.75
},
"/mnt/data/godot/projects/Azaraka/maps/worldmap.tmx": {
"scale": 0.03125,
"selectedLayer": 0,
"viewCenter": {
"x": 10496,
"y": 2592
}
},
"/mnt/data/godot/projects/Azaraka/maps/worldmap.tsx": {
"scaleInDock": 0.33
},
"/mnt/data/godot/projects/Platformer/asset/spritesheet_ground.tsx": {
"scaleInDock": 0.125,
"scaleInEditor": 0.75
},
"/mnt/data/godot/projects/Platformer/asset/world.tmx": {
"scale": 0.5,
"selectedLayer": 0,
"viewCenter": {
"x": 1326,
"y": 1210
}
},
"/mnt/data/godot/projects/Platformer/asset/world1.tmx": {
"scale": 0.5714843749999999,
"selectedLayer": 0,
"viewCenter": {
"x": 640.4374572795626,
"y": 640.4374572795626
}
},
"/mnt/data/projects/edx/games/azaraka/maps/tilesets/grassland_shadows.tsx": {
"scaleInDock": 1
},
"/mnt/data/projects/edx/games/azaraka/maps/tilesets/grassland_spring.tsx": {
"scaleInDock": 1
},
"/mnt/data/projects/edx/games/azaraka/maps/tilesets/grassland_spring_water.tsx": {
"scaleInDock": 1
},
"/mnt/data/projects/edx/games/azaraka/maps/tilesets/grassland_spring_waterfall.tsx": {
"scaleInDock": 1
},
"/mnt/data/projects/edx/games/project/graphics/dungeon.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1.5
},
"/mnt/data/projects/edx/games/project/graphics/dungeon_entrance.tmx": {
"scale": 1,
"selectedLayer": 3,
"viewCenter": {
"x": 320,
"y": 175.5
}
},
"/mnt/data/projects/edx/games/project/graphics/flame.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/graphics/grassland.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/graphics/house.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/graphics/town.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/maps/dungeon.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/maps/dungeon/dungeon.tsx": {
"scaleInDock": 1
},
"/mnt/data/projects/edx/games/project/maps/dungeon/entrance.tmx": {
"scale": 1.3329687499999998,
"selectedLayer": 4,
"viewCenter": {
"x": 320.3375923103974,
"y": 176.67330910795923
}
},
"/mnt/data/projects/edx/games/project/maps/dungeon/entrance.tmx#dungeon": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/maps/entrance.tmx": {
"scale": 1.3332386363636362,
"selectedLayer": 4,
"viewCenter": {
"x": 292.89580225868315,
"y": 116.25825697847861
}
},
"/mnt/data/projects/edx/games/project/maps/grassland.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1.5
},
"/mnt/data/projects/edx/games/project/maps/outside_entrance.tmx": {
"scale": 1.3332386363636362,
"selectedLayer": 0,
"viewCenter": {
"x": 320.64777327935224,
"y": -69.00490091625824
}
},
"/mnt/data/projects/edx/games/project/maps/tilesets/dungeon.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"/mnt/data/projects/edx/games/project/maps/tilesets/grassland.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"levels/level01.tmx": {
"scale": 0.75,
"selectedLayer": 1,
"viewCenter": {
"x": 544,
"y": 248
}
},
"parallax/clouds.tmx": {
"scale": 0.9252604166666667,
"selectedLayer": 0,
"viewCenter": {
"x": 264.790318041092,
"y": 384.7565437658316
}
},
"parallax/hills.tmx": {
"scale": 0.9252604166666667,
"selectedLayer": 0,
"viewCenter": {
"x": 264.790318041092,
"y": 384.7565437658316
}
},
"parallax/snow.tmx": {
"scale": 0.9252604166666667,
"selectedLayer": 0,
"viewCenter": {
"x": 264.790318041092,
"y": 384.7565437658316
}
},
"tilesets/backgrounds.tsx": {
"scaleInDock": 3,
"scaleInEditor": 4
},
"tilesets/tiles.tsx": {
"scaleInDock": 2,
"scaleInEditor": 2
}
},
"frame.defaultDuration": 300,
"last.exportedFilePath": "/mnt/data/godot/projects/Platformer",
"last.imagePath": "/mnt/data/godot/projects/juego/godot/assets/backgrounds",
"lastUsedTilesetExportFilter": "Godot Tileset format (*.tres)",
"loadedWorlds": [
"/home/cromer/projects/edx/games/project/maps/azaraka"
],
"map.fixedSize": true,
"map.height": 12,
"map.lastUsedExportFilter": "Godot Tilemap format (*.tscn)",
"map.lastUsedFormat": "tmx",
"map.tileHeight": 24,
"map.tileWidth": 24,
"map.width": 22,
"openFiles": [
"tilesets/tiles.tsx",
"levels/level01.tmx"
],
"project": "juego.tiled-project",
"property.type": "int",
"recentFiles": [
"tilesets/tiles.tsx",
"levels/level01.tmx",
"tilesets/backgrounds.tsx",
"parallax/snow.tmx",
"parallax/hills.tmx",
"/mnt/data/godot/projects/Azaraka/maps/worldmap.tsx",
"/mnt/data/godot/projects/Azaraka/maps/worldmap.tmx",
"/mnt/data/godot/projects/Platformer/asset/world1.tmx",
"/mnt/data/godot/projects/Platformer/asset/spritesheet_ground.tsx",
"/mnt/data/godot/projects/Platformer/asset/world.tmx",
"/mnt/data/godot/projects/Azaraka/maps/dungeon1.tmx",
"/mnt/data/projects/edx/games/azaraka/maps/outside_entrance.tmx"
],
"tileset.embedInMap": false,
"tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)",
"tileset.lastUsedFormat": "tsx",
"tileset.tileSize": {
"height": 24,
"width": 24
},
"tileset.transparentColor": "#000000",
"tileset.useTransparentColor": false
}

112
godot/levels/level01.tmx Normal file
View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="128" height="32" tilewidth="18" tileheight="18" infinite="0" nextlayerid="4" nextobjectid="1">
<tileset firstgid="1" source="../tilesets/tiles.tsx"/>
<layer id="2" name="Background" width="128" height="32">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,154,155,156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,70,
0,154,155,156,0,0,0,0,0,18,19,20,0,0,0,0,0,0,0,0,0,0,0,154,155,156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,90,
0,0,0,0,0,0,0,0,0,38,39,39,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,90,
0,0,0,0,0,0,0,0,0,38,39,39,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,90,
0,0,0,0,0,0,0,0,0,58,98,59,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,90,
0,0,0,0,0,0,0,0,0,0,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,90,
0,0,0,0,0,0,0,0,99,100,137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,90,
0,0,0,0,0,0,0,0,0,0,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,0,0,0,0,0,0,0,0,0,0,0,110,
0,125,86,0,0,0,0,0,0,0,138,0,0,0,0,0,0,0,0,0,0,0,0,94,134,134,134,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,70,0,0,0,70,0,0,0,70,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,90,0,0,0,90,0,0,0,90,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,133,134,134,115,0,0,0,0,0,129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,0,0,110,0,0,0,110,0,0,0,110,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<layer id="1" name="Middleground" width="128" height="32">
<data encoding="csv">
154,155,156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,50,50,50,50,50,50,50,50,50,50,50,50,51,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,51,
2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,0,0,0,0,0,0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,0,21,0,0,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,23,23,23,23,23,23,23,23,24,0,0,0,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,
122,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,124,0,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,122,123,123,123,123,123,123,123,123,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
122,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,124,69,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,122,123,123,123,123,123,123,123,123,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<layer id="3" name="Foreground" width="128" height="32">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,70,0,0,0,70,0,0,0,70,0,0,0,70,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,90,0,0,0,90,0,0,0,90,0,0,0,90,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,0,0,110,0,0,0,110,0,0,0,110,0,0,0,110,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
</map>

View File

@ -0,0 +1,22 @@
[remap]
importer="vnen.tiled_importer"
type="PackedScene"
path="res://.import/level01.tmx-65e129bada03d3bf56997e5be6fa923f.scn"
[deps]
source_file="res://levels/level01.tmx"
dest_files=[ "res://.import/level01.tmx-65e129bada03d3bf56997e5be6fa923f.scn" ]
[params]
custom_properties=true
tile_metadata=false
uv_clip=true
image_flags=7
collision_layer=1
embed_internal_images=false
save_tiled_properties=false
add_background=true
post_import_script=""

0
godot/parallax/.gdignore Normal file
View File

32
godot/parallax/clouds.tmx Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="22" height="24" tilewidth="24" tileheight="24" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../tilesets/backgrounds.tsx"/>
<layer id="1" name="Tile Layer 1" width="22" height="24">
<data encoding="csv">
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
</data>
</layer>
</map>

32
godot/parallax/hills.tmx Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="22" height="24" tilewidth="24" tileheight="24" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../tilesets/backgrounds.tsx"/>
<layer id="1" name="Tile Layer 1" width="22" height="24">
<data encoding="csv">
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
</data>
</layer>
</map>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="22" height="24" tilewidth="24" tileheight="24" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../tilesets/backgrounds.tsx"/>
<layer id="1" name="Tile Layer 1" width="22" height="24">
<data encoding="csv">
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
</data>
</layer>
</map>

32
godot/parallax/snow.tmx Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="22" height="24" tilewidth="24" tileheight="24" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../tilesets/backgrounds.tsx"/>
<layer id="1" name="Tile Layer 1" width="22" height="24">
<data encoding="csv">
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
</data>
</layer>
</map>

87
godot/project.godot Normal file
View File

@ -0,0 +1,87 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
[application]
config/name="Juego"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"
[display]
window/size/width=512
window/size/height=288
window/stretch/mode="viewport"
window/stretch/aspect="keep"
[editor_plugins]
enabled=PoolStringArray( "res://addons/vnen.tiled_importer/plugin.cfg" )
[importer_defaults]
texture={
"compress/bptc_ldr": 0,
"compress/hdr_mode": 0,
"compress/lossy_quality": 0.7,
"compress/mode": 0,
"compress/normal_map": 0,
"detect_3d": false,
"flags/anisotropic": false,
"flags/filter": false,
"flags/mipmaps": false,
"flags/repeat": 0,
"flags/srgb": 2,
"process/HDR_as_SRGB": false,
"process/fix_alpha_border": true,
"process/invert_color": false,
"process/normal_map_invert_y": false,
"process/premult_alpha": false,
"size_limit": 0,
"stream": false,
"svg/scale": 1.0
}
[input]
run={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
jump={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
[physics]
common/enable_pause_aware_picking=true
[rendering]
environment/default_environment="res://default_env.tres"
[tiled_importer]
enable_json_format=false

0
godot/tilesets/.gdignore Normal file
View File

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.8" tiledversion="1.8.4" name="backgrounds" tilewidth="24" tileheight="24" tilecount="12" columns="6">
<image source="../assets/backgrounds/backgrounds.png" width="144" height="48"/>
</tileset>

199
godot/tilesets/tiles.tsx Normal file
View File

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.8" tiledversion="1.8.4" name="tiles" tilewidth="18" tileheight="18" tilecount="180" columns="20">
<image source="../assets/tiles/tiles.png" width="360" height="162"/>
<tile id="0">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="1">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="2">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="3">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="6">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="20">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="21">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="22">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="23">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="26">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="40">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="41">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="42">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="43">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="47">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="48">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="49">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="50">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="60">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="61">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="62">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="63">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="80">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="81">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="82">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="83">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="100">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="101">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="102">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="103">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="104">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="120">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="121">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="122">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="123">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="140">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="141">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="142">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
<tile id="143">
<objectgroup draworder="index" id="2">
<object id="1" x="0" y="0" width="18" height="18"/>
</objectgroup>
</tile>
</tileset>

BIN
icon.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,22 +0,0 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
[application]
config/name="juego"
config/icon="res://icon.png"
[physics]
common/enable_pause_aware_picking=true
[rendering]
environment/default_environment="res://default_env.tres"

43
source.code-workspace Normal file
View File

@ -0,0 +1,43 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.exclude": {
"**/*.cpp": false,
"**/*.h": false,
"**/*.o": true,
"**/*.svg": true,
"**/*.png": true,
"**/*.a": true,
"**/*.os": true,
"**/*.so": true,
"**/*.dll": true,
"**/*.tmx": true,
"**/*.tsx": true,
"**/SConstruct": false,
"**/__pycache__": true,
"**/.git": true,
"**/*.yml": true,
"**/SCsub": true,
"**/Makefile": false,
"**/bin": true,
"**/build": true,
"godot/android": true,
"godot": true,
"docs": true,
"**/.import": true,
"**/*.import": true,
"compile_commands.json": true,
"**/.sconsign.dblite": true
},
"cSpell.words": [
"gdnative",
"godot",
"lerp",
"tscn"
]
}
}

99
src/Main.cpp Normal file
View File

@ -0,0 +1,99 @@
#include "Main.h"
#include <SceneTree.hpp>
using namespace godot;
void Main::_register_methods()
{
register_method("_ready", &Main::_ready);
register_method("_physics_process", &Main::_physics_process);
register_property<Main, bool>("full_screen", &Main::set_full_screen, &Main::get_full_screen, JUEGO_MAIN_FULL_SCREEN);
register_property<Main, Vector2>("window_size", &Main::set_window_size, &Main::get_window_size, JUEGO_MAIN_WINDOW_SIZE);
register_property<Main, int8_t>("launch_screen", &Main::set_launch_screen, &Main::get_launch_screen, JUEGO_MAIN_LAUNCH_SCREEN);
}
Main::Main()
{
}
Main::~Main()
{
}
void Main::_init()
{
_os = OS::get_singleton();
_input = Input::get_singleton();
full_screen = JUEGO_MAIN_FULL_SCREEN;
window_size = JUEGO_MAIN_WINDOW_SIZE;
launch_screen = JUEGO_MAIN_LAUNCH_SCREEN;
}
void Main::_ready()
{
if (get_full_screen())
{
_os->set_window_fullscreen(true);
}
else
{
String resolution = String("Resolution before: " + String().num(_os->get_window_size().x) + "x" + String().num(_os->get_window_size().y));
Godot::print(resolution);
_os->set_window_size(window_size);
_os->set_window_position(
_os->get_screen_position(get_launch_screen()) + _os->get_screen_size() * 0.5 - _os->get_window_size() * 0.5
);
resolution = String("Resolution after: " + String().num(_os->get_window_size().x) + "x" + String().num(_os->get_window_size().y));
Godot::print(resolution);
}
}
void Main::_physics_process(float delta)
{
if (_input->is_action_just_pressed("ui_cancel"))
{
get_tree()->quit();
}
}
void Main::set_full_screen(bool new_full_screen)
{
full_screen = new_full_screen;
}
bool Main::get_full_screen()
{
return full_screen;
}
void Main::set_window_size(Vector2 new_window_size)
{
window_size = new_window_size;
}
Vector2 Main::get_window_size()
{
return window_size;
}
void Main::set_launch_screen(int8_t new_launch_screen)
{
launch_screen = new_launch_screen;
}
int8_t Main::get_launch_screen()
{
if (launch_screen == -1)
{
return _os->get_current_screen();
}
else
{
return launch_screen;
}
}

237
src/Player.cpp Normal file
View File

@ -0,0 +1,237 @@
#include "Player.h"
#include <Camera2D.hpp>
#include <TileMap.hpp>
#include <VisibilityNotifier2D.hpp>
#include <SceneTree.hpp>
#include <Texture.hpp>
using namespace godot;
void Player::_register_methods()
{
register_method("_ready", &Player::_ready);
register_method("_physics_process", &Player::_physics_process);
register_method("_on_Player_player_moved", &Player::_on_Player_player_moved);
//register_property<Player, Ref<SpriteFrames>>("sprite_frames", &Player::set_sprite_frames, &Player::get_sprite_frames, Ref<SpriteFrames>(), GODOT_METHOD_RPC_MODE_DISABLED, GODOT_PROPERTY_USAGE_DEFAULT, GODOT_PROPERTY_HINT_RESOURCE_TYPE, String("SpriteFrames"));
register_property<Player, float>("speed", &Player::set_speed, &Player::get_speed, JUEGO_PLAYER_SPEED);
register_property<Player, float>("jump_force", &Player::set_jump_force, &Player::get_jump_force, JUEGO_PLAYER_JUMP_FORCE);
register_property<Player, float>("gravity", &Player::set_gravity, &Player::get_gravity, JUEGO_PLAYER_GRAVITY);
register_property<Player, float>("run_speed", &Player::set_run_speed, &Player::get_run_speed, JUEGO_PLAYER_RUN_SPEED);
register_signal<Player>("player_moved", "position", GODOT_VARIANT_TYPE_VECTOR2);
}
Player::Player()
{
}
Player::~Player()
{
}
void Player::_init()
{
_os = OS::get_singleton();
_input = Input::get_singleton();
_resource_loader = ResourceLoader::get_singleton();
//sprite_frames = _resource_loader->load(JUEGO_PLAYER_SPRITE_FRAMES);
set_speed(JUEGO_PLAYER_SPEED);
set_jump_force(JUEGO_PLAYER_JUMP_FORCE);
set_gravity(JUEGO_PLAYER_GRAVITY);
set_run_speed(JUEGO_PLAYER_RUN_SPEED);
coins = 0;
velocity = Vector2();
jumping = 0;
}
void Player::_ready()
{
animated_sprite = get_node<AnimatedSprite>("AnimatedSprite");
if (!animated_sprite)
{
WARN_PRINT("AnimateSprite not found!");
animated_sprite = AnimatedSprite()._new();
}
//animated_sprite->set_sprite_frames(sprite_frames);
auto node = get_parent()->find_node("Middleground");
if (node != nullptr)
{
auto tile_map = Object::cast_to<TileMap>(node);
get_parent()->call_deferred("remove_child", this);
tile_map->call_deferred("add_child", this);
}
else
{
WARN_PRINT("Middleground not found!");
}
}
void Player::_physics_process(float delta)
{
auto current_speed = get_speed();
velocity.x = 0;
if (_input->is_action_pressed("run"))
{
current_speed *= get_run_speed();
}
if (_input->is_action_pressed("right"))
{
velocity.x += current_speed;
}
if (_input->is_action_pressed("left"))
{
velocity.x += -current_speed;
}
if (velocity.x > 0)
{
animated_sprite->play("move");
animated_sprite->set_flip_h(true);
}
else if (velocity.x < 0)
{
animated_sprite->play("move");
animated_sprite->set_flip_h(false);
}
else
{
animated_sprite->stop();
animated_sprite->set_animation("idle");
}
if (jumping > 0 && is_on_floor())
{
animated_sprite->set_frame(1);
jumping = 0;
}
if (!is_on_floor())
{
animated_sprite->stop();
animated_sprite->set_animation("air");
if (jumping == 0)
{
jumping = 2;
}
}
velocity.y += get_gravity();
if (_input->is_action_just_pressed("jump") && jumping < 2)
{
velocity.y = -get_jump_force();
jumping++;
}
if (_input->is_action_just_released("jump"))
{
if (velocity.y < -100)
{
velocity.y = -100;
}
}
if (velocity.x < 0 || velocity.x > 0)
{
//emit_signal("player_moved", get_position());
}
velocity = move_and_slide(velocity, Vector2::UP, true);
velocity.x = Math::lerp((float) velocity.x, (float) 0, (float) 0.2);
// Clamp the player's position inside the camera's limits
auto camera = get_node<Camera2D>("Camera2D");
auto position = get_global_position();
auto sprite_node = get_node<AnimatedSprite>("AnimatedSprite");
if (sprite_node != nullptr)
{
position.x = Math::clamp((float) position.x, (float) camera->get_limit(0), (float) camera->get_limit(2) - sprite_node->get_sprite_frames()->get_frame("idle", 0)->get_size().x);
position.y = Math::clamp((float) position.y, (float) camera->get_limit(1), (float) camera->get_limit(3) + sprite_node->get_sprite_frames()->get_frame("idle", 0)->get_size().y);
}
else {
WARN_PRINT("Could not clamp player based on sprite frame size!");
position.x = Math::clamp((float) position.x, (float) camera->get_limit(0), (float) camera->get_limit(2));
position.y = Math::clamp((float) position.y, (float) camera->get_limit(1), (float) camera->get_limit(3));
}
set_global_position(position);
// If the player is off screen reload the scene
auto notifier = get_node<VisibilityNotifier2D>("Camera2D/VisibilityNotifier2D");
if (notifier != nullptr)
{
if (!notifier->is_on_screen())
{
if (get_parent()->get_class() == "TileMap")
{
Godot::print("Off screen");
auto error = get_tree()->change_scene("res://Main.tscn");
if (error != Error::OK)
{
ERR_PRINT(String().num((int) error) + " Could not load scene!");
}
}
}
}
}
void Player::set_sprite_frames(Ref<SpriteFrames> new_sprite_frames)
{
sprite_frames = new_sprite_frames;
}
Ref<SpriteFrames> Player::get_sprite_frames()
{
return sprite_frames;
}
void Player::set_speed(float new_speed)
{
speed = new_speed;
}
float Player::get_speed()
{
return speed;
}
void Player::set_jump_force(float new_jump_force)
{
jump_force = new_jump_force;
}
float Player::get_jump_force()
{
return jump_force;
}
void Player::set_gravity(float new_gravity)
{
gravity = new_gravity;
}
float Player::get_gravity()
{
return gravity;
}
void Player::set_run_speed(float new_run_speed)
{
run_speed = new_run_speed;
}
float Player::get_run_speed()
{
return run_speed;
}
void Player::_on_Player_player_moved(Vector2 position)
{
Godot::print(position);
}

26
src/godot.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <Godot.hpp>
#include "Main.h"
#include "Player.h"
using namespace godot;
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o)
{
Godot::gdnative_init(o);
}
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o)
{
// This next line is a workaround to fix bug:
// https://github.com/godotengine/godot/issues/48295
Godot::nativescript_terminate(_RegisterState::nativescript_handle);
Godot::gdnative_terminate(o);
}
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle)
{
Godot::nativescript_init(handle);
register_class<Main>();
register_class<Player>();
}

143
src/include/Main.h Normal file
View File

@ -0,0 +1,143 @@
#ifndef JUEGO_MAIN_H
#define JUEGO_MAIN_H
#include <Godot.hpp>
#include <Node.hpp>
#include <OS.hpp>
#include <Input.hpp>
/**
* @brief If the game should be full screen or not by default.
*/
#define JUEGO_MAIN_FULL_SCREEN false
/**
* @brief The default size of the window.
* @details This is ignored if full screen is true.
*/
#define JUEGO_MAIN_WINDOW_SIZE Vector2(1280, 720)
/**
* @brief Which screen to launch the game on.
* @details If -1 it will launch the game on the "active" screen. Anything between 0 and N represents the screen number to show the game on when opened.
*/
#define JUEGO_MAIN_LAUNCH_SCREEN -1
/**
* @brief This is the godot namespace for all the code included in the library.
* @details This namespace is used a prefix when the Godot engine looks for classes, methods, and properties.
*/
namespace godot
{
/**
* @brief This class controls the Main node.
* @details The main node is responsible for controling the window and the game iteself is a child of it.
*/
class Main : public Node
{
GODOT_CLASS(Main, Node)
private:
/**
* @brief OS singleton.
*/
OS *_os;
/**
* @brief Input singleton.
*/
Input *_input;
/**
* @brief If the window is full screen or not.
*/
bool full_screen;
/**
* @brief The size of the window.
*/
Vector2 window_size;
/**
* @brief The screen to launch the game on.
*/
int8_t launch_screen;
public:
/**
* @brief This method registers classes with Godot.
* @details This method registers methods, properties, and signals with the Godot engine.
*/
static void _register_methods();
/**
* @brief Construct a new Main object.
*/
Main();
/**
* @brief Destroy the Main object.
*/
~Main();
/**
* @brief Initialize the class from Godot.
* @details This method is called just once when the Godot engine connects to the instance of the class.
*/
void _init();
/**
* @brief Code to be run when ready.
* @details This method is run when all the children of this node are ready.
*/
void _ready();
/**
* @brief This class handles the physics processing.
* @details Every delta time, this function is called to check for input and update positioning.
*
* @param[in] delta The difference in time that passed since the last call to this method.
*/
void _physics_process(float delta);
/**
* @brief Set the full screen object.
*
* @param[in] new_full_screen The new full screen state.
*/
void set_full_screen(bool new_full_screen);
/**
* @brief Get the full screen object.
*
* @return true If full screen.
* @return false If not full screen.
*/
bool get_full_screen();
/**
* @brief Set the window size object.
*
* @param[in] new_window_size The new window size.
*/
void set_window_size(Vector2 new_window_size);
/**
* @brief Get the window size object.
*
* @return Vector2 The window size.
*/
Vector2 get_window_size();
/**
* @brief Set the launch screen object.
*
* @param[in] new_launch_screen The launch screen to use.
*/
void set_launch_screen(int8_t new_launch_screen);
/**
* @brief Get the launch screen object.
*
* @return int8_t The launch screen.
*/
int8_t get_launch_screen();
};
}
#endif

219
src/include/Player.h Normal file
View File

@ -0,0 +1,219 @@
#ifndef JUEGO_PLAYER_H
#define JUEGO_PLAYER_H
/**
* @brief This resource is loaded by default for the AnimatedSprite node.
*/
#define JUEGO_PLAYER_SPRITE_FRAMES "res://characters/player/sprites/green.tres"
/**
* @brief The speed the player should move it.
*/
#define JUEGO_PLAYER_SPEED 100.0
/**
* @brief The force applied to the player when jumping.
*/
#define JUEGO_PLAYER_JUMP_FORCE 300.0
/**
* @brief The gravity applied to the player.
*/
#define JUEGO_PLAYER_GRAVITY 9.81
/**
* @brief The multiplier used to change the speed of the player when running.
*/
#define JUEGO_PLAYER_RUN_SPEED 2.0
#include <Godot.hpp>
#include <KinematicBody2D.hpp>
#include <OS.hpp>
#include <Sprite.hpp>
#include <Vector2.hpp>
#include <Input.hpp>
#include <AnimatedSprite.hpp>
#include <SpriteFrames.hpp>
#include <ResourceLoader.hpp>
#include <PackedScene.hpp>
/**
* @brief This is the godot namespace for all the code included in the library.
* @details This namespace is used a prefix when the Godot engine looks for classes, methods, and properties.
*/
namespace godot
{
/**
* @brief This class is used to control the player.
* @details This class allows the player to move, run, and jump as well as controls the sprite displayed for those actions.
*/
class Player : public KinematicBody2D
{
GODOT_CLASS(Player, KinematicBody2D)
private:
/**
* @brief OS singleton.
*/
OS *_os;
/**
* @brief Input singleton.
*/
Input *_input;
/**
* @brief ResourceLoader singleton.
*/
ResourceLoader *_resource_loader;
/**
* @brief The animated sprite connected to the KinematicBody2D.
*/
AnimatedSprite *animated_sprite;
/**
* @brief The sprite frames used in the animated sprite.
*/
Ref<SpriteFrames> sprite_frames;
/**
* @brief The coins the player has collected.
*/
uint8_t coins;
/**
* @brief The velocity at which moves the player moves.
*/
Vector2 velocity;
/**
* @brief The speed that the player moves in.
*/
float speed;
/**
* @brief The force applied to the player when jumping.
*/
float jump_force;
/**
* @brief The gravity applied to the player.
*/
float gravity;
/**
* @brief The speed multiplier used to make the player move faster.
*/
float run_speed;
/**
* @brief State of jumping of the player. To be replaced with a state machine in the future.
*/
uint8_t jumping;
public:
/**
* @brief This method registers classes with Godot.
* @details This method registers methods, properties, and signals with the Godot engine.
*/
static void _register_methods();
/**
* @brief Construct a new Player object.
*/
Player();
/**
* @brief Destroy the Player object.
*/
~Player();
/**
* @brief Initialize the class from Godot.
* @details This method is called just once when the Godot engine connects to the instance of the class.
*/
void _init();
/**
* @brief Code to be run when ready.
* @details This method is run when all the children of this node are ready.
*/
void _ready();
/**
* @brief This class handles the physics processing.
* @details Every delta time, this function is called to check for input and update positioning.
*
* @param[in] delta The difference in time that passed since the last call to this method.
*/
void _physics_process(float delta);
/**
* @brief Set the sprite frames object.
*
* @param[in] new_sprite_frames The new sprite frame.
*/
void set_sprite_frames(Ref<SpriteFrames> new_sprite_frames);
/**
* @brief Get the sprite frames object.
*
* @return Ref<SpriteFrames> A reference to the sprite frames object.
*/
Ref<SpriteFrames> get_sprite_frames();
/**
* @brief Set the speed object.
*
* @param[in] new_speed The new speed.
*/
void set_speed(float new_speed);
/**
* @brief Get the speed object.
*
* @return float The current speed of the player.
*/
float get_speed();
/**
* @brief Set the jump force object.
*
* @param[in] new_jump_force The new force applied to the player to make him jump.
*/
void set_jump_force(float new_jump_force);
/**
* @brief Get the jump force object.
*
* @return float The current force being applied to the player.
*/
float get_jump_force();
/**
* @brief Set the gravity object.
*
* @param[in] new_gravity The new gravity to apply to the player.
*/
void set_gravity(float new_gravity);
/**
* @brief Get the gravity object.
*
* @return float The current gravity applied to the player.
*/
float get_gravity();
/**
* @brief Set the run speed object.
*
* @param[in] new_run_speed The new speed for running.
*/
void set_run_speed(float new_run_speed);
/**
* @brief Get the run speed object.
*
* @return float The current run speed of the player.
*/
float get_run_speed();
/**
* @brief This signal is called when the player moves.
* @details The jump action is not included in this signal, just moving left or right.
*
* @param[in] position The new position of the player.
*/
void _on_Player_player_moved(Vector2 position);
};
}
#endif