Coder Social home page Coder Social logo

simple-tiled-implementation's Introduction

Simple Tiled Implementation

Join the chat at https://gitter.im/karai17/Simple-Tiled-Implementation

If you like STI, consider tossing me a few monies via PayPal.

Simple Tiled Implementation is a Tiled map loader and renderer designed for the awesome LÖVE framework. Please read the documentation to learn how it works, or check out the tutorials included in this repo.

Quick Example

-- This example uses the included Box2D (love.physics) plugin!!

local sti = require "sti"

function love.load()
	-- Grab window size
	windowWidth  = love.graphics.getWidth()
	windowHeight = love.graphics.getHeight()

	-- Set world meter size (in pixels)
	love.physics.setMeter(32)

	-- Load a map exported to Lua from Tiled
	map = sti("assets/maps/map01.lua", { "box2d" })

	-- Prepare physics world with horizontal and vertical gravity
	world = love.physics.newWorld(0, 0)

	-- Prepare collision objects
	map:box2d_init(world)

	-- Create a Custom Layer
	map:addCustomLayer("Sprite Layer", 3)

	-- Add data to Custom Layer
	local spriteLayer = map.layers["Sprite Layer"]
	spriteLayer.sprites = {
		player = {
			image = love.graphics.newImage("assets/sprites/player.png"),
			x = 64,
			y = 64,
			r = 0,
		}
	}

	-- Update callback for Custom Layer
	function spriteLayer:update(dt)
		for _, sprite in pairs(self.sprites) do
			sprite.r = sprite.r + math.rad(90 * dt)
		end
	end

	-- Draw callback for Custom Layer
	function spriteLayer:draw()
		for _, sprite in pairs(self.sprites) do
			local x = math.floor(sprite.x)
			local y = math.floor(sprite.y)
			local r = sprite.r
			love.graphics.draw(sprite.image, x, y, r)
		end
	end
end

function love.update(dt)
	map:update(dt)
end

function love.draw()
	-- Draw the map and all objects within
	love.graphics.setColor(1, 1, 1)
	map:draw()

	-- Draw Collision Map (useful for debugging)
	love.graphics.setColor(1, 0, 0)
	map:box2d_draw()

	-- Please note that map:draw, map:box2d_draw, and map:bump_draw take
	-- translate and scale arguments (tx, ty, sx, sy) for when you want to
	-- grow, shrink, or reposition your map on screen.
end

Requirements

This library recommends LÖVE 11.x and Tiled 1.2.x. If you are updating from an older version of Tiled, please re-export your Lua map files.

License

This code is licensed under the MIT/X11 Open Source License. Check out the LICENSE file for more information.

simple-tiled-implementation's People

Contributors

133794m3r avatar alesegdia avatar bjorn avatar bobbyjoness avatar cluke009 avatar coz-eduardo-hernandez avatar danielpower avatar derakon avatar doolinius avatar drauthius avatar drjamgo avatar entrancejew avatar gitter-badger avatar ioribranford avatar josefnpat avatar karai17 avatar lemilonkh avatar lukaspirkl avatar matiasah avatar maxha651 avatar npinochet avatar pevzi avatar premek avatar prust avatar rosshadden avatar rozenmad avatar saevyn avatar tobiasvl avatar tomc1998 avatar tyraindreams avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-tiled-implementation's Issues

tile object rotation

The rotation of a tile object is ignored when drawing.
setObjectSpriteBatches need to check rotation.

Requires canvas

This should be stated in the documentation or somehow add a way to support computers without canvas support (which I would really appreciate hahaha)

Sprite Batches

Efficient drawing of bajillions of tiles would be useful.

bit.lua

Not everyone will have bit.lua as required here. Won't this be an issue?

Scaling

When scaling using a non-integer factor, there are unsightly lines between tiles. This needs to be fixed!

Code Cleanup

Move some things (batch creation, etc) into their own functions and try to simplify some expensive tasks

Advice from Bjorn

[17:34:00] Karai: Basically you should probably take the following steps:
[17:34:33] 1. Make sure that for each tile, there is a table with whatever information needs to be there to render it. There's only so many tiles, so this isn't a lot of data.
[17:35:00] 2. During loading, change each layer.data[index] from the gid it is now to a reference to one of these tile tables.
[17:36:16] 3. During rendering, do a double-for loop over y and x, then do local tile = layer.data[y * width + x + 1] and render this tile at x * tileWidth, y * tileHeight.
[17:36:50] This index assumes your x/y iterate from 0 to width-1/height-1.

tl;dr build a table with y/x coord and iterate through them. should probably store the tileset index in the tile grid, too

Callbacks

Should STI support callbacks? If so, which? I feel like the ability to extend drawing and updating might be useful in the future.

Micro Optimizations

  • No global lookups are in loops
    • local draw = love.graphics.draw
    • local floor = math.floor
    • local layer = self.layers["Some Layer"]
  • Locals outside of loops when possible

Installation Help - Setup Tutorial in the Documentation Needed.

While this is not an issue, it is a question.

I probably come off sounding really stupid, but how do I actually go about installing the library?
I download the raw zip from github, because that's the only link available, and then I add it to my project's folder. However, while calling sti (local sti = require("sti")), nothing happens, because there's no STI file in the zip.

Is there a process to go through, or am I missing something?
I'd recommend some form of setup tutorial in the documentation for the future.

sti.new Function Argument

I'm not very experienced in this realm, but if I'm not mistaken, aren't all of our map files going to be .lua files? If so, I think it would be great if you just did

map = sti.new( "map" )

instead of

map = sti.new( "map.lua" )

Just my opinion, though.

Different Sized tiles?

Will STI provide capabilities for different size tiles or overlapping tiles (like Micha used in their project, mentioned here?)

Doesn't work in Love2d 0.9.1

When I try run returns this error:

Error: libs/sti/framework/love.lua:22: Cannot create canvas: Error in implementation. Possible fix: Make canvas width and height powers of two.
stack traceback:
    [C]: in function 'newCanvas'
    libs/sti/framework/love.lua:22: in function 'newCanvas'
    libs/sti/init.lua:58: in function 'new'
    main.lua:4: in function 'load'
    [string "boot.lua"]:407: in function <[string "boot.lua"]:399>
    [C]: in function 'xpcall'

Tile object shape position

Hi,

Tile objects shape are not at the right position. But the tile itself is ok.

Some screenshots to illustrate:

In editor
oneditor

In game
ongame
The shape is drawn below the tile

Flipped and rotated tiles?

In Tiled, you can flip/rotates tiles with x, y, and z before laying them down. Will STI support these tiles?

Draw to canvas

Draw the map to canvas pre-scaling, then draw the scaled canvas to screen. This should resolve any quirky scaling bugs or misaligned tiles.

Wrong gid

current stable and daily Tiled exports map to lua in such a way that tile ID in a tileset and tile ID used in layer.data to represent a map are different. So that if using STI I'll try to get a tile from the map by gid taken from layer data tile, I will fail. Than makes impossible to use tile properties:

local layer = map.layers['ground']
for x=1, map.width do
        for y=1, map.height do
            local tile = layer.data[y][x] -- layer tile has ID 37 for instance
            map.tiles[tile.gid] -- that same tile in that collection will have different ID (36) and thus indexing will fail
        end
end

libs/sti.lua:191: attempt to index local 'tile' (a nil value)

libs/sti.lua:191: attempt to index local 'tile' (a nil value)

This occurs in current ~master (9a33807) when executing sti.new on a map which has spacing set when creating a new tileset. In my specific example, I'm trying to use a spacing of 3.

Setting spacing to 0 fixes the problem. Seems to be related to the bit twiddling after minor inspection.

Drawing individual layers

Allow for use of layer name/number in these functions (like the documentation says!)

if type(layer) == "String" then
    layer = self.layers[layer]
end

Collision

Should the library support a basic collision layer/collidable objects, or should that be completely left up to developers?

If so, what would be the best way to do this? Some options could be tileset/object properties, layer properties.

Provide functions to convert between coordinate systems.

You should provide helper functions to convert between isometric and cartesian coordinate systems. Perhaps you should additionally provide a function to see which isometric tile a certain screen location is at (as tiles are not squares, and therefore the standard way of detecting it will not work).

Updating Tiles

Tiles should be able to be updated in real-time. This could include changing the gid.

What are some other properties that could be useful to update?

Custom Layers

ATL used Custom Layers to allow developers to place sprites or whatever in a layer for proper draw order. What would be the best way to go about this?

Map Scaling

Should this be an option for the library, or should I leave it up to developers to implement their own scaling?

Rendering Maps smaller than the screen

I was trying to render a map that was smaller than my screen in full screen (the map is 20x17 w/ 32x32 tiles) and by using the love.graphics.translate and setDrawRange functions in various ways, No matter what the map is moved over and cut off.

Draw Range

Automatic draw range, and manual override would be useful for efficiency.

Support for Tile Collections

STI currently supports tileset spritesheets, but does not support tileset collections. This needs to be fixed!

addCustomLayer()

local layer = {}
table.insert(map.layers, whatever_index, layer)

Tiled Animation System

Tiled 0.9.2 will support Tile Animations, so it would be nice to get those implemented soonish.

Draw call should respect current canvas in LOVE

Hi I am the author of light_world.lua and I have been trying to get my library to work with your and I have found the clear way to do this. The only problem is that your code needs to change a bit, but I dont want to disturb your support for other frameworks.

so here is the problem, here is your draw code

function Map:draw(sx, sy)
    framework.setCanvas(self.canvas) 
    framework.clear(self.canvas)-- this calls love.graphics.clear() meaning it clears the screen not the canvas

    for _, layer in ipairs(self.layers) do
        if layer.visible and layer.opacity > 0 then
            self:drawLayer(layer)
        end
    end

    framework.setCanvas() -- this does not set it back to the last canvas if the map is being drawn to a canvas

    framework.push()
    framework.origin()
    framework.draw(self.canvas, 0, 0, 0, sx, sy)
    framework.pop()
end

Here are my fixes without respect to other framworks:

function Map:draw(sx, sy)
        local current_canvas = love.graphics.getCanvas() -- get the canvas we are drawing to
    framework.setCanvas(self.canvas)
        canvas:clear() --clear the canvas instead of the screen
    --framework.clear(self.canvas)

    for _, layer in ipairs(self.layers) do
        if layer.visible and layer.opacity > 0 then
            self:drawLayer(layer)
        end
    end

    framework.setCanvas(current_canvas) --set back to old canvas or nil if there isnt one

    framework.push()
    framework.origin()

    framework.draw(self.canvas, 0, 0, 0, sx, sy)
    framework.pop()
end

Changing this could make your library a bit more flexible to integrate into other libraries. Let me know what you think.

Juttering

For some reason, the map seems to jutter when it moves. Everything is floored or ceiled so I can't really find out where the issue comes from. Any ideas?

incorrect collision layer name elegant nil error

When I use map:createCollisionMap() and pass in an incorrect layer the program throws a nil error. I want STI to instead hold my hand and tell me that I made a mistake and that it's ok and that everyone makes mistakes and that the layer name could not be found.

Improve Documentation

While the documentation explains how to use the API, it doesn't explain how to use internal data. Some improvements that could be made are:

  • Explain how map.layers works
  • Explain Tile Objects from map.tiles and map.layers[y][x]
  • Explain how to get properties from map.tiles and map.layers

STI should implement a broader collision system

Now that the meat of the collision system is built, it should be pretty simple to extend collision object creation to any layer, tile, object, or image.

If a map developer adds the property collidable to anything that can have properties, and sets the value to true, then Map:initWorldCollision() will create collision objects from that thing and any subset therein.

Framework-Agnostic API

Hello,

I realize that this may be out of the scope of the project; however, I wanted to see if you (or anyone else) had any interest.

Basically, I'm working on a networked game and I use STI. The problem is, the game supports both listen and dedicated servers. The dedicated server only uses Lua (and not LÖVE). It still needs to use some things from STI primarily for server-side collision detection. Obviously this becomes problematic.

It would be nice if there was stilua.lua and stilove.lua, the former containing LÖVE-agnostic functionality, and the latter containing LÖVE-using functionality such as sprite batching and drawing. Another advantage of this is the ease of creating more frontends for Lua game engines such as Corona (sticorona.lua), and of course my original case of a dedicated server.

It doesn't seem like much work, so I'll probably do it in a fork when I have time. Is this too far out of the scope of the project or perhaps you'd be interested in a pull request when I'm done?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.