I need help making a faster way to draw this...

Immediately, somethings I can see that are problematic =

  1. The switch over to meshes has rendered my touched() code useless
  2. You have a for loop to randomize the blocks, that’s useless now too
  3. You only have to call mesh.texture once
    As I notice more things, I wil add them

worldCreate = class()

function worldCreate:init()
    -- you can accept and set parameters here
    wWidth = WIDTH/32
    wHeight = HEIGHT/2/32
    world = {}
    id = {}
    --blocks = {}
    img = readImage("Documents:Minecraft Tileset")
    --blocks["grass"] = mesh()
    --blocks["dirt"] = mesh()
    --blocks["stone"] = mesh() -- CHANGED IT ALL TO ONE MESH!!!
    blocks = mesh()
    blocks.texture = img
    for i = 1,wWidth do
        world[i] = {}
        for j = 1, wHeight do
            world[i][j] = math.random(6)
        end
    end
    
    for r,row in pairs(world) do
        id[r] = {}
        for c,col in pairs(row) do
            id[r][c] = blocks:addRect(-16 + r*32,-16 + c*32,32,32) 
                -- -64 is way too much (or too little...), it should be -16
                -- so is - 32
                -- Moving this line out of the if clause, because it would be called every time
            if c == wHeight then
                blocks:setRectTex(id[r][c], 3/16,15/16,32/512,32/512)
            elseif c < (wHeight - 2) and c >= 7 and col > 5 then
                blocks:setRectTex(id[r][c], 6/16,15/16,32/512,32/512)
            else
                blocks:setRectTex(id[r][c],2/16,15/16,32/512,32/512)
            end
        end
    end
end

function worldCreate:draw()
    -- Codea does not automatically call this method
    blocks:draw()
end

function worldCreate:touched(touch)
    -- Codea does not automatically call this method
    if touch.state == ENDED and touch.y < HEIGHT / 2  then
        blocks:setRect(id[math.ceil(touch.x/32)][math.ceil(touch.y/32)], 0, 0, 0, 0)
    end
end

You are welcome!


worldCreate = class()

function worldCreate:init()
    -- you can accept and set parameters here
    wWidth = WIDTH/32
    wHeight = HEIGHT/2/32
    world = {}
    id = {}
    --blocks = {}
    img = readImage("Documents:Minecraft Tileset")
    --blocks["grass"] = mesh()
    --blocks["dirt"] = mesh()
    --blocks["stone"] = mesh() -- CHANGED IT ALL TO ONE MESH!!!
    blocks = mesh()
    blocks.texture = img
    for i = 1,wWidth do
        world[i] = {}
        for j = 1, wHeight do
            world[i][j] = math.random(6)
        end
    end
    
    for r,row in pairs(world) do
        id[r] = {}
        for c,col in pairs(row) do
            id[r][c] = blocks:addRect(-16 + r*32,-16 + c*32,32,32) 
                -- -64 is way too much (or too little...), it should be -16
                -- so is - 32
                -- Moving this line out of the if clause, because it would be called every time
            if c == wHeight then
                blocks:setRectTex(id[r][c], 3/16,15/16,32/512,32/512)
            elseif c < (wHeight - 2) and c >= 7 and col > 5 then
                blocks:setRectTex(id[r][c], 6/16,15/16,32/512,32/512)
            else
                blocks:setRectTex(id[r][c],2/16,15/16,32/512,32/512)
            end
        end
    end
end

function worldCreate:draw()
    -- Codea does not automatically call this method
    blocks:draw()
end

function worldCreate:touched(touch)
    -- Codea does not automatically call this method
    if touch.state == ENDED and touch.y < HEIGHT / 2  then
        blocks:setRect(id[math.ceil(touch.x/32)][math.ceil(touch.y/32)], 0, 0, 0, 0)
    end
end

You are welcome!

Deleting the rectangle from the world table isn’t enough: you’ve already copied all of that information across to the mesh so you need to delete it from the mesh. To do that, you need to save the identification numbers returned by the addRect method. Then you can use setRect(id,...) to effectively remove that rectangle at a later date (you cannot set it to nil, but if you set all the coordinates to 0 then it has the same effect). Your id table is almost there, but it only saves the id of the last rectangle in the row. I can’t see where else you use that, though.

Here’s what I think would work. You only need one mesh and then use world to save the ids so the init function looks like:

