I’m doing something like this now in the game I’m working on in my spare time. I’m not using JSON but a simple Lua module that’s a really big table. Perhaps code will help :-)
-- -- campaign class -- -- A library to manage backgrounds and other campaign needs -- local myData = require("classes.mydata") local M = {} M.maxCampaigns = 8 M.levelsPerCampaign = 5 M.campaign = {} M.campaign[1] = {} M.campaign[1].name="San Fransciso" M.campaign[1].startLevel = 1 M.campaign[1].endLevel = 5 M.campaign[1].minimumStars = 0 M.campaign[1].mapLocation = { x = -98, y = -11 } M.campaign[1].layers = 3 M.campaign[1].layer = {} M.campaign[1].layer[1] = {} M.campaign[1].layer[1].type = "gradient" M.campaign[1].layer[1].start = { 0.0666, 0.0319, 0.0000} M.campaign[1].layer[1].stop = { 0.5906, 0.2542, 0.0000} M.campaign[1].layer[2] = {} M.campaign[1].layer[2].type = "image" M.campaign[1].layer[2].images = {} M.campaign[1].layer[2].images[1] = { filename = "images/sanfran01.png", width = 1201, height = 375 } M.campaign[1].layer[2].images[2] = { filename = "images/sanfran02.png", width = 1201, height = 375 } M.campaign[1].layer[2].images[3] = { filename = "images/sanfran01.png", width = 1201, height = 375 } M.campaign[1].layer[2].images[4] = { filename = "images/sanfran02.png", width = 1201, height = 375 } M.campaign[1].layer[3] = {} M.campaign[1].layer[3].type = "image" M.campaign[1].layer[3].images = {} M.campaign[1].layer[3].images[1] = { filename = "images/buildings01.png", width = 1024, height = 512 } M.campaign[1].layer[3].images[2] = { filename = "images/buildings02.png", width = 1024, height = 512 } M.campaign[1].layer[3].images[3] = { filename = "images/buildings03.png", width = 1024, height = 512 } M.campaign[2] = {} M.campaign[2].name="Chicago" M.campaign[2].startLevel = 6 M.campaign[2].endLevel = 10 M.campaign[2].minimumStars = 12 M.campaign[2].mapLocation = { x = -72, y = -10 } M.campaign[2].layers = 3 M.campaign[2].layer = {} M.campaign[2].layer[1] = {} M.campaign[2].layer[1].type = "gradient" M.campaign[2].layer[1].start = { 0.0912, 0.1302, 0.1348} M.campaign[2].layer[1].stop = { 0.9965, 0.9965, 0.9965} M.campaign[2].layer[2] = {} M.campaign[2].layer[2].type = "image" M.campaign[2].layer[2].images = {} M.campaign[2].layer[2].images[1] = { filename = "images/chicago01.png", width = 750, height = 375 } M.campaign[2].layer[2].images[2] = { filename = "images/chicago02.png", width = 750, height = 375 } M.campaign[2].layer[2].images[3] = { filename = "images/chicago03.png", width = 750, height = 375 } M.campaign[2].layer[2].images[4] = { filename = "images/chicago01.png", width = 750, height = 375 } M.campaign[2].layer[2].images[5] = { filename = "images/chicago02.png", width = 750, height = 375 } M.campaign[2].layer[2].images[6] = { filename = "images/chicago03.png", width = 750, height = 375 } M.campaign[2].layer[3] = {} M.campaign[2].layer[3].type = "image" M.campaign[2].layer[3].images = {} M.campaign[2].layer[3].images[1] = { filename = "images/buildings04.png", width = 1024, height = 512 } M.campaign[2].layer[3].images[2] = { filename = "images/buildings05.png", width = 1024, height = 512 }
My game is organized into campaigns (cities) that you have to defend. I create a master campaign table, then each array entry represents one campaign. It’s got basic information like where it is on the world map. How many stars you need to have earned to play that campaign, start, stop levels etc. Then each campaign has three parallax backgrounds, a background that doesn’t move, a silhouette layer and a buildings layer. There may be multiple images needed to make up each background, so I have an array of images. Some levels don’t have all three layers. But by using this type of construct I can easily set various parameters needed.
Then I have another Lua module dedicated to level specific information:
local M = {} M[1] = { droneType = 1, droneMovement = "straight", spawnSpeed = 3000, spawnCount = 20, bossType = 1, microDroneType = 0, microDroneMovement = "straight", microDroneSpawnPattern = "wall", spawnHealthRate = 20000, spawnPickupRate = 30000, energyChance = 100, freezeChance = 0, toxicChance = 0, nukeChance = 0 } M[2] = { droneType = 2, droneMovement = "sweep", spawnSpeed = 2750, spawnCount = 20, bossType = 2, microDroneType = 0, microDroneMovement = "straight", microDroneSpawnPattern = "wall", spawnHealthRate = 20000, spawnPickupRate = 30000, energyChance = 98, freezeChance = 2, toxicChance = 0, nukeChance = 0 } M[3] = { droneType = 3, droneMovement = "seek", spawnSpeed = 2500, spawnCount = 20, bossType = 1, microDroneType = 0, microDroneMovement = "straight", microDroneSpawnPattern = "wall", spawnHealthRate = 20000, spawnPickupRate = 30000, energyChance = 96, freezeChance = 4, toxicChance = 0, nukeChance = 0 } M[4] = { droneType = 0, droneMovement = "", spawnSpeed = 3000, spawnCount = 25, bossType = 2, microDroneType = 1, microDroneMovement = "straight", microDroneSpawnPattern = "wall", spawnHealthRate = 20000, spawnPickupRate = 30000, energyChance = 94, freezeChance = 6, toxicChance = 0, nukeChance = 0 } M[5] = { droneType = 0, droneMovement = "", spawnSpeed = 3000, spawnCount = 0, bossType = 9, microDroneType = 1, microDroneMovement = "straight", microDroneSpawnPattern = "wall", spawnHealthRate = 20000, spawnPickupRate = 30000, energyChance = 94, freezeChance = 6, toxicChance = 0, nukeChance = 0 }
I have an entry for each table that provides data that I use to drive the enemies. Each enemy (drone, boss, microDrone, minelayer, campaignBoss) has their own .lua file that has all the code for that enemy type, but another table that contains enemy specific features:
local droneData = {} droneData[1] = {} droneData[1].exhaustOffset = { x = -15, y = 0 } droneData[1].fireOffset = { x = 0, y = 0 } droneData[1].health = 1 droneData[1].points = 100 droneData[1].speed = 1 droneData[1].damage = 1 droneData[1].guns = 1 droneData[1].fireSpeed = 900 droneData[1].seeks = false droneData[1].sweeps = false droneData[2] = {} droneData[2].exhaustOffset = { x = -28, y = 5 } droneData[2].fireOffset = { x = -20, y = 12 } droneData[2].health = 2 droneData[2].points = 200 droneData[2].speed = 1 droneData[2].damage = 1 droneData[2].guns = 1 droneData[2].fireSpeed = 850 droneData[2].seeks = false droneData[2].sweeps = true
In my case the drones are all in a single image sheet and the frame index is the same as the index for the droneData. So if my droneType is 1 I will spawn a drone with frame 1 of the image sheet, and give it the above properties.
In my game the basic start up flow is: Menu->Campaign Select->Level Select->Game->Next Level or Game Over with Next Level going back to Game. Each enemy and the player have their own lua files.
Rob