Drag and drop

Hi guys, just starting with codea coming from a web dev background.

Looking for an idea of how to make a sprite drag and drop? I want to be able to press a puzzle piece and drag it somewhere else on screen, and none of the demos seem to do this kind of thing?

Any simple pointers would be appreciated, I just need a place to start…

Thanks!

James

Hi James, here’s an example

function setup()
    pos = vec2(200,200)
    size = vec2(202,342)
end

function draw()
    background()
    spriteMode(CORNER)
    sprite("Planet Cute:Character Boy",pos.x,pos.y,size.x,size.y)
end

function touched(t)
    tpos = vec2(t.x,t.y)
    if tpos.x>=pos.x and tpos.x<=pos.x+size.x and tpos.y>=pos.y and tpos.y<=pos.y+size.y then
        if t.state == BEGAN then 
            anchor = tpos - pos
        end
    end
    
    if anchor then pos = tpos - anchor end  
    if t.state == ENDED then anchor = nil end
end

Helllo JmsCrk!

I made an example in which you can move several pieces of puzzle.

Here’s the code:

Main class:

function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_LEFT)
    saveProjectInfo("Description", "Drag & Drop Example")
    saveProjectInfo("Author", "Georgian")
    saveProjectInfo("Version", "1.0")
    saveLocalData('puzzleID', 1)
    saveLocalData('selected', false)
    puzzle1 = Puzzle( 1, 300, 300, 200, 200 )
    puzzle1.image = "Planet Cute:Icon"
    puzzle2 = Puzzle( 2, 500, 300, 200, 200 )
    puzzle2.image = "Small World:Icon"
end

function draw()
    background(255, 255, 255, 255)
    
    if readLocalData('puzzleID') == 1 then
        puzzle2:draw()
        puzzle1:draw()
    elseif readLocalData('puzzleID') == 2 then
        puzzle1:draw()
        puzzle2:draw()
    end
    
    font("Futura-CondensedMedium")
    fill(0, 0, 0, 255)
    fontSize(50)
    if readLocalData('selected') then
        text("  Puzzle "..readLocalData('puzzleID', 0).." has been selected", WIDTH/2, HEIGHT/2-300)
    else
        text("No puzzle has been selected", WIDTH/2, HEIGHT/2-300)
    end
end

function touched(touch) 
    puzzle1:touched(touch)
    puzzle2:touched(touch)
end

Puzzle class:

Puzzle = class()

function Puzzle:init( id, x, y, w, h )
    self.id = id
    self.image = image
    self.position = vec2(x,y)
    self.size = vec2(w,h)
end

function Puzzle:draw()
    sprite(self.image, self.position.x + self.size.x/2, self.position.y + self.size.y/2, self.size.x, self.size.y )
end

function Puzzle:contains( point )
    local l = self.position.x
    local r = self.position.x + self.size.x
    local b = self.position.y
    local t = self.position.y + self.size.y

    if point.x > l and point.x < r and
       point.y > b and point.y < t then
        return true
    end
    return false
end

function Puzzle:touched(touch)
    if touch.state == BEGAN and touch.tapCount == 1 then
        if self:contains( vec2(touch.x, touch.y) ) then
            saveLocalData('puzzleID', self.id)
            saveLocalData('selected', true)
        end
    end
    if touch.state == MOVING and touch.tapCount == 1 then
        if self:contains( vec2(touch.x, touch.y) ) and readLocalData('puzzleID') == self.id then
            self.position.x = CurrentTouch.x - self.size.x / 2
            self.position.y = CurrentTouch.y - self.size.y / 2
        end
    end
    if touch.state == ENDED then
        saveLocalData('selected', false)
    end
end

I hope this code will help you. :slight_smile:

I’m amazed at how quickly you guys pump out code!

Wow thanks for these examples! Amazingly helpful and very quick. It’s the touch state parts that I didn’t know about.

It looks like this code is checking the bounds by a box - I assume you’re doing this because there’s no way to check the shape of an actual sprite? I’m thinking of the way Flash used to be able to check a click on a complex shape by checking the actual pixels…

no easy way to check the shape of the sprite. You could approximately model with a polygon. Otherwise, here’s the best I can come up with: http://twolivesleft.com/Codea/Talk/discussion/comment/10917#Comment_10917