Another fine mesh I've got myself into...

Okay so I’ve been looking at meshes at a beginner level of course and written the following which works fine

-- Basemesh

function setup()
displayMode(FULLSCREEN)
   l=5 --alter this to change resolution of mesh can handle upto about 1000+ before crashing
   meshdata={}
   basemesh=mesh()
    for i=1,l do
    for y=1,l do
        posx=(i*HEIGHT/l)-HEIGHT/(2*l)
        posy=(y*HEIGHT/l)-HEIGHT/(2*l)
    basemesh:addRect(posx,posy,HEIGHT/l,HEIGHT/l)
    end
    end
    for z=1,l^2 do
        colconv=z*255/l^2
    basemesh:setRectColor(z,255-colconv,colconv,255-colconv) --remove the 255-s for grey scale
    end
end
function draw()
    basemesh:draw()
end

So obviously it produces a square mesh of composite squares and you could if you wish set the dimensions using l and with l=height then in landscape mode you have a square which fits on the screen and a mesh which in theory should be composed of pixel sized rectangular meshes. Each square module has been individually coloured with a slightly different colour using a loop.

Okay so the aim of this is to plug this into a tiling program…I wrote some code for the tiling program and it worked well but an alternative much more elegant code was suggested by @dave1707 so I’ve embedded the above into that (anyone who has had the misfortune of trying to help me previously may have uploaded 512 images into their documents folder -apologies again)…the following code which includes the embedded code above does not do this but stores them in a table.

function setup()
    
   displayMode(FULLSCREEN)
   l=10                                                 --alter this to change resolution of mesh
   meshdata={}                                          --create meshdata as table                           
   basemesh=mesh()                                      --create basemesh as a mesh
    for i=1,l do 
        meshdata[i]={}                                       
    for y=1,l do                                        --double iteration which sets up               
        meshdata[i][y]=0                                --meshdata as a 2 way table
        posx=(i*HEIGHT/l)-HEIGHT/(2*l)                  --generates a central x coord
        posy=(y*HEIGHT/l)-HEIGHT/(2*l)                  --and a central y coord
                                                        --for a grid of square mesh pieces
       
        idx = basemesh:addRect(posx,posy,HEIGHT/l,HEIGHT/l) 
                                   --inserts all rectangle meshes into basemesh and returns id
    posx=math.ceil(posx/HEIGHT*l)  --these two lines convert the x,y coordinate into a horizontal
    posy=math.ceil(posy/HEIGHT*l)  --and vertical address for each mesh tile, which along with 
    meshdata[posx][posy]=idx       --its idx is written into the table meshdata
--  print(posx, posy, idx)         --this is a check that the meshdata table has been correctly made 
    end
    end
    for z=1,l^2 do                 --this loop sets up colours for each mesh piece in the basemesh
        colconv=z*255/l^2
    basemesh:setRectColor(z,colconv,colconv,colconv)   
    end
    tab={}                         --the following generates 512 tiles based on permutations
    rectMode(CORNER)               --of a binary coded 3x3 matrix....
    spriteMode(CORNER)
    base=readImage("Documents:newtile")
    shady=readImage("Documents:newshade")
    dy=0
    z=0
end

function draw()
    background(40, 40, 50)
    fill(255)
    if z<512 then
        tab[z]=image(123,123)
        setContext(tab[z])
        sprite(base,0,0,123,123)
        bin(z)
        setContext()
        text("creating image  "..z,WIDTH/2,HEIGHT/2)
        z=z+1
    else                                --here all tiles have now been generated and stored
                                          --using the bin function below
        text("Slide to change",WIDTH/2+400,HEIGHT/2+200)
        yy=math.floor(dy/10)
        text("image "..yy,WIDTH/2+400,HEIGHT/2+100)
        sprite(tab[yy],WIDTH/2+340,HEIGHT/2-61)
        basemesh:draw()                    --here the base mesh is being drawn
    end        
end

function bin(z)
    x,y=0,-1
    for a=8,0,-1 do
        y=y+1
        if y>2 then
            y=0
            x=x+1
        end
        if z>=2^a then
            z=z-2^a
            sprite(shady,y*41,x*41,41,41)
        end
    end
end

function touched(t)
    if t.x>=HEIGHT and t.state==MOVING then --this detects swiping in the r.h.s of the screen
        dy=dy+t.deltaY
        if dy>#tab*10 then
            dy=#tab*10
        elseif dy<0 then
            dy=0
        end
        end
    if t.x<=HEIGHT and t.tapCount==2 then do --this detects a double tap on the mesh
        tileselect(t)
    end
end
end

function tileselect(t)
    xsel=math.ceil(t.x/HEIGHT*l) --these two lines convert the touch coordinates
    ysel=math.ceil(t.y/HEIGHT*l) --into the horizontal and vertical address system 
                                 --tabulated in meshdata so that I can match the mesh piece
                                 --selected with its identity with the aim of using the selected
                                 --tile image on the r.h.s. as a texture map to the selected mesh           
                                 --section
                               
    basemesh.texture = tab[yy]   --this selects the current generated tile as a texture map for
                                 --the selected mesh
--  print(meshdata[xsel][ysel])  --this checks that the touch has been converted correctly
    basemesh:setRectTex(meshdata[xsel][ysel],0,0,1,1)
    end
    
    --the penultimate line is supposed to map the texture to the specific tile selected but all tiles are affected...Help!

Much gratitude for any assistance or pointers. My naive thinking was that since I can individually colour each mesh section, then I should be able to individually specify a texture map to each mesh section, and indeed my interpretation of the literature seemed to suggest that one could…I changed the 0,0,1,1 into 0,0,1/l,1/l as an experiment which had a bizarre effect but did start affecting things individually…but…hmmm. Any thought gratefully accepted.

Code above corrupted by if statement, now removed and working,…

@TheAbstractMan Can you explain more. Is the mesh supposed to be the little squares (shady), or is it the large square (base) tile. Not sure what the final result is supposed to be.

@TheAbstractMan Sorry, I didn’t read the comments in your code. I didn’t realize double tapping on the mesh area changed the mesh based on what was displayed in the small tile area.

Hi @dave1707. If you run it with some dummy images, then you’ll have the familiar tile on the right hand side of the screen and a set of almost grey scale squares which form a larger square of the left hand side of the screen. All the grey scale squares are rectangular meshes which have been placed into the larger encompassing mesh defined at the beginning as “basemesh”. So with the code given, there should be a 10x10 array of grey shaded squares which make up basemesh. The aim is to double tap any of the greyscale squares and for the exhibited tile on the r.h.s of the screen to be inserted as a texture map onto just the double tapped selected greyscale square.(if for example the selection of “tile” images on the right hand side where of some grass, some woods and some sand then I would be able to place any of these three in any of the greyscale squares, to build up a map) The overall aim of this is basically to use this as a map drawing facility to design dungeon maps using the tiles generated. Hope that makes sense…remember all the tiles that have been generated are just 3x3 grids with some or all or none of the squares shaded in.

@TheAbstractMan That makes more sense.

@TheAbstractMan I used my original code and added meshes to that. Is this like what you were after. Select an image then double tap one of the circles. I was in a hurry, and there isn’t very much error checking, so it could crash if something is selected wrong.


displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT_ANY)

function setup()
    rectMode(CORNER)
    spriteMode(CORNER)
    meshTab={}
    for x=1,10 do
        for y=1,10 do
            m=mesh()
            m:addRect(x*60,y*60,60,60)
            m.texture="SpaceCute:Collision Circle"
            table.insert(meshTab,m)
        end
    end
    tab={}
    base=readImage("SpaceCute:Background")
    shady=readImage("SpaceCute:Icon")
    dy=0
    z=0
end

function draw()
    background(40, 40, 50)
    fill(255)
    if z<512 then
        tab[z]=image(123,123)
        setContext(tab[z])
        sprite(base,0,0,123,123)
        bin(z)
        setContext()
        text("creating image  "..z,WIDTH/2,HEIGHT/2)
        z=z+1
    else
        text("Slide finger up or down to show different image",WIDTH/2,HEIGHT-250)
        text("Double tap on a circle to select that image",WIDTH/2,HEIGHT-300)
        yy=math.floor(dy/10)
        text("image "..yy,WIDTH/2+120,HEIGHT-120)
        sprite(tab[yy],WIDTH/2-61,HEIGHT-200)
        for z=1,#meshTab do
            meshTab[z]:draw()
        end
   end        
end

function bin(z)
    x,y=0,-1
    for a=8,0,-1 do
        y=y+1
        if y>2 then
            y=0
            x=x+1
        end
        if z>=2^a then
            z=z-2^a
            sprite(shady,y*41,x*41,41,41)
        end
    end
end

function touched(t)
    if t.state==MOVING then
        dy=dy+t.deltaY
        if dy>#tab*10 then
            dy=#tab*10
        elseif dy<0 then
            dy=0
        end
    end
    if t.state==BEGAN and t.tapCount==2 then
        x=math.floor((t.x-30)/60)
        y=math.ceil((t.y-30)/60)
        if x<=10 and y<=10 then
            xy=x*10+y
            meshTab[xy].texture=tab[yy]
        end
    end       
end

I like the simplicity of the slide to change image but the useability of it is not ideal. I understand it is a test but a sepeate grid say 2x10 on the right side and a two touch slide to bring it and then a tap to select a tile. Not much mork to implement, but if you are going to be making maps scrolling through 512 image is not ideal or productive. Still, it’s cool :slight_smile:

Yeah…that’s exactly it @dave1707. I’m just reading through the code as I’m typing this. It appears that you’ve opted to use a table as a storage structure for individual mesh rectangles, which instantly cuts out the problem I was having. I on the other hand was attempting to use the overall basemesh itself as the storage structure. My thinking was that any manipulation of the overall image of the basemesh could then be done with a single command…but there’s nothing stopping me from inserting all of those individual meshes stored in the table into one single overarching mesh is there, once they’ve had their textures mapped… so exactly the same aim can be achieved…(sorry…thinking out aloud…)…yeah, brilliant, once again a simple elegant solution to a twisted sorry knot of thinking!

The question still remains though, if you do have a constructed mesh can you alter texture mapping for individual components without having to find a way of splitting the contructed mesh back up or rebuilding it from scratch. I just assumed that you could because of the identity element returned for each mesh component added and the presence of the identity arg in the mesh.setRectTex command…the reason I’m thinking about this is that
1: I keep reading that the manipulation of meshes speeds everything up.
2: you can make meshes the size of an individual pixel
3: you can put individual meshes together meaning that you can in effect create an equivalent of a sprite but it can be of any shape, size, have holes in it etc. not just limited to rectangles
4: by texture mapping…or just by colouring I suppose …and recolouring/mapping you then have the facility to create very nice, complex animations by applying for want of a better phrase “transition tables” to the mesh in question and if 1 is true then the speed should be good…

It’s probably a cart before horse way of thinking about things and I need to go and read up on animations & Tweens etc which will probably turn out to be the same thing… but always like to think about what can be done with what can be done…unfortunately I still can’t do! Slowly crawling there though…

This one should go before the last…don’t know why it didn’t send

Completely agree. @Thwapp That’s the next step. I’m just taking everything one step at a time as I’m a total beginner. I do have a fully designed end point in mind but trying to learn stuff as I go along. I was thinking of the scrolling tiles thing, and then also thinking if you could use “scale” and “z levels” to make the selected tile ‘raised’ and ‘enlarged’ so to speak as you scroll through…but as I said I’m just looking to proceed step by step.
Just out of bed so will check through the code @dave1707. As always many thanks for invaluable advice.

I have learned a few things while making a tile map. Get the drawing order down early. It could be a z index you sort, or just drop items into a tables (background, players,fx,interface…) and then draw in the order you want. Create a block class for the tiles so you can use values used in the game. for example:
block.pos(x,y)
block.id
block.isActive
block.isSelectable
block.giveDamage
Just psuedo code but you get the idea.

Thanks @Thwapp, I’m just starting to look at classes, need to do a bit more reading on the theory of them as I’m not entirely sure how to use them conceptually. I get the impression that it’s a whole series of user defined functions which specifically operate on and keep track of a type of abstract object…here it would be the tiles and all of their associated data…which you would be calling a “block” is that correct?

Having attempted the tile generation and mapping interface (and falling flat on my face several times)…it’s been an interesting learning curve. I think what you were saying about the functionality/useability of it is correct, and even with additional tiles on display, it’s not ideal. So I’m going to rewrite it with what I’ve learnt and kindly been shown by others to make it more functional. I think it will be easier just with individual cells. The reason I was using 3x3 tiles was I was thinking about having them rotate at various instances and change the game environment but I think it’s possible to do that anyway…

The thing I have to keep reminding myself with is the mantra “the image is the interface” I don’t feel I’ve sufficiently embraced touch screen technology on a conceptual level because it’s how you think about something which determines how you act and implement things. A typical example is the above code that @dave1707 wrote which just shows how simple something can be if you think about it it the correct manner…

Rule #1. There are no wrong solutions while learning, just refactoring. If you are going to use pathfiding (down the road) then the cell/grid should be the smallest walkable area and a 3x3 cell would complicate things. Better to make the grid smaller.

Here is an good example of classes by @Ignatz.
http://coolcodea.wordpress.com/2013/06/14/84-a-practical-example-showing-the-value-of-classes/

His entire site is awesome.

Many thanks, will study…

Here is the start for creating many dragable objects. It is from a card game game prototyping I am starting. It’s not grid based but it’s a a good example of creating and selecting meshes with touch controls.

-- Use this function to perform your initial setup
function setup()
    --displayMode( FULLSCREEN )

gameState = 0
loadingScreen = 1
initGraphics = 2
loadCharacters = 3
createCharacter = 4

    --buttonframe = frame(865, 50, WIDTH - 5, HEIGHT - 55)
    buttons = {}
   img1 = readImage("SpaceCute:Star")
  -- buttons[#buttons + 1] = Button(100, 500, 100, 100, img1, menu)
  --  buttons[#buttons + 1] = Button(100, 200, 100, 100, img1, menu)
 cards = {}
    img2 = readImage("Planet Cute:Heart")
    for i=1,151 do
cards[#cards+1] = Card(i,math.random(600),math.random(500),50,50,img2,1,processCardTouch,"one")
end
   -- t=Tasks
--    t:add(p,{"remove",math.random(100)},1)
    --t:add(p,{"2","wait 12 sec"},12)
   -- t:add(p,{"3","wait 36"},36)
end

function p(t)
    
    
  --  print(t[1],t[2])
end

function draw()
    --t:draw()
    background(40, 40, 50) 
    -- draw buttons
    for i=1,#buttons do
        buttons[i]:draw()
    end
    --draw cards
    for i=1,#cards do
        cards[i]:draw()
    end
    -- draw cards
end


function menu()
    print("you touched menu")
end

function processCardTouch(touch,card)
        --cards[#cards+1] = Card(2,300,75,300,220,img2,1,processCardTouch)
        output.clear()
        print("you touched a card ")
        print("From Touch id "..card.id)
end
function cardDrag ()
    print("you touched cardDrag")
end
function touched(touch)
    sound(SOUND_HIT, 33733)
    for i=1,#buttons do
        buttons[i]:touched(touch)
    end
    for i=1,#cards do
      -- print("loop "..cards[i].id)
        cards[i]:touched(touch,cards[i])
    end
end
Card = class()

function Card:init(id,x,y,width,height,cardImage,activeState,callbackFunction,name)
    self.name = name
    self.id = id
        -- you can accept and set parameters here
 -- you can accept and set parameters here
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.mesh = mesh()
    self.mesh.texture = cardImage
    self.textureCordsList = {}
    self.mesh:addRect(x,y,width,height)
    self.mesh:setRectTex(id,0,0,1,1)
    self.buttonCorner1 = vec2(x-width/2,y-height/2)
    self.buttonCorner2 = vec2(x+width/2, y+height/2)
    self.callbackFunction = callbackFunction
end

function Card:draw()
    self.mesh:draw()
   -- print("xxx")
    -- Codea does not automatically call this method
end
function Card:setCardTexture(pos,width,height)
    -- this function will change the texture of the card.
    -- a list of texture cordinates 
    -- each cordinate will define the location on the texture image
    -- a timer could be set to animate the x,y,width,height
    self.x = pos.x
    self.y = pos.y
    self.width = width
    self.height = height
    self.mesh:setRect(1,x,y,width,height)
end
function Card:touched(touch,card)
    --selectedId = 0
    if touch.state == BEGAN then
        
        if touch.x >= self.buttonCorner1.x and touch.x <= self.buttonCorner2.x and touch.y >= self.buttonCorner1.y and touch.y <= self.buttonCorner2.y then
    output.clear()
    
    --print("Card.id= "..card.id)
    selectedId=self.id
    --print("selectedId= "..selectedId)
    --print("begin x"..self.x.." begin y"..self.y)

        selectedId = self.id
        --self.callbackFunction(card,touch)
    --    background(100, 120, 160)
        end
    elseif touch.state == MOVING then
        --self.callbackFunction(card)
       -- print("selectedId= "..selectedId.." self.id "..self.id)
        if self.id == selectedId then
            --print("moving")

            self.x = self.x +  touch.deltaX
            self.y = self.y +  touch.deltaY
            self.mesh:setRect(1,self.x,self.y,self.width,self.height)
        end    
    elseif touch.state == ENDED then
        --if card.id == selectedId then
        --self.x = self.x +  touch.deltaX
        --self.y = self.y +  touch.deltaY
        self.buttonCorner1 = vec2(self.x-self.width/2,self.y-self.height/2)
    self.buttonCorner2 = vec2(self.x+self.width/2, self.y+self.height/2)
      --  self.mesh:setRect(1,self.x,self.y,self.width,self.height)
        selectedId = 0
        --end
    end
end

@Thwapp - I wrote a card game class some time back, if you are interested. You can get all the images for the suits from the Emoji fonts.

Thanks, @Thwapp, that mesh/touch code will help me in my project!

@Ignatz I saw that earlier. I am not making traditioal card game with suites. I am trying to replicate the Pathfinder Adventure Card Game. I will start a seperate theread so not to hijack this one. Along the way I am getting a better grip on capturing touches on meshes, dragging meshes and AABB hit test with box2D, building and managing decks with many attribures to check.

@time_trial. I hope it helps.

Hi @Thwapp, forgive me if this turns out not to make sense. I’m still trying to wrap my head around classes…I’m looking at your code above and trying to ‘read’ it…and if you don’t have time to respond to this please ignore…no offense will be taken.

I’ll list what I think is happening along with any questions…
Your initial loop defines 151 entries in a table…but the entries are function calls for ‘card’, each with a unique set of parameters. By doing this, is the function actually called? (I’m assuming it is…and if it is, is anything actually returned to the table?)

As each instance of the function card is called, I recognise that card is being used as a class, so when it is called, we jump to card:init which then takes the parameters sent from the loop and is it this ‘init’ which forms the individual ‘object’ or instance from the parameters sent?..the object being the collected listed attributes linked to ‘self’, the particular instance of the object?

So the outcome is to create 151 unique card objects each of which can be processed through a variety of user defined functions if called upon?

Is that about right?

See post: http://twolivesleft.com/Codea/Talk/discussion/4493/my-first-try-at-object-overlap-detection#Item_1

Not sure what I was thinking, cleaner code in this thread