Sprite Sheet help

@dave1707 I wanted to add a vec4 for movement just for the sake of learning and because I couldn’t figure it out. I’m going to use your way though, especially now since I know how to add backgrounds with the table. The visual helped me comprehend. Thanks!

@dave1707 I thought I knew what you meant but after a couple of hours of trail and error I realized I don’t. Can I get a example in code of inserting different sections in the ground or a link to help me understand. All I’m getting is the background image in all directions endlessly.

Slide your finger to move the ground around.

displayMode(FULLSCREEN)

function setup()
    tab={   asset.builtin.Blocks.Grass_Top,     -- 1 thru 6
            asset.builtin.Blocks.Stone_Coal_Alt,    -- 7
            asset.builtin.Blocks.Sand,              -- 8
            asset.builtin.Blocks.Stone_Diamond_Alt, -- 9
            asset.builtin.Blocks.Mushroom_Red,      -- 10
            asset.builtin.Blocks.Wheat_Stage4,      -- 11
            asset.builtin.Blocks.Fence_Stone,       -- 12
            asset.builtin.Blocks.Water }            -- 13
    bTab={}
    for x=-20,20 do
        for y=-20,20 do
            table.insert(bTab,{x=x,y=y,v=math.random(13)})
        end       
    end
    dx,dy=WIDTH/2,HEIGHT/2
end

function draw()
    background(0)
    s=130
    for a,b in pairs(bTab) do
        if b.v<7 then
            sprite(tab[1],b.x*s+dx,b.y*s+dy)        -- 1 thru 6
        else
            sprite(tab[b.v-5],b.x*s+dx,b.y*s+dy)    -- 7 thru 13
        end
    end
end

function touched(t)
    if t.state==MOVING then
        dx=dx+t.deltaX
        dy=dy+t.deltaY
    end
end

@dave1707 Thanks btw I figured out how to move all directions using vec4.
Correct if I’m wrong but to my understanding your way moves the ground corresponding to the sprite sheet image.
I believe this way moves the spritesheet image via x y coordinates.

displayMode(FULLSCREEN)

function setup()
    img=readImage(asset.documents.Dropbox["Photo Apr 10, 8 24 31 PM.png"])

    rectMode(CENTER)
    x=WIDTH/2
    y=100
    dir=1
    i=1
    bTab={}
    table.insert(bTab,button(x-50,y+50,17))
    table.insert(bTab,button(x,y+50,9))
    table.insert(bTab,button(x+50,y+50,1))
    table.insert(bTab,button(x-50,y,33))
    table.insert(bTab,button(x+50,y,25))
    table.insert(bTab,button(x-50,y-50,57))
    table.insert(bTab,button(x,y-50,49))
    table.insert(bTab,button(x+50,y-50,41))
    delay=0
    iw=img.width
    ih=img.height
    sizeX=iw
    sizeY=ih    
    spriteMode(CORNER)
    img1=image(iw,ih)    
    setContext(img1)
    background(255)
    sprite(img,0,0)
    setContext()   
    wide=8
    high=8 
    extract()
    xs=0
    ys=0
    b1=vec4(WIDTH/2-50,100,50,50) --left
    b2=vec4(WIDTH/2+50,100,50,50) --right
    b3=vec4(WIDTH/2,150,50,50) --top
    b4=vec4(WIDTH/2,50,50,50) -- bottom
    b5=vec4(WIDTH/2-50,150,50,50) --top left
    b6=vec4(WIDTH/2+50,150,50,50) -- top right
    b7=vec4(WIDTH/2-50,50,50,50) -- bottom left
    b8=vec4(WIDTH/2+50,50,50,50) -- bottom right
  
end

function extract()
    tab={}
    dx,dy=WIDTH/2,HEIGHT/2
    stepX=iw//wide
    stepY=ih//high
    sizeY=stepY*high
    sizeX=stepX*wide
    for y=1,sizeY,stepY do
    for x=1,sizeX,stepX do
            table.insert(tab,img1:copy(x,y,stepX,stepY))
        end
    end
end

function draw()
    background(255)
    for a,b in pairs(bTab) do
        b:draw()
    end
    if #tab>0 then
        delay=delay+1   
        if delay>15 then
            delay=1
            i=i+1
            if i>dir+7 then
                i=dir
            end
        end
        
         --sprite position and scale size
        sprite(tab[i],dx-50,dy,100)
        dx=dx+xs
        dy=dy+ys
     
    pushStyle()   
    fill(255, 0, 0)
    rect(b1.x,b1.y,b1.z,b1.w)   -- button 1 left
    rect(b2.x,b2.y,b2.z,b2.w)   -- button 2 right
    rect(b3.x,b3.y,b3.z,b3.w)   -- button 3 top
    rect(b4.x,b4.y,b4.z,b4.w)   -- button 4 bottom
    rect(b5.x,b5.y,b5.z,b5.w)
    rect(b6.x,b6.y,b6.z,b6.w)
    rect(b7.x,b7.y,b7.z,b7.w)
    rect(b8.x,b8.y,b8.z,b8.w)   
    popStyle()    
        
    pushStyle()
    fill(248)
    fontSize(15)
    text("Left",b1.x,b1.y)
    text("Right",b2.x,b2.y)
    text("Top",b3.x,b3.y)
    text("Bottom",b4.x,b4.y)
    text("TL",b5.x,b5.y)
    text("TR",b6.x,b6.y)
    text("BL",b7.x,b7.y)
    text("BR",b8.x,b8.y)
    popStyle()       
    end
end

--touch controls,directions
function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        xs=0
    if t.x>b1.x-b1.z/2 and t.x<b1.x+b1.z/2 and
            t.y>b1.y-b1.w/2 and t.y<b1.y+b1.z/2 then
                xs=-2.2
        end
    if t.x>b2.x-b2.z/2 and t.x<b2.x+b2.z/2 and
            t.y>b2.y-b2.w/2 and t.y<b2.y+b1.z/2 then
                xs=2.2
        end
    if t.x>b3.x-b3.z/2 and t.x<b3.x+b3.z/2 and
            t.y>b3.y-b3.w/2 and t.y<b3.y+b1.z/2 then
                ys=2.2
        end
    if t.x>b4.x-b4.z/2 and t.x<b4.x+b4.z/2 and
            t.y>b4.y-b4.w/2 and t.y<b4.y+b1.z/2 then
                ys=-2.2
        end
        if t.x>b5.x-b5.z/2 and t.x<b5.x+b5.z/2 and
            t.y>b5.y-b5.w/2 and t.y<b5.y+b1.z/2 then
                ys=2.2
                xs=-2.2
        end
    if t.x>b6.x-b6.z/2 and t.x<b6.x+b6.z/2 and
            t.y>b6.y-b6.w/2 and t.y<b6.y+b1.z/2 then
                ys=2.2
                xs=2.2
            end
    if t.x>b7.x-b7.z/2 and t.x<b7.x+b7.z/2 and
            t.y>b7.y-b7.w/2 and t.y<b7.y+b1.z/2 then
                ys=-2.2
                xs=-2.2
            end
    if t.x>b8.x-b8.z/2 and t.x<b8.x+b8.z/2 and
            t.y>b8.y-b8.w/2 and t.y<b8.y+b1.z/2 then
                ys=-2.2
                xs=2.2
            end
        
    for a,b in pairs(bTab) do
            b:touched(t)
        end
    end
    if t.state==ENDED then
        xs=0
        ys=0
    end
end

--class for dpad
button=class()

function button:init(x,y,d)
    self.x=x
    self.y=y
    self.dir=d
end

--drawing pad
function button:draw()
    rect(self.x,self.y,50,50)
end

--touch for dpad
function button:touched(t)
    if t.x>self.x-25 and t.x<self.x+25 and t.y>self.y-25 and t.y<self.y+25 then
        dir=self.dir
        i=dir
    end
    end

@Jarc What are you going to do when the sprite person walks off the edge of the screen. Your vec4 works, but look at the size of your touched routine. The purpose of a class is to cut down on the code for multiple items. Using a class, you make changes to the code for 1 button (which is all buttons), in your code you’ll have to make changes for 8 buttons. As you code more and use classes, you see the advantages of using them. It took me a long time before I understood how classes worked and why they should be used.

PS. By moving the ground, the ground can be a lot larger than the screen size. In the background example above, as you scroll the background around, you’ll see that it’s a lot larger than the screen.

@dave1707 Way to shoot me down Dave, just kidding I see your point. Thanks for the insight you’re right.

@Jarc I didn’t mean anything by what I said, just trying to point out things. By moving the character, you’re kind of limited by the screen size unless you add a lot of code when the character reaches the screen edge. By keeping the character in the middle and moving the background, the background can be any size. You can constantly create more background off screen as the character moves. As for vec4’s, it’s good to learn and try new things. One thing you’ll find that you use a lot are tables and classes. You can skip using them, but you’ll be writing a lot more code and it will be more complicated. Like I said above, it took me a long time before I understood classes. I didn’t know why they were used and I didn’t have anyone to explain well enough their use. Or maybe I was told enough, but I just didn’t understand. Just keep trying new things and asking questions.

@dave1707 how do I tie a dynamic collider to the sprite animation so whenever I move any direction it stays on him.

2nd question, how do I set up a static collider so he can’t walk through walls and can interact with objects.

displayMode(FULLSCREEN)

function setup()
    img=readImage(asset.documents.Dropbox["Photo Apr 10, 8 24 31 PM.png"])
    rectMode(CENTER)
    dir,i=1,1
    delay,xs,ys=0,0,0
    dx,dy=WIDTH/2,HEIGHT/2
    createButtons()
    extractSprites()
end    

function createButtons()
    x,y=WIDTH/2,100
    bTab={}
    table.insert(bTab,button(x-50,y+50,17,-1,1,"u-l"))
    table.insert(bTab,button(x,y+50,9,0,1,"up"))
    table.insert(bTab,button(x+50,y+50,1,1,1,"u-r"))
    table.insert(bTab,button(x-50,y,33,-1,0,"left"))
    table.insert(bTab,button(x+50,y,25,1,0,"right"))
    table.insert(bTab,button(x-50,y-50,57,-1,-1,"d-l"))
    table.insert(bTab,button(x,y-50,49,0,-1,"down"))
    table.insert(bTab,button(x+50,y-50,41,1,-1,"d-r"))
end

function extractSprites()   
    tab={}
    stepX=img.width//8
    stepY=img.height//8
    sizeX=stepX*8
    sizeY=stepY*8
    for y=1,sizeY,stepY do
        for x=1,sizeX,stepX do
            table.insert(tab,img:copy(x,y,stepX,stepY))
        end
    end
end

function draw()
    background(255)
    drawGround()
    checkButtons()   
    drawPerson()
end

function drawGround()
    dx=dx+xs
    dy=dy+ys
    for x=-20,20 do
        for y=-20,20 do
            sprite(asset.builtin.Blocks.Gravel_Stone,x*128-dx,y*128-dy)
        end
    end   
end

function checkButtons()
    for a,b in pairs(bTab) do
        b:draw()
    end
end

function drawPerson()    
    delay=delay+1   
    if delay>15 then
        delay=1
        if xs~=0 or ys~=0 then
            i=i+1
            if i>dir+7 then
                i=dir
            end
        end
    end
    sprite(tab[i],WIDTH/2,HEIGHT/2,100)
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        for a,b in pairs(bTab) do
            b:touched(t)
        end
    elseif t.state==ENDED then
        xs=0
        ys=0
    end
end

button=class()

function button:init(x,y,d,xs,ys,n)
    self.x=x    -- x position   
    self.y=y    -- y position
    self.dir=d  -- person direction
    self.xs=xs*2  -- person speed x
    self.ys=ys*2 -- person speed y
    self.name=n -- button name
end

function button:draw()
    fill(255,0,0)
    rect(self.x,self.y,50,50)
    fill(255)
    text(self.name,self.x,self.y)
end

function button:touched(t)
    if t.x>self.x-25 and t.x<self.x+25 and t.y>self.y-25 and t.y<self.y+25 then
        dir=self.dir
        i=dir
        xs=self.xs
        ys=self.ys
    end
end

@Jarc You know the x,y position of your sprite walker. To prevent the walker from going thru a wall, just make sure the walker won’t have the same x,y position plus or minus some value as the wall.

@dave1707 Why is the other ellipse moving relative to me? I want to be able to walk up to it, is it a problem with background? Also when I give the sprite collider coordinates

 self.x=x 
 self.y=y

it doesn’t work.

Here’s what I have so far.

displayMode(FULLSCREEN)

function setup()
    img=readImage(asset.documents.Dropbox["Photo Apr 10, 8 24 31 PM.png"])
    rectMode(CENTER)
    dir,i=1,1
    delay,xs,ys=0,0,0
    dx,dy=WIDTH/2,HEIGHT/2
    createButtons()
    extractSprites()
    
    --Collider
        
    c1 = physics.body(CIRCLE,100)    -- sprite collision circle
    c1.type=STATIC
    c1.x=WIDTH/2
    c1.y=360
    
    c2 = physics.body(CIRCLE,50)    -- ellipse 
    c2.type=STATIC
    c2.x=400
    c2.y=750
    
end    

function createButtons()
    x,y=WIDTH/2,100
    bTab={}
    table.insert(bTab,button(x-50,y+50,17,-1,1,"u-l"))
    table.insert(bTab,button(x,y+50,9,0,1,"up"))
    table.insert(bTab,button(x+50,y+50,1,1,1,"u-r"))
    table.insert(bTab,button(x-50,y,33,-1,0,"left"))
    table.insert(bTab,button(x+50,y,25,1,0,"right"))
    table.insert(bTab,button(x-50,y-50,57,-1,-1,"d-l"))
    table.insert(bTab,button(x,y-50,49,0,-1,"down"))
    table.insert(bTab,button(x+50,y-50,41,1,-1,"d-r"))
end

function extractSprites()   
    tab={}
    stepX=img.width//8
    stepY=img.height//8
    sizeX=stepX*8
    sizeY=stepY*8
    for y=1,sizeY,stepY do
        for x=1,sizeX,stepX do
            table.insert(tab,img:copy(x,y,stepX,stepY))
        end
    end
end

function draw()
    background(255)
    drawGround()
    checkButtons()   
    drawPerson()
end

function drawGround()
    dx=dx+xs
    dy=dy+ys
    for x=-20,20 do
        for y=-20,20 do
            sprite(asset.builtin.Blocks.Gravel_Stone,x*128-dx,y*128-dy)
        end
    end   
    
    --collider
    popStyle()
    stroke(255)
    strokeWidth(1)
    noFill()
    ellipse(c1.x,c1.y,100,140)    -- collider on sprite
    ellipse(c2.x,c2.y,100,100)    -- ellipse collider
    pushStyle()
    
end

function checkButtons()
    for a,b in pairs(bTab) do
        b:draw()
    end
end

function drawPerson()    
    delay=delay+1   
    if delay>15 then
        delay=1
        if xs~=0 or ys~=0 then
            i=i+1
            if i>dir+7 then
                i=dir
            end
        end
    end
    sprite(tab[i],WIDTH/2,HEIGHT/2,100)
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        for a,b in pairs(bTab) do
            b:touched(t)
        end
    elseif t.state==ENDED then
        xs=0
        ys=0
    end
end

button=class()

function button:init(x,y,d,xs,ys,n)
    self.x=x    -- x position   
    self.y=y    -- y position
    self.dir=d  -- person direction
    self.xs=xs*2  -- person speed x
    self.ys=ys*2 -- person speed y
    self.name=n -- button name
end

function button:draw()
    fill(255,0,0)
    rect(self.x,self.y,50,50)
    fill(255)
    text(self.name,self.x,self.y)
end

function button:touched(t)
    if t.x>self.x-25 and t.x<self.x+25 and t.y>self.y-25 and t.y<self.y+25 then
        dir=self.dir
        i=dir
        xs=self.xs
        ys=self.ys
    end
end


function collide(c)  -- this gets called when a collision occurs
    if c.state==BEGAN then
        print("\
collision")
        print("radius of body A ",c.bodyA.radius)
        print("radius of body B ",c.bodyB.radius)
    end  
end

@dave1707 I made this change but the other ellipse still moves relative to me.

  c1.x=dx
  c1.y=dy

Both of your collider ellipses need to be relative to the ground, dx,dy.

    --Collider

    c1 = physics.body(CIRCLE,100)    -- sprite collision circle
    c1.type=STATIC
    c1.x=WIDTH/2*2
    c1.y=360+dy

    c2 = physics.body(CIRCLE,50)    -- ellipse 
    c2.type=STATIC
    c2.x=400+dx
    c2.y=750+dy
    --collider
    popStyle()
    stroke(255)
    strokeWidth(1)
    noFill()
    ellipse(c1.x-dx,c1.y-dy,100,140)    -- collider on sprite
    ellipse(c2.x-dx,c2.y-dy,100,100)    -- ellipse collider
    pushStyle()

@dave1707 but the collider isn’t tied to him anymore.

@dave1707 same problem with what I sent. It ties it to him and I can walk to other ellipse but collision isn’t working now.

@dave1707 The one with the comment “sprite collision circle” and “Collider on sprite” beside it

Is this ok.

    c1 = physics.body(CIRCLE,100)    -- sprite collision circle
    c1.type=STATIC
    c1.x=WIDTH/2
    c1.y=HEIGHT/2

    c2 = physics.body(CIRCLE,50)    -- ellipse 
    c2.type=STATIC
    c2.x=400+dx
    c2.y=750+dy
    --collider
    popStyle()
    stroke(255)
    strokeWidth(1)
    noFill()
    ellipse(c1.x,c1.y,100,140)    -- collider on sprite
    ellipse(c2.x-dx,c2.y-dy,100,100)    -- ellipse collider
    pushStyle()

@dave1707 This way ties it to him and I can walk to other ellipse but collision stops working.

    c1 = physics.body(CIRCLE,100)    -- sprite collision circle
    c1.type=STATIC
    c1.x=WIDTH/2
    c1.y=360

 
    c2 = physics.body(CIRCLE,50)    -- ellipse 
    c2.type=STATIC
    c2.x=400+dx
    c2.y=750+dy
   --collider
    popStyle()
    stroke(255)
    strokeWidth(1)
    noFill()
    ellipse(c1.x,c1.y,100,140)    -- collider on sprite   -- ellipse collider
    ellipse(c2.x-dx,c2.y-dy,100,100)    -- ellipse collider
    pushStyle()

.

@dave1707 So for my question at 11:00am I would have rather you said “it can’t be done on Codea” then having me go down a rabbit hole.

.