function worldCreate:init()
    -- you can accept and set parameters here
    local wWidth = WIDTH/32 + 2
    local wHeight = HEIGHT/2/32
    local world = {}
    local img = readImage("Documents:Minecraft Tileset")
    local blocks = mesh()
    blocks.texture = img

    local col,id
    for r = 1,wWidth do
        world[r] = {}
        for c = 1, wHeight do
            col = math.random(6)
            id = blocks:addRect(-64 + r*32,-32 + c*32,32,32)
            if c == wHeight then
                blocks:setRectTex(id, 3/16,15/16,32/512,32/512)
            elseif c < (wHeight - 2) and c >= 7 and col > 5 then
                blocks:setRectTex(id, 6/16,15/16,32/512,32/512)
            else
                blocks:setRectTex(id,2/16,15/16,32/512,32/512)
            end
            world[r][c] = id
        end
    end
    self.world = world
    self.blocks = blocks
end

The draw method only needs to call self.blocks:draw(). Then the touched function is:

function worldCreate:touched(touch)
    -- Codea does not automatically call this method
    if touch.state == ENDED then
        self.blocks:setRect(self.world[math.ceil(touch.x/32)][math.ceil(touch.y/32)],0,0,0,0)
    end
end

(Warning: not tested)

(I see Jordan’s had pretty much the same ideas as me!)

But I posted first, so you had the same idea as ME! :stuck_out_tongue: But I see our code is pretty much identical, except that you made self.world = world and self.blocks = blocks

Possible responses:

  1. Careful, or I’ll use my superpowers to change the order of posts so it looks like you had the same idea as me.
  2. You just type faster than I do, that’s all.

If you choose (1), turn to page 45. If you choose (2), turn to page 63.

(Sorry, been reading those “Decide your destiny” books with my kids.)

More seriously, yes. A class should never set or modify global variables: what if you had two instances of the class? So things that the instance “owns” should be of the form self.whatever.

Sorry to pollute this thread, but @Andrew_Stacey, I am working on a class that interacts with the touched function, modifies it, and returns it. But I have a problem… When I want to remove that class, I also need to restore the touched function, so it doesn’t execute its code, how can I do that, without wiping the other instances of the class’s changes to touched. My current solution is using a table, but I think that is an ugly answer to my question… Any help from you? (And do you think this is worth a new discussion?

And do you think this is worth a new discussion?

Yes, I do. And put some code in as I have only the vaguest idea what you’re doing!

Buttons, lots and lots of buttons. :wink: Imagine the possibilities, buttons, without having to put the pesky myButton:touched! It’s the future!

Thanks you guys, it seems your guys could do my project in a day if you wanted to :stuck_out_tongue:
But I do have another question. I’m trying to develop an id system to determine which blocks are which.
Kinda like:

if blockID = "stone" then
    stone = stone + 1
end

I’ve tried a few ways with unsuccessful results, I’m sure you guys could help :slight_smile:

Hold on, let me try something out… blockID = "stone"
I’ve Always wondered how you put pieces of code in like that! Now I know! Lol, okay back to my project

I am thinking (I can’t seem to get this to work, I will leave the code to @Andrew_Stacey) that you would have to use an if clause to check if the texture coordinates are the stone co ords :slight_smile:

Nevermind. I figured it out. I’m sure you guys could do better but for now I’ll use what I gots. Thanks for everything so far!

Code please? :slight_smile:

Added bid(block id) to the code

    for r,row in pairs(world) do
        id[r] = {}
        bid[r] = {}
        for c,col in pairs(row) do
            id[r][c] = blocks:addRect(-16 + r*32,-16 + c*32,32,32)
            if c == wHeight then
                blocks:setRectTex(id[r][c], 3/16,15/16,32/512,32/512)
                bid[r][c] = 1
            elseif c < (wHeight - 2) and c >= 7 and col > 5 then
                blocks:setRectTex(id[r][c], 1/16,15/16,32/512,32/512)
                bid[r][c] = 2
            else
                blocks:setRectTex(id[r][c],2/16,15/16,32/512,32/512)
                bid[r][c] = 3
            end
        end
    end

Then I put tht in an if clause

pic.twitter.com/LTNZX2sJ
Pic of v0.1

I’ve embedded your image here: Minecraft
(You can do this by typing ![ImageName](ImageLink))

thanks

Note = @RichGala1, you must provide the direct link to the image e.g. http://p.twimg.com/A1kZrQWCQAEdfRb.jpg:large