Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

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

edited August 2012 in General Posts: 68

Back to Codea! The title says it all, the 2D Minecraft Project I'm doing is going to require WAAY more drawing than the simple thing I have so far, so I need to find a way to draw things faster so that the framerate is not affected. Here's the code:

-- 2D Minecraft

-- Use this function to perform your initial setup
function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    version = 0.1
    saveProjectInfo("Author","Enro Corp")
    saveProjectInfo("Description", "My quest to create a fun 2D Minecraft begins...")
    saveProjectData("Version",version)
    
    worldCreate:init()
    
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(0)

    -- This sets the line thickness
    strokeWidth(5);rectMode(CENTER);
    noStroke();fill(255)
    font("ArialMT");fontSize(10)
    text("Version "..readProjectData("Version"),WIDTH/2,HEIGHT - 50)

    -- Do your drawing here
    worldCreate:draw()
    
    for r,row in ipairs(level) do
        for c,cell in ipairs(row) do
            if r == 10 then
                local grass,img
                grass = mesh()
                img = readImage("Documents:blockGrass")
                grass.texture = img
                grass:addRect(-16 + c*32,-16 + r*32,32,32)
                grass:draw()
            else
                local dirt,img
                dirt = mesh()
                img = readImage("Documents:blockDirt")
                dirt.texture = img
                dirt:addRect(-16 + c*32,-16 + r*32,32,32)
                dirt:draw()
            end
        end
    end
    
end

WORLD CREATE CLASS

worldCreate = class()

function worldCreate:init()
    -- you can accept and set parameters here
    height = 102
    width = 10
    level = {}
    index = {}
    
    for i = 1,width do
        level[i] = {}
        for j = 1,height do
            level[i][j] = math.random(6)
        end
    end
    
    for i = 1,width do
        index[i] = {}
        for j = 1,height do
            index[i][j] = math.random(6)
        end
    end

end

function worldCreate:draw()
    -- Codea does not automatically call this method
    for r,row in ipairs(index) do
        for c,cell in ipairs(row) do
            text(r.."/"..c, WIDTH - width*40 + c*35,HEIGHT - height*40 + r*35)
        end
    end
    
end
«1

Comments

  • SimeonSimeon Admin Mod
    edited August 2012 Posts: 5,417

    Sounds like the first thing you should aim for is to draw all your similar blocks (e.g. dirt) as one mesh. So you have a structure like:

    blockMeshes = {}
    
    blockMeshes["dirt"] = mesh()
    blockMeshes["dirt"]:addRect( ... )
    ...
    blockMeshes["dirt"]:draw() -- one draw for all dirt blocks
    

    Then you can take this even further and pack all your dirt, grass, stone and other textures into one image. Then you can use one mesh to render all your blocks. This would be the fastest solution.

    Edit: Also I would suggest constructing your meshes once, outside your draw function. Then modifying them as needed on interaction.

  • Posts: 791

    Have a look at this previous discussion which compares meshes and sprites for an example of what @Simeon is suggesting

    http://twolivesleft.com/Codea/Talk/discussion/1378/sprites-vs-meshes/p1

  • edited August 2012 Posts: 68

    Like this?
    (Didn't test the code, away from Codea atm)

    -- Mesh Atlas
    
    -- Use this function to perform your initial setup
    function setup()
        print("Hello World!")
        texmesh = mesh()
        
    end
    
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color 
        background(0)
    
        -- This sets the line thickness
        img = readImage("Documents:Minecraft Tileset")
        texmesh.texture = img
        texmesh.addRect(WIDTH/2,HEIGHT/2,32,32)
        texmesh:texCoord(img,12,12)
        texmesh:draw()
    
        -- Do your drawing here
        
    end
    
    
    
  • okay so I'm using Codea again and I feel like I'm really close to figuring it out. But I havn't. Here's what I think I'm supposed to be doing:

    dirtmesh = mesh()
    img = readImage("Documents:Minecraft Tileset")
    dirtmesh.texture = img
    idx = dirtmesh:addRect(WIDTH/2, HEIGHT/2, 32, 32)
    dirtmesh:setRectTex(idx,0,0,1,1)
    

    So the "0,0,1,1" gives me the entire tileset, whenever I change some of the digits (for example: "0, .480, .32, .32" I get the image zoomed up and stuff which is what I'm assuming you guys told me to do. make different submeshes that all use a super image filled with all the minecraft tiles I'll need.
    So my problem is that I have no idea what to put in the "setRectTex()" to make the mesh be on the appropriate image. Why doesn't it go by pixel coordinates? I don't think it does because I've put in "0 [for the left edge], 480 [for the bottom edge] and 32,32 [for the size that the tile is]" and I just got some weird tv static image but with random colors from my tileset O.O

    Please help me better understand so that I can put in the proper coordinates

  • edited August 2012 Posts: 791

    edited
    Was writing this while you posted the above. You are pretty much there!

    Couple of changes


    -- Mesh Atlas -- Use this function to perform your initial setup function setup()     texmesh = mesh()     img = readImage("Cargo Bot:Codea Icon")     texmesh.texture = img      end -- This function gets called once every frame function draw()     -- This sets a dark background color      background(0)     texmesh:clear()     -- This sets the line thickness       local idx = texmesh:addRect(WIDTH/2,HEIGHT/2,32,32)     texmesh:setRectTex(idx,0,0,1,1)             texmesh:draw()     -- Do your drawing here      end

    The important bit for selecting a subsection of your image is the line

        texmesh:setRectTex(idx,0,0,1,1)
    

    idx is the identifier for the rectangle you have just added to the mesh, the next two values 0,0 are the bottom left location of the portion of the image you want to add and the next two are the size of the portion of the image. These values are in proportion to the full image.

    For example

        texmesh:setRectTex(idx,0,0,0.5,1)
    

    Will display the left half of the image while

        texmesh:setRectTex(idx,0.5,0.5,0.5,0.5)
    

    Will display the top right hand quarter of the image.

    These will be scaled and stretched to fit the size used in addRect on the previous line.

  • SimeonSimeon Admin Mod
    edited August 2012 Posts: 5,417

    Okay so setRectTex() takes values from 0 to 1, where 0 is the first pixel on your axis, and 1 is the last.

    Say your Minecraft tileset image is 500x500 pixels. It's divided into a grid 100 individual tiles, each tile is 50x50 pixels. Your dirt tile is the first tile in the image, the one in the upper left corner.

    You can refer to it like this:

    idx = dirtmesh:addRect(WIDTH/2, HEIGHT/2, 32, 32)
    dirtmesh:setRectTex(idx, 0, 0, 50/500, 50/500)
    

    What is this saying? It's saying set the span of texture to use on the rect to go from (0,0) in your texture coordinate space, to (50/500, 50/500) — or (0.1, 0.1). Because 50 pixels across in a 500-pixel-wide texture is 10% (0.1) of the texture.

    If you wanted to refer to the second tile in your tileset texture, you could do it like this:

    idx = dirtmesh:addRect(WIDTH/2, HEIGHT/2, 32, 32)
    dirtmesh:setRectTex(idx, 50/500, 0, 50/500, 50/500)
    

    It's starting to look like a pattern. We can now write a generic function to index any of our 100 tiles in this hypothetical Minecraft tileset image:

    function setMeshTile( theMesh, rectIndex, img, tileX, tileY )
        -- We assume our tiles are 50x50 pixels square
        local tileSize = 50
    
        -- tileX and tileY are assumed to start at 1, 1 and go up to 10, 10
    
        theMesh:setRectTex( rectIndex, (tileX - 1) * (tileSize/img.width),
                                       (tileY - 1) * (tileSize/img.height),
                                       (tileSize/img.width),
                                       (tileSize/img.height) )
    end
    
  • okay so with you guys' help I've changed my code a bit to do what you showed me.

    -- Mesh Atlas
    
    -- Use this function to perform your initial setup
    function setup()
        // mts = Minecraft TileSet
        mts = {}
        
        mts["dirt"] = mesh()
        idx = mts["dirt"]:addRect(16,HEIGHT/2,32,32)
        
        mts["index"] = mesh()
        idi = mts["index"]:addRect(WIDTH/2,HEIGHT - 128,256,256)
        
        
        img = readImage("Documents:Minecraft Tileset")
        
    end
    
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color 
        background(0)
    
        -- This sets the line thickness
        noSmooth() --gives it the trademark blocky texture
        --VARIABLE
        mts["dirt"]:setRectTex(idx,3/16,15/16,32/512,32/512)
        mts["dirt"].texture = img
        mts["dirt"]:draw()
    
        -- Do your drawing here
        
    end
    

    I have it set to the grass and I just have to change the "3/16" to "2/16" because the dirt texture is the second image out of the 16 images in the first row.

    How exactly do I get my code to make dirt and grass rectangles all across the Width of the screen?

  • btw thanks you guys I appreciate it and hopefully once I'm started off I'll be able to do some of this on my own :)

  • Okay, can you guys give me an example of a touch function that works with tables?

    I'm not sure I'm explaining my request properly :\

    worldCreate = class()
    
    function worldCreate:init()
        -- you can accept and set parameters here
        wWidth = WIDTH/64
        wHeight = (HEIGHT/4)/32
        world = {}
        
        for r = 1, wWidth do
            world[r] = {}
            for c = 1,wHeight do
                world[r][c] = math.random(2)
            end
        end
    end
    
    function worldCreate:draw()
        -- Codea does not automatically call this method
        
        pushStyle()
        noStroke();noSmooth()
        for r,row in pairs(world) do
            for c,col in pairs(row) do
                if c == wHeight then
                    fill(0,255,0)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                elseif c < wHeight and c > wHeight/2 and col == 2 then
                    fill(175, 166, 147, 255)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                elseif c < wHeight/2 and c > 0 and col == 1 then
                    fill(125, 121, 114, 255)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                else
                    fill(148, 95, 25, 255)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                end
            end
        end
        popStyle()
    

    my v0.1 (without textures for now)

    How do I go about making a touch function to "destroy" one of the rectangles if you touch that specific one? On the ENDED touch state

  • Posts: 371

    I have written code for this, try =

    worldCreate = class()
    
    function worldCreate:init()
        -- you can accept and set parameters here
        wWidth = WIDTH/64
        wHeight = (HEIGHT/4)/32
        self.world = {}
        
        for r = 1, wWidth do
            self.world[r] = {}
            for c = 1,wHeight do
                self.world[r][c] = math.random(2)
            end
        end
    end
    
    function worldCreate:draw()
        -- Codea does not automatically call this method
        pushStyle()
        noStroke();noSmooth()
        for r,row in pairs(self.world) do
            for c, col in pairs(row) do
                if c == wHeight then
                    fill(0,255,0)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                elseif c < wHeight and c > wHeight/2 and col == 2 then
                    fill(175, 166, 147, 255)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                 elseif c < wHeight/2 and c > 0 and col == 1 then
                    fill(125, 121, 114, 255)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                else
                    fill(148, 95, 25, 255)
                    rect(-64 + (r*64),-64 + c*64,64,64)
                end
            end
        end
        popStyle()
    end
    
    function worldCreate:touched(touch)
        -- This is where the magic happens
        if touch.y < HEIGHT / 2 and touch.state == ENDED then
            print("Co-ordinates of your touch = ("..math.ceil(touch.x / 64)..", "..math.ceil(touch.y / 64)..")")
            self.world[math.ceil(touch.x / 64)][math.ceil(touch.y / 64)] = nil -- remove the entry from the table
        end
    end
    
    function setup()
        world = worldCreate()
    end
    
    function draw()
        background(0, 0, 0, 255) -- try remove this ;)
        world:draw()
    end
    
    function touched(touch)
        world:touched(touch)
    end
    
  • Posts: 791

    The following is untested as I don't have my iPad with me.

    You need a function to read in the screen position where you have touched, something along the lines of:

    if currentTouch.state==ENDED then
      lastx=currentTouch.x
      lasty=currentTouch.y
    end
    

    Then inside your second for loop (the one one iterating through the columns) check to see if the lastx and lasty values are within the rectangle being created, if they are then set world[r][c]=0 - this will make the rectangle appear as it does in the final "else" part (I assume that's what you mean by destroy)

    The if statement might look something like:

    if lastx>(r*64)-64 and lastx<r*64 and lasty>(c*64)-64 and lasty<(r*64) then
      world[r][c]=0
    end
    

    Another thread of interest might be this one, which uses sprites

    http://twolivesleft.com/Codea/Talk/discussion/comment/11214#Comment_11214

  • YEEEEESS! to @Jordan!!!!!! Whoo!

  • Posts: 371

    Glad to have helped! :D Feel free to use it (I have no licenses or policies or what-what, I'm only 13)

  • :[ Daaaaarn! I need help again. I swear I looked the code over and there shouldn't be a reason as to why it doesn't work when I combined what I learned with the meshes (which render fast enough, btw! Thanks to EVERYONE here). Here's my worldCreate() class

    worldCreate = class()
    
    function worldCreate:init()
        -- you can accept and set parameters here
        wWidth = WIDTH/32 + 2
        wHeight = HEIGHT/2/32
        world = {}
        id = {}
        blocks = {}
        img = readImage("Documents:Minecraft Tileset")
        blocks["grass"] = mesh()
        blocks["dirt"] = mesh()
    
        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
            for c,col in pairs(row) do
                if c == wHeight then
                    id[r] = blocks["grass"]:addRect(-64 + r*32,-32 + c*32,32,32)
                    blocks["grass"]:setRectTex(id[r], 3/16,15/16,32/512,32/512)
                    blocks["grass"].texture = img
                else
                    id[r] = blocks["dirt"]:addRect(-64 + r*32,-32 + c*32,32,32)
                    blocks["dirt"]:setRectTex(id[r],2/16,15/16,32/512,32/512)
                    blocks["dirt"].texture = img
                end
            end
        end
    end
    
    function worldCreate:draw()
        -- Codea does not automatically call this method
        blocks["grass"]:draw()
        blocks["dirt"]:draw()
    end
    
    function worldCreate:touched(touch)
        -- Codea does not automatically call this method
        if touch.state == ENDED then
            world[math.ceil(touch.x/32)][math.ceil(touch.y/32)] = nil
        end
    end
    
  • Posts: 371

    Hey @RichGala1, I'm assuming you have functions setup(), draw(), and touched() somewhere else, right? And this would be much easier if you posted a link to your "minecraft tileset"

  • Yes to both those things. I'm gonna see where I'll put the tileset real quick

  • edited August 2012 Posts: 791

    As @Jordan said have you instantiated your class? Something like this in your main class

    function setup()
        myW=worldCreate()
    end
    
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color 
        background(40, 40, 50)
    
        -- Do your drawing here
        myW:draw()
    end
    
    
  • edited August 2012 Posts: 68

    Yeah don't worry I'm not tht noob anymore :)
    I put the pic on my twitter. Here's the link:

    pic.twitter.com/55gRt1rj

    Everything shows up but I guess the problem is that the "rect()" function was directly connected to my table so it would easily erase with "nil" But my the mesh only needs to set up it's rectangles and texture stuff once and it's good to go.
    "Nil" won't get rid of it because it may take it away the rectangle setup from the table but I don't want to get rid of the setup but that actual part of the mesh.

    I suck at explaining myself > <

  • Changed the code a little. Other than adding new blocks at certain heights and making the framerate go up it isn't any much different.

    worldCreate = class()
    
    function worldCreate:init()
        -- you can accept and set parameters here
        wWidth = WIDTH/32 + 2
        wHeight = HEIGHT/2/32
        world = {}
        id = {}
        blocks = {}
        img = readImage("Documents:Minecraft Tileset")
        blocks["grass"] = mesh()
        blocks["dirt"] = mesh()
        blocks["stone"] = mesh()
    
        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
            for c,col in pairs(row) do
                if c == wHeight then
                    id[r] = blocks["grass"]:addRect(-64 + r*32,-32 + c*32,32,32)
                    blocks["grass"]:setRectTex(id[r], 3/16,15/16,32/512,32/512)
                    blocks["grass"].texture = img
                elseif c < (wHeight - 2) and c >= 7 and col > 5 then
                    id[r] = blocks["stone"]:addRect(-64 + r*32,-32 + c*32,32,32)
                    blocks["stone"]:setRectTex(id[r], 6/16,15/16,32/512,32/512)
                    blocks["stone"].texture = img
                else
                    id[r] = blocks["dirt"]:addRect(-64 + r*32,-32 + c*32,32,32)
                    blocks["dirt"]:setRectTex(id[r],2/16,15/16,32/512,32/512)
                    blocks["dirt"].texture = img
                end
            end
        end
    end
    
    function worldCreate:draw()
        -- Codea does not automatically call this method
        blocks["grass"]:draw()
        blocks["dirt"]:draw()
        blocks["stone"]:draw()
    end
    
    function worldCreate:touched(touch)
        -- Codea does not automatically call this method
        if touch.state == ENDED then
            world[math.ceil(touch.x/32)][math.ceil(touch.y/32)] = nil
        end
    end
    
    

    and so you don't worry :)

    -- 2DMC Mechanics
    
    -- Use this function to perform your initial setup
    function setup()
        displayMode(FULLSCREEN)
        worldCreate:init()
        time = 0
        fc = 0
    end
    
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color 
        background(152, 213, 223, 225)
        fc = fc + 1
        time = time + DeltaTime
        text(math.floor(fc/time+ 0.5),WIDTH/2,HEIGHT - 50)
    
        worldCreate:draw()
    end
    
    function touched(touch)
        worldCreate:touched(touch)
    end
    
  • edited August 2012 Posts: 371

    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

  • Posts: 371

    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!

  • Posts: 371

    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!

  • Posts: 2,161

    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)

  • Posts: 2,161

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

  • Posts: 371

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

  • Posts: 2,161

    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.

  • Posts: 371

    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?

  • Posts: 2,161

    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!

  • Posts: 371

    Buttons, lots and lots of buttons. ;-) 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 :P
    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 :)

  • edited August 2012 Posts: 68

    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

  • Posts: 371

    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 :)

  • 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!

  • Posts: 371

    Code please? :)

  • edited August 2012 Posts: 68

    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

  • Posts: 371

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

  • edited August 2012 Posts: 68

    thanks

  • Posts: 371

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

  • lmao if you had constantly refreshed your page you would've seen me stupidly trying to figure out how to work it, lol. I got it now ^ ^

  • Posts: 371

    Soooo, where are you going to go from here? layers? 3D? movement?

  • edited August 2012 Posts: 68

    I need help again :\
    This time with my character and how to detect if he should fall or not
    I've tried making a way to have the game check if there's a block underneath the self.y of the character and if it's nil, to change the self.floor to the top of the block that's underneath.
    This seems to be much easier to detect if you use sprites but, yeah...

    if self.y - 32 > self.floor then
        self.y = self.y - self.vel
    end
    
  • Posts: 371

    You could try using the physics engine... But that would make EVERYTHING physics-y. (All the blocks...)

  • Well, @Jordan your pretty smart, so in your opinion would the game work better or make more sense of I used physics?

  • Posts: 371

    Just thinking about it, you could use fixed EDGEs on the top of every block, and it wouldn't mess with the gameplay. I will try and write something up for you (BUT YOU TRY AND BEAT ME)
    P.S. Character? Hmmm... Any code for my prying eyes?
    P.P.S. That applies to @Andrew_Stacey too ;)

  • Lol, he's just a bunch of meshes put together to resemble the minecraft character for now :)
    He's only colors. Lol, he's under the class, "Joe"

  • Posts: 371

    (@RichGala1, are you jailbroken? If not, I have a little surprise for you)
    Still, I kinda want to see you code, so I can modify it, and you don't have to modify mine.

  • If I am then I don't get a surprise?

  • Posts: 371

    If you are, do you own minecraft pocket edition? And here is another little surprise for you...


    --# Main -- MineCraft by Jordan Arenstein function setup() world = worldCreate() ellipseMode(RADIUS) end function draw() background(0, 0, 0, 255) world:draw() end function touched(touch) world:touched(touch) end --# worldCreate worldCreate = class() function worldCreate:init() -- you can accept and set parameters here wWidth = WIDTH/32 wHeight = HEIGHT/2/32 local world = {} local id = {} local bid = {} local bodies = {} self.player = physics.body(CIRCLE, 25) self.player.position = vec2(WIDTH / 2, HEIGHT / 4 * 3) --blocks = {} img = readImage("Documents:Minecraft Tileset") --blocks["grass"] = mesh() --blocks["dirt"] = mesh() --blocks["stone"] = mesh() -- CHANGED IT ALL TO ONE MESH!!! self.blocks = mesh() self.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] = {} bid[r] = {} bodies[r] = {} for c,col in pairs(row) do id[r][c] = self.blocks:addRect(-16 + r*32,-16 + c*32,32,32) bodies[r][c] = physics.body(EDGE, vec2((r - 1) * 32, c * 32), vec2(r * 32, c * 32)) bodies[r][c].restitution = .5 if c == wHeight then self.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 self.blocks:setRectTex(id[r][c], 1/16,15/16,32/512,32/512) bid[r][c] = 2 else self.blocks:setRectTex(id[r][c],2/16,15/16,32/512,32/512) bid[r][c] = 3 end end end self.world = world self.id = id self.bid = bid self.bodies = bodies end function worldCreate:draw() -- Codea does not automatically call this method self.blocks:draw() fill(255, 246, 0, 255) ellipse(self.player.position.x, self.player.position.y, 25) end function worldCreate:touched(touch) -- Codea does not automatically call this method if touch.state == ENDED and touch.y < HEIGHT / 2 then self.blocks:setRect(self.id[math.ceil(touch.x/32)][math.ceil(touch.y/32)], 0, 0, 0, 0) self.bodies[math.ceil(touch.x/32)][math.ceil(touch.y/32)]:destroy() end self.player:applyForce(vec2(touch.x, touch.y) - self.player.position) end
  • I am jailbroken and I do own MCPE. I'm using their tiles :P (cheater)
    Ooh! Code! Checking it now :)

Sign In or Register to comment.