Shortcut for platforms

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
GungnirDev
Party member
Posts: 119
Joined: Thu Jun 28, 2012 10:31 pm

Shortcut for platforms

Post by GungnirDev »

In my platformer, I'm trying to create a system where I can post something like "platform1(x, y)" and it'll post both the necessary collision boxes and the image altogether, in the right places. This way I can create 10-20 platform types and paste them at will, minimizing code-per-level. How can I do this?

The platforms look like this.

Code: Select all

platform = {}
platform.x = 50
platform.y = 400
platform.w = 100
platform.h = 5
table.insert(platforms, platform)
The image code looks like this:

Code: Select all

love.graphics.draw(natplat1, x, y)
Bullets are the beauty of the blistering sky
Bullets are the beauty and I don't know why
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Shortcut for platforms

Post by HugoBDesigner »

Sorry to say this, but your post was a little vague for me. The way I interpreted this:

You want to make multiple platforms in an easy way and draw them just as easy. Here's a good solution for both:

To make them:

Code: Select all

function newplatform(x, y, w, h)
    return {x = x, y = y, width = w, height = h}
end
Where you make them:

Code: Select all

table.insert(platforms, newplatform(x, y, w, h))

To draw them (supposing they're rectangles. If not it's easy to adapt):

Code: Select all

function drawplatform(platform)
    local x, y, w, h = unpack(platform)
    love.graphics.rectangle("fill", x, y, w, h)
end
And where you draw them:

Code: Select all

drawplatform(platforms[i])
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
GungnirDev
Party member
Posts: 119
Joined: Thu Jun 28, 2012 10:31 pm

Re: Shortcut for platforms

Post by GungnirDev »

I am not quite sure where you are meaning for me to plug these in. I've rearranged the code a few times but I keep receiving 'syntax' or 'nil' errors. I've not done many shortcuts in LOVE before.

Code: Select all

platform = {}

function newplatform(x, y, w, h)
    return {x = x, y = y, width = w, height = h}
end

function drawplatform(platform)
    local x, y, w, h = unpack(platform)
    love.graphics.rectangle("fill", x, y, w, h)
end


function love.load()

end

function love.update(dt)

table.insert(platforms, newplatform(x, y, w, h))

end

function love.draw()

drawplatform(platforms[i])

end
To better help you understand my predicament, I am already able to create rectangular platforms. However, I have platform-images with irregular shapes, and I want to use these as platforms. So, I want to create a platform for each horizontal surface of this platform, and also post the image, and create this as a single platform (let's say, called, natplat2).

Then, by typing natplat2(x, y) I should be able to place this platform anywhere I choose. Does that make more sense?
Attachments
light red is platform-space to walk on.  dark red is background-trim.
light red is platform-space to walk on. dark red is background-trim.
natplat2.png (87.04 KiB) Viewed 3452 times
Bullets are the beauty of the blistering sky
Bullets are the beauty and I don't know why
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Shortcut for platforms

Post by HugoBDesigner »

GungnirDev wrote:I am not quite sure where you are meaning for me to plug these in. I've rearranged the code a few times but I keep receiving 'syntax' or 'nil' errors. I've not done many shortcuts in LOVE before.

Code: Select all

platform = {}

function newplatform(x, y, w, h)
    return {x = x, y = y, width = w, height = h}
end

function drawplatform(platform)
    local x, y, w, h = unpack(platform)
    love.graphics.rectangle("fill", x, y, w, h)
end


function love.load()

end

function love.update(dt)

table.insert(platforms, newplatform(x, y, w, h))

end

function love.draw()

drawplatform(platforms[i])

end
To better help you understand my predicament, I am already able to create rectangular platforms. However, I have platform-images with irregular shapes, and I want to use these as platforms. So, I want to create a platform for each horizontal surface of this platform, and also post the image, and create this as a single platform (let's say, called, natplat2).

Then, by typing natplat2(x, y) I should be able to place this platform anywhere I choose. Does that make more sense?
Oh, okay then.

So, if you want to use images to make objects, you have a few ways of doing this. Some are harder, some are not:

• Convert pixels to platforms (slower, more work for computer, more chances to fail, much more precision for collisions *precision is variable, depending on the computer speed);

• Convert lines of pixels to platform (slow, but not as much as pixels, more work for computer, smaller chances to fail, much more precision for collision);

• Convert blocks of pixels to platforms by using an image mask (fast, less work for computer, little chances to fail, good precision, but not as much as pixel maps);


I already used the first option in a mod I made for Mari0, called Mari0 +Portal. There's a tile property I made named "Pixel collision" that converts each pixel of a tile to a collidable point. It is very slow and fails many times (because of slowing down PC speed), but if I were/am going to remake that, I'd use the second option because of it's precision. For your case, I'd use the last.


Make it so when you're loading the image, it groups similar color of pixels and "draws" a rectangle based on these points. Something like this:

Code: Select all

local imgdata = love.image.newImageData(platform mask image)

local platsToDo = {}
for x = 0, imgdata:getWidth()-1 do
    for y = 0, imgdata:getHeight()-1 do
        local r, g, b, a = imgdata:getPixel(x, y)
        if a == 255 then --If opaque, and not transparent
            if platsToDo[r.."-"..g.."-"..b] then
                platsToDo[r.."-"..g.."-"..b][2] = {x+1, y+1}
            else
                platsToDo[r.."-"..g.."-"..b] = {}
                platsToDo[r.."-"..g.."-"..b][1] = {x+1, y+1}
            end
        end
    end
end

for i, v in pairs(platsToDo) do
    if v[1] and v[2] then --make a rectangle
        table.insert(platforms, platform:new(v[1][1], v[1][2], v[2][1]-v[1][1], v[2][2]-v[1][2])
    end
end
But in the example above (which should work, so feel free to use if you want), I'm directly converting them into the screen. If your games dimensions don't apply (tiles, scale or something else) or your platform should not be made in the same spots as the image mask (multiple platforms in different places, for example), just convert to your game's dimension on the "table.insert" part, where it creates the platforms. Also, if instead of the system "x, y, width, height" you're using a system like "x1, y1, x2, y2", just remove the values being subtracted in the last 2 arguments on the platform creator.

I hope I helped. If not, just let me know :)

EDIT: Here's an example of it based on your image. I had to make it on Windows XP paint, because I'm not in my computer, so sorry in advance for the quality. Just make like in the image below, except for the background (use a transparent background too). You have to make each rectangle of a different color, but, by using some program other than Paint I'm sure you can do a lot better ;)
Attachments
Sorry, again, for the poor quality...
Sorry, again, for the poor quality...
MapExample.PNG (41.89 KiB) Viewed 3436 times
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
GungnirDev
Party member
Posts: 119
Joined: Thu Jun 28, 2012 10:31 pm

Re: Shortcut for platforms

Post by GungnirDev »

Ok, that's good, but now I have problems. I tacked on a parenthesis after

Code: Select all

table.insert(platforms, platform:new(v[1][1], v[1][2], v[2][1]-v[1][1], v[2][2]-v[1][2])
since it was giving me an error. Now I get a different error: 'attempt to call method 'new' (a nil value).' I think it might be a problem with your solution being dated for love 8.0? Maybe there is a different term used in 9.0.
Bullets are the beauty of the blistering sky
Bullets are the beauty and I don't know why
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Shortcut for platforms

Post by HugoBDesigner »

GungnirDev wrote:Ok, that's good, but now I have problems. I tacked on a parenthesis after

Code: Select all

table.insert(platforms, platform:new(v[1][1], v[1][2], v[2][1]-v[1][1], v[2][2]-v[1][2])
since it was giving me an error. Now I get a different error: 'attempt to call method 'new' (a nil value).' I think it might be a problem with your solution being dated for love 8.0? Maybe there is a different term used in 9.0.
No, this is general code. I mean, it works in most versions of LÖVE, including 0.8.0 and 0.9.0.
Anyway, I made the "platform:new" thing because I'm really used to the class function. But in your case, replace the "platform:new" by "newplatform" and use the code I wrote in a previous post. This should pretty much work, but I don't know about the parenthesis thing. Perhaps you/I made some mistake before/after this line? I can't see why it happens...
@HugoBDesigner - Twitter
HugoBDesigner - Blog
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests