shifted from proprietary ascii rawlevel to LDTK (using ldtkgo@master)

This commit is contained in:
2024-03-10 13:05:31 +01:00
parent a2ed7782b2
commit af19ccb833
15 changed files with 819 additions and 173 deletions

View File

@@ -0,0 +1,686 @@
{
"__header__": {
"fileType": "LDtk Project JSON",
"app": "LDtk",
"doc": "https://ldtk.io/json",
"schema": "https://ldtk.io/files/JSON_SCHEMA.json",
"appAuthor": "Sebastien 'deepnight' Benard",
"appVersion": "1.5.3",
"url": "https://ldtk.io"
},
"iid": "267e9380-d7b0-11ee-a97e-35bec9c19d52",
"jsonVersion": "1.5.3",
"appBuildId": 473703,
"nextUid": 11,
"identifierStyle": "Capitalize",
"toc": [],
"worldLayout": "Free",
"worldGridWidth": 256,
"worldGridHeight": 256,
"defaultLevelWidth": 256,
"defaultLevelHeight": 256,
"defaultPivotX": 0,
"defaultPivotY": 0,
"defaultGridSize": 32,
"defaultEntityWidth": 32,
"defaultEntityHeight": 32,
"bgColor": "#40465B",
"defaultLevelBgColor": "#696A79",
"minifyJson": false,
"externalLevels": false,
"exportTiled": false,
"simplifiedExport": false,
"imageExportMode": "None",
"exportLevelBg": true,
"pngFilePattern": null,
"backupOnSave": false,
"backupLimit": 10,
"backupRelPath": null,
"levelNamePattern": "Level_%idx",
"tutorialDesc": null,
"customCommands": [],
"flags": [],
"defs": { "layers": [
{
"__type": "Entities",
"identifier": "Entities",
"type": "Entities",
"uid": 5,
"doc": null,
"uiColor": null,
"gridSize": 32,
"guideGridWid": 0,
"guideGridHei": 0,
"displayOpacity": 1,
"inactiveOpacity": 0.6,
"hideInList": false,
"hideFieldsWhenInactive": true,
"canSelectWhenInactive": true,
"renderInWorldView": true,
"pxOffsetX": 0,
"pxOffsetY": 0,
"parallaxFactorX": 0,
"parallaxFactorY": 0,
"parallaxScaling": true,
"requiredTags": [],
"excludedTags": [],
"autoTilesKilledByOtherLayerUid": null,
"uiFilterTags": [],
"useAsyncRender": false,
"intGridValues": [],
"intGridValuesGroups": [],
"autoRuleGroups": [],
"autoSourceLayerDefUid": null,
"tilesetDefUid": null,
"tilePivotX": 0,
"tilePivotY": 0,
"biomeFieldUid": null
},
{
"__type": "Tiles",
"identifier": "Tiles",
"type": "Tiles",
"uid": 2,
"doc": null,
"uiColor": null,
"gridSize": 32,
"guideGridWid": 0,
"guideGridHei": 0,
"displayOpacity": 1,
"inactiveOpacity": 1,
"hideInList": false,
"hideFieldsWhenInactive": false,
"canSelectWhenInactive": true,
"renderInWorldView": true,
"pxOffsetX": 0,
"pxOffsetY": 0,
"parallaxFactorX": 0,
"parallaxFactorY": 0,
"parallaxScaling": true,
"requiredTags": [],
"excludedTags": [],
"autoTilesKilledByOtherLayerUid": null,
"uiFilterTags": [],
"useAsyncRender": false,
"intGridValues": [],
"intGridValuesGroups": [],
"autoRuleGroups": [],
"autoSourceLayerDefUid": null,
"tilesetDefUid": 1,
"tilePivotX": 0,
"tilePivotY": 0,
"biomeFieldUid": null
}
], "entities": [
{
"identifier": "Player_Primary",
"uid": 3,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 32,
"height": 32,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#2F3BBE",
"renderMode": "Tile",
"showName": true,
"tilesetId": 1,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 1, "x": 32, "y": 96, "w": 32, "h": 32 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
},
{
"identifier": "Collectible",
"uid": 4,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 32,
"height": 32,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#FEAE34",
"renderMode": "Tile",
"showName": true,
"tilesetId": 1,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 1, "x": 32, "y": 32, "w": 32, "h": 32 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
},
{
"identifier": "Obstacle_West",
"uid": 7,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 32,
"height": 32,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#BE4A2F",
"renderMode": "Tile",
"showName": true,
"tilesetId": 1,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 1, "x": 0, "y": 96, "w": 32, "h": 32 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
},
{
"identifier": "Obstacle_East",
"uid": 8,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 32,
"height": 32,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#D77643",
"renderMode": "Tile",
"showName": true,
"tilesetId": 1,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 1, "x": 64, "y": 32, "w": 32, "h": 32 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
},
{
"identifier": "Obstacle_North",
"uid": 9,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 32,
"height": 32,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#F77622",
"renderMode": "Tile",
"showName": true,
"tilesetId": 1,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 1, "x": 0, "y": 64, "w": 32, "h": 32 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
},
{
"identifier": "Obstacle_South",
"uid": 10,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 32,
"height": 32,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#E43B44",
"renderMode": "Tile",
"showName": true,
"tilesetId": 1,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 1, "x": 32, "y": 64, "w": 32, "h": 32 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
}
], "tilesets": [
{
"__cWid": 3,
"__cHei": 5,
"identifier": "Map2",
"uid": 1,
"relPath": "../sprites/map.png",
"embedAtlas": null,
"pxWid": 96,
"pxHei": 160,
"tileGridSize": 32,
"spacing": 0,
"padding": 0,
"tags": [],
"tagsSourceEnumUid": null,
"enumTags": [],
"customData": [],
"savedSelections": [],
"cachedPixelData": { "opaqueTiles": "110000000000000", "averageColors": "f777f766f766f9533c965c355c355c354b355c35987d687d1b4700000000" }
}
], "enums": [], "externalEnums": [], "levelFields": [] },
"levels": [
{
"identifier": "Level_0",
"iid": "267fa4f0-d7b0-11ee-a97e-d90512e08363",
"uid": 0,
"worldX": -224,
"worldY": 0,
"worldDepth": 0,
"pxWid": 640,
"pxHei": 480,
"__bgColor": "#696A79",
"bgColor": null,
"useAutoIdentifier": true,
"bgRelPath": null,
"bgPos": null,
"bgPivotX": 0.5,
"bgPivotY": 0.5,
"__smartColor": "#ADADB5",
"__bgPos": null,
"externalRelPath": null,
"fieldInstances": [],
"layerInstances": [
{
"__identifier": "Entities",
"__type": "Entities",
"__cWid": 20,
"__cHei": 15,
"__gridSize": 32,
"__opacity": 1,
"__pxTotalOffsetX": 0,
"__pxTotalOffsetY": 0,
"__tilesetDefUid": null,
"__tilesetRelPath": null,
"iid": "99cd5060-d7b0-11ee-a97e-3f143b461cd1",
"levelId": 0,
"layerDefUid": 5,
"pxOffsetX": 0,
"pxOffsetY": 0,
"visible": true,
"optionalRules": [],
"intGridCsv": [],
"autoLayerTiles": [],
"seed": 1148260,
"overrideTilesetUid": null,
"gridTiles": [],
"entityInstances": [
{
"__identifier": "Player_Primary",
"__grid": [7,5],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 32, "y": 96, "w": 32, "h": 32 },
"__smartColor": "#2F3BBE",
"iid": "c33a2c20-d7b0-11ee-a97e-03409aba0392",
"width": 32,
"height": 32,
"defUid": 3,
"px": [224,160],
"fieldInstances": [],
"__worldX": 0,
"__worldY": 160
},
{
"__identifier": "Collectible",
"__grid": [11,7],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 32, "y": 32, "w": 32, "h": 32 },
"__smartColor": "#FEAE34",
"iid": "f2b2ff50-d7b0-11ee-98fb-b34c447bc14d",
"width": 32,
"height": 32,
"defUid": 4,
"px": [352,224],
"fieldInstances": [],
"__worldX": 128,
"__worldY": 224
}
]
},
{
"__identifier": "Tiles",
"__type": "Tiles",
"__cWid": 20,
"__cHei": 15,
"__gridSize": 32,
"__opacity": 1,
"__pxTotalOffsetX": 0,
"__pxTotalOffsetY": 0,
"__tilesetDefUid": 1,
"__tilesetRelPath": "../sprites/map.png",
"iid": "3f368c70-d7b0-11ee-a97e-65a98b860ebf",
"levelId": 0,
"layerDefUid": 2,
"pxOffsetX": 0,
"pxOffsetY": 0,
"visible": true,
"optionalRules": [],
"intGridCsv": [],
"autoLayerTiles": [],
"seed": 4985586,
"overrideTilesetUid": null,
"gridTiles": [
{ "px": [192,128], "src": [64,0], "f": 0, "t": 2, "d": [86], "a": 1 },
{ "px": [224,128], "src": [64,0], "f": 0, "t": 2, "d": [87], "a": 1 },
{ "px": [256,128], "src": [64,0], "f": 0, "t": 2, "d": [88], "a": 1 },
{ "px": [288,128], "src": [64,0], "f": 0, "t": 2, "d": [89], "a": 1 },
{ "px": [320,128], "src": [64,0], "f": 0, "t": 2, "d": [90], "a": 1 },
{ "px": [352,128], "src": [64,0], "f": 0, "t": 2, "d": [91], "a": 1 },
{ "px": [384,128], "src": [64,0], "f": 0, "t": 2, "d": [92], "a": 1 },
{ "px": [416,128], "src": [0,0], "f": 0, "t": 0, "d": [93], "a": 1 },
{ "px": [416,128], "src": [64,0], "f": 0, "t": 2, "d": [93], "a": 1 },
{ "px": [192,160], "src": [64,0], "f": 0, "t": 2, "d": [106], "a": 1 },
{ "px": [256,160], "src": [64,0], "f": 0, "t": 2, "d": [108], "a": 1 },
{ "px": [416,160], "src": [64,0], "f": 0, "t": 2, "d": [113], "a": 1 },
{ "px": [192,192], "src": [64,0], "f": 0, "t": 2, "d": [126], "a": 1 },
{ "px": [256,192], "src": [64,0], "f": 0, "t": 2, "d": [128], "a": 1 },
{ "px": [320,192], "src": [64,0], "f": 0, "t": 2, "d": [130], "a": 1 },
{ "px": [352,192], "src": [64,0], "f": 0, "t": 2, "d": [131], "a": 1 },
{ "px": [416,192], "src": [64,0], "f": 0, "t": 2, "d": [133], "a": 1 },
{ "px": [192,224], "src": [64,0], "f": 0, "t": 2, "d": [146], "a": 1 },
{ "px": [256,224], "src": [64,0], "f": 0, "t": 2, "d": [148], "a": 1 },
{ "px": [320,224], "src": [64,0], "f": 0, "t": 2, "d": [150], "a": 1 },
{ "px": [416,224], "src": [64,0], "f": 0, "t": 2, "d": [153], "a": 1 },
{ "px": [192,256], "src": [64,0], "f": 0, "t": 2, "d": [166], "a": 1 },
{ "px": [256,256], "src": [64,0], "f": 0, "t": 2, "d": [168], "a": 1 },
{ "px": [320,256], "src": [64,0], "f": 0, "t": 2, "d": [170], "a": 1 },
{ "px": [416,256], "src": [64,0], "f": 0, "t": 2, "d": [173], "a": 1 },
{ "px": [192,288], "src": [64,0], "f": 0, "t": 2, "d": [186], "a": 1 },
{ "px": [320,288], "src": [64,0], "f": 0, "t": 2, "d": [190], "a": 1 },
{ "px": [416,288], "src": [64,0], "f": 0, "t": 2, "d": [193], "a": 1 },
{ "px": [192,320], "src": [64,0], "f": 0, "t": 2, "d": [206], "a": 1 },
{ "px": [224,320], "src": [64,0], "f": 0, "t": 2, "d": [207], "a": 1 },
{ "px": [256,320], "src": [64,0], "f": 0, "t": 2, "d": [208], "a": 1 },
{ "px": [288,320], "src": [64,0], "f": 0, "t": 2, "d": [209], "a": 1 },
{ "px": [320,320], "src": [64,0], "f": 0, "t": 2, "d": [210], "a": 1 },
{ "px": [352,320], "src": [64,0], "f": 0, "t": 2, "d": [211], "a": 1 },
{ "px": [384,320], "src": [64,0], "f": 0, "t": 2, "d": [212], "a": 1 },
{ "px": [416,320], "src": [64,0], "f": 0, "t": 2, "d": [213], "a": 1 }
],
"entityInstances": []
}
],
"__neighbours": []
},
{
"identifier": "_First_Try",
"iid": "024390f0-d7b0-11ee-98fb-1bc6ad7e4172",
"uid": 6,
"worldX": 480,
"worldY": 0,
"worldDepth": 0,
"pxWid": 640,
"pxHei": 480,
"__bgColor": "#696A79",
"bgColor": null,
"useAutoIdentifier": false,
"bgRelPath": "../sprites/background-lila.png",
"bgPos": "Cover",
"bgPivotX": 0.5,
"bgPivotY": 0.5,
"__smartColor": "#ADADB5",
"__bgPos": { "topLeftPx": [0,0], "scale": [1,1], "cropRect": [0,0,640,480] },
"externalRelPath": null,
"fieldInstances": [],
"layerInstances": [
{
"__identifier": "Entities",
"__type": "Entities",
"__cWid": 20,
"__cHei": 15,
"__gridSize": 32,
"__opacity": 1,
"__pxTotalOffsetX": 0,
"__pxTotalOffsetY": 0,
"__tilesetDefUid": null,
"__tilesetRelPath": null,
"iid": "0243b800-d7b0-11ee-98fb-f1914bde56c8",
"levelId": 6,
"layerDefUid": 5,
"pxOffsetX": 0,
"pxOffsetY": 0,
"visible": true,
"optionalRules": [],
"intGridCsv": [],
"autoLayerTiles": [],
"seed": 2072933,
"overrideTilesetUid": null,
"gridTiles": [],
"entityInstances": [
{
"__identifier": "Obstacle_West",
"__grid": [6,8],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 0, "y": 96, "w": 32, "h": 32 },
"__smartColor": "#BE4A2F",
"iid": "8aab4e10-d7b0-11ee-98fb-2171f9170515",
"width": 32,
"height": 32,
"defUid": 7,
"px": [192,256],
"fieldInstances": [],
"__worldX": 672,
"__worldY": 256
},
{
"__identifier": "Player_Primary",
"__grid": [4,5],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 32, "y": 96, "w": 32, "h": 32 },
"__smartColor": "#2F3BBE",
"iid": "8d2c2c90-d7b0-11ee-98fb-d523a27935ba",
"width": 32,
"height": 32,
"defUid": 3,
"px": [128,160],
"fieldInstances": [],
"__worldX": 608,
"__worldY": 160
},
{
"__identifier": "Collectible",
"__grid": [4,9],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 32, "y": 32, "w": 32, "h": 32 },
"__smartColor": "#FEAE34",
"iid": "a1dfb440-d7b0-11ee-98fb-933f35aeb72b",
"width": 32,
"height": 32,
"defUid": 4,
"px": [128,288],
"fieldInstances": [],
"__worldX": 608,
"__worldY": 288
},
{
"__identifier": "Collectible",
"__grid": [14,6],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 32, "y": 32, "w": 32, "h": 32 },
"__smartColor": "#FEAE34",
"iid": "f7ec8340-d7b0-11ee-98fb-1fa75c7ce959",
"width": 32,
"height": 32,
"defUid": 4,
"px": [448,192],
"fieldInstances": [],
"__worldX": 928,
"__worldY": 192
},
{
"__identifier": "Obstacle_South",
"__grid": [15,6],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 1, "x": 32, "y": 64, "w": 32, "h": 32 },
"__smartColor": "#E43B44",
"iid": "45c2d010-d7b0-11ee-98fb-13d8f32ffff0",
"width": 32,
"height": 32,
"defUid": 10,
"px": [480,192],
"fieldInstances": [],
"__worldX": 960,
"__worldY": 192
}
]
},
{
"__identifier": "Tiles",
"__type": "Tiles",
"__cWid": 20,
"__cHei": 15,
"__gridSize": 32,
"__opacity": 1,
"__pxTotalOffsetX": 0,
"__pxTotalOffsetY": 0,
"__tilesetDefUid": 1,
"__tilesetRelPath": "../sprites/map.png",
"iid": "0243b801-d7b0-11ee-98fb-79b1102fb094",
"levelId": 6,
"layerDefUid": 2,
"pxOffsetX": 0,
"pxOffsetY": 0,
"visible": true,
"optionalRules": [],
"intGridCsv": [],
"autoLayerTiles": [],
"seed": 2952425,
"overrideTilesetUid": null,
"gridTiles": [
{ "px": [96,128], "src": [64,0], "f": 0, "t": 2, "d": [83], "a": 1 },
{ "px": [128,128], "src": [64,0], "f": 0, "t": 2, "d": [84], "a": 1 },
{ "px": [160,128], "src": [64,0], "f": 0, "t": 2, "d": [85], "a": 1 },
{ "px": [192,128], "src": [64,0], "f": 0, "t": 2, "d": [86], "a": 1 },
{ "px": [224,128], "src": [64,0], "f": 0, "t": 2, "d": [87], "a": 1 },
{ "px": [384,128], "src": [64,0], "f": 0, "t": 2, "d": [92], "a": 1 },
{ "px": [416,128], "src": [64,0], "f": 0, "t": 2, "d": [93], "a": 1 },
{ "px": [448,128], "src": [64,0], "f": 0, "t": 2, "d": [94], "a": 1 },
{ "px": [480,128], "src": [64,0], "f": 0, "t": 2, "d": [95], "a": 1 },
{ "px": [512,128], "src": [64,0], "f": 0, "t": 2, "d": [96], "a": 1 },
{ "px": [96,160], "src": [64,0], "f": 0, "t": 2, "d": [103], "a": 1 },
{ "px": [224,160], "src": [64,0], "f": 0, "t": 2, "d": [107], "a": 1 },
{ "px": [384,160], "src": [64,0], "f": 0, "t": 2, "d": [112], "a": 1 },
{ "px": [512,160], "src": [64,0], "f": 0, "t": 2, "d": [116], "a": 1 },
{ "px": [96,192], "src": [64,0], "f": 0, "t": 2, "d": [123], "a": 1 },
{ "px": [224,192], "src": [64,0], "f": 0, "t": 2, "d": [127], "a": 1 },
{ "px": [384,192], "src": [64,0], "f": 0, "t": 2, "d": [132], "a": 1 },
{ "px": [512,192], "src": [64,0], "f": 0, "t": 2, "d": [136], "a": 1 },
{ "px": [224,224], "src": [64,0], "f": 0, "t": 2, "d": [147], "a": 1 },
{ "px": [384,224], "src": [64,0], "f": 0, "t": 2, "d": [152], "a": 1 },
{ "px": [224,256], "src": [64,0], "f": 0, "t": 2, "d": [167], "a": 1 },
{ "px": [384,256], "src": [64,0], "f": 0, "t": 2, "d": [172], "a": 1 },
{ "px": [448,256], "src": [64,0], "f": 0, "t": 2, "d": [174], "a": 1 },
{ "px": [224,288], "src": [64,0], "f": 0, "t": 2, "d": [187], "a": 1 },
{ "px": [384,288], "src": [64,0], "f": 0, "t": 2, "d": [192], "a": 1 },
{ "px": [448,288], "src": [64,0], "f": 0, "t": 2, "d": [194], "a": 1 },
{ "px": [96,320], "src": [64,0], "f": 0, "t": 2, "d": [203], "a": 1 },
{ "px": [128,320], "src": [64,0], "f": 0, "t": 2, "d": [204], "a": 1 },
{ "px": [160,320], "src": [64,0], "f": 0, "t": 2, "d": [205], "a": 1 },
{ "px": [192,320], "src": [64,0], "f": 0, "t": 2, "d": [206], "a": 1 },
{ "px": [224,320], "src": [64,0], "f": 0, "t": 2, "d": [207], "a": 1 },
{ "px": [384,320], "src": [64,0], "f": 0, "t": 2, "d": [212], "a": 1 },
{ "px": [416,320], "src": [64,0], "f": 0, "t": 2, "d": [213], "a": 1 },
{ "px": [448,320], "src": [64,0], "f": 0, "t": 2, "d": [214], "a": 1 },
{ "px": [480,320], "src": [64,0], "f": 0, "t": 2, "d": [215], "a": 1 },
{ "px": [512,320], "src": [64,0], "f": 0, "t": 2, "d": [216], "a": 1 }
],
"entityInstances": []
}
],
"__neighbours": []
}
],
"worlds": [],
"dummyWorldIid": "267ee1a0-d7b0-11ee-a97e-53f0a359eae1"
}

View File

@@ -1,23 +1,17 @@
package assets
import (
"bufio"
_ "image/png"
"io/fs"
"log"
"log/slog"
"openquell/config"
"openquell/util"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"github.com/hajimehoshi/ebiten/v2"
"github.com/solarlune/ldtkgo"
)
var Levels = LoadLevels("levels")
var Project = LoadLDTK("levels")
var Tiles = InitTiles()
// Tile: contains image, identifier (as used in level data) and
@@ -186,44 +180,22 @@ func NewTileHiddenDoor(class []string) *Tile {
}
// used to map level data bytes to actual tiles
type TileRegistry map[byte]*Tile
// holds a raw level spec:
//
// Name: the name of the level file w/o the .lvl extension
// Background: an image name used as game background for this level
// Description: text to display on top
// Data: a level spec consisting of chars of the above mapping and spaces, e.g.:
// ####
// # #
// ####
//
// Each level data must be 20 chars wide (= 640 px width) and 15 chars
// high (=480 px height).
type RawLevel struct {
Number int
Name string
Description string
Background *ebiten.Image
Data []byte
MinMoves int
}
type TileRegistry map[string]*Tile
func InitTiles() TileRegistry {
return TileRegistry{
' ': {Id: ' ', Class: "floor", Renderable: false},
//'#': NewTileBlock("block-grey32"),
'#': NewTileBlock("block-greycolored"),
'B': NewTileBlock("block-orange-32"),
'S': NewTilePlayer(Primary),
's': NewTilePlayer(Secondary),
'o': NewTileCollectible("collectible-orange"),
'+': NewTileObstacle("obstacle-star", config.All),
'^': NewTileObstacle("obstacle-north", config.North),
'v': NewTileObstacle("obstacle-south", config.South),
'<': NewTileObstacle("obstacle-west", config.West),
'>': NewTileObstacle("obstacle-east", config.East),
'*': NewTileParticle([]string{
"floor": {Id: ' ', Class: "floor", Renderable: false},
"default": NewTileBlock("block-greycolored"),
"solidorange": NewTileBlock("block-orange-32"),
"player-primary": NewTilePlayer(Primary),
"player-secondary": NewTilePlayer(Secondary),
"collectible": NewTileCollectible("collectible-orange"),
"obstacle-star": NewTileObstacle("obstacle-star", config.All),
"obstacle-north": NewTileObstacle("obstacle-north", config.North),
"obstacle-south": NewTileObstacle("obstacle-south", config.South),
"obstacle-west": NewTileObstacle("obstacle-west", config.West),
"obstacle-east": NewTileObstacle("obstacle-east", config.East),
"particle": NewTileParticle([]string{
//"particle-ring-1",
"particle-ring-2",
"particle-ring-3",
@@ -231,91 +203,56 @@ func InitTiles() TileRegistry {
"particle-ring-5",
"particle-ring-6",
}),
't': NewTileTranswall([]string{"transwall", "block-orange-32"}),
'W': NewTileHiddenDoor([]string{"block-greycolored", "block-greycolored-damaged"}),
"transient": NewTileTranswall([]string{"transwall", "block-orange-32"}),
"hiddendoor": NewTileHiddenDoor([]string{"block-greycolored", "block-greycolored-damaged"}),
}
}
// load levels at compile time into ram, creates a slice of raw levels
func LoadLevels(dir string) []RawLevel {
levels := []RawLevel{}
// we use embed.FS to iterate over all files in ./levels/
entries, err := assetfs.ReadDir(dir)
// load LDTK project at compile time into ram
func LoadLDTK(dir string) *ldtkgo.Project {
fd, err := assetfs.Open("levels/openquell.ldtk")
if err != nil {
log.Fatalf("failed to read level dir %s: %s", dir, err)
}
sort.Slice(entries, func(i, j int) bool {
return entries[i].Name() < entries[j].Name()
})
for idx, levelfile := range entries {
if levelfile.Type().IsRegular() && strings.Contains(levelfile.Name(), ".lvl") {
path := filepath.Join("assets", dir)
level := ParseRawLevel(path, levelfile)
level.Number = idx
levels = append(levels, level)
slog.Debug("loaded level", "path", path, "file", levelfile)
}
}
return levels
}
func ParseRawLevel(dir string, levelfile fs.DirEntry) RawLevel {
fd, err := os.Open(filepath.Join(dir, levelfile.Name()))
if err != nil {
log.Fatalf("failed to read level file %s: %s", levelfile.Name(), err)
log.Fatalf("failed to open LDTK file levels/openquell.ldtk: %s", err)
}
defer fd.Close()
name := strings.TrimSuffix(levelfile.Name(), ".lvl")
name = name[3:]
des := ""
background := &ebiten.Image{}
data := []byte{}
minmoves := 0
fileinfo, err := fd.Stat()
if err != nil {
log.Fatalf("failed to stat() LDTK file levels/openquell.ldtk: %s", err)
}
scanner := bufio.NewScanner(fd)
for scanner.Scan() {
// ignore any whitespace
line := scanner.Text()
filesize := fileinfo.Size()
buffer := make([]byte, filesize)
// ignore empty lines
if len(line) == 0 {
continue
_, err = fd.Read(buffer)
if err != nil {
log.Fatalf("failed to read bytes from LDTK file levels/openquell.ldtk: %s", err)
}
project, err := ldtkgo.Read(buffer)
if err != nil {
panic(err)
}
// do some sanity checks
properties := []string{"min-moves", "background", "level", "name", "descrption"}
need := len(properties)
for idx, level := range project.Levels {
have := 0
for _, property := range level.Properties {
if util.Contains(properties, property.Identifier) {
have++
}
}
switch {
case strings.Contains(line, "Background:"):
haveit := strings.Split(line, ": ")
if util.Exists(Assets, haveit[1]) {
background = Assets[haveit[1]]
}
case strings.Contains(line, "Description:"):
haveit := strings.Split(line, ": ")
des = haveit[1]
case strings.Contains(line, "MinMoves:"):
haveit := strings.Split(line, ": ")
minmoves, err = strconv.Atoi(haveit[1])
if err != nil {
log.Fatal("Failed to convert MinMoves to int: %w", err)
}
default:
// all other non-empty and non-equalsign lines are
// level definition matrix data, merge thes into data
data = append(data, line+"\n"...)
if have != need {
log.Fatalf("level definition for level %d (%s) invalid: %d missing properties\n required: %s",
idx, level.Identifier, need-have, strings.Join(properties, ", "),
)
}
}
return RawLevel{
Name: name,
Data: data,
Background: background,
Description: des,
MinMoves: minmoves,
}
return project
}

View File

@@ -16,7 +16,7 @@ import (
// Maps image name to image data
type AssetRegistry map[string]*ebiten.Image
//go:embed levels/*.lvl sprites/*.png fonts/*.ttf
//go:embed sprites/*.png fonts/*.ttf levels/*.ldtk
var assetfs embed.FS
var Assets = LoadImages("sprites")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

View File

@@ -0,0 +1,2 @@
#!/bin/sh
montage -tile 4x0 -geometry +0+0 block* collectible-orange.png obstacle-* sphere-blue* transwall.png map.png && okular map.png

BIN
assets/sprites/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB