Hi everyone

Hi everyone, i played a lot with Codea.
I’ve searched on the internet more about Codea and haven’t found anything, only this forum.
Dear staff and users, I came here to ask for some help and tips from anyone that could help me.
I have to prepare something nice, really, really nice. A magic game!
I use images with opacity like balls, gems… I need to detect if a sprite has been touched,
but only the visible pixels, not opacity. How can I accomplish this?
By the way my game must be accompanied by a song, a magic song. Can I import a song created with MorphWiz?
Thanks a lot!

Hi Estella, welcome to the forums.

Detecting if a sprite has been touched just by its visible pixels is a tricky one — I’d suggest starting out by just approximating your sprites with rectangles.

I’ll have to think about the best way to do per-pixel hit testing. It could be quite slow if done incorrectly.

In Lua your best bet might be to use some sort of hierarchical spatial partitioning (such as a quadtree) but this seems pretty heavy for hit-testing a sprite.

The fastest method I can think of (that requires a bit of work from your end) is to generate polygons that trace your sprite using the physics engine with the triangulate function, then hit test those physics bodies using an AABB query. This is still a very tricky thing to implement!

At the moment Codea can’t import custom music, but this is an area we’d like to improve.

Hi @Estella_Fox, the following code implements a collision test with an interface inspired to flash as3 hitTest()

As @Simeon suggests the first test is a bounding box check, that is a fast operation, followed by a check pixel per pixel.

Try if it could fit your needs, even if it’s not the fastest function in the world :slight_smile:

Rect = class()

function Rect:init(x,y,w,h)
    self.x = x
    self.y = y
    self.w = w
    self.h = h
end

function Rect:intersects(r2)
   if self.x > (r2.x + r2.w) or (self.x + self.w) < r2.x then
        return false
    end
    if self.y > (r2.y + r2.h) or (self.y + self.h) < r2.y then
        return false
    end
    return true
end


--[[
imageHitTest

check pixel perfect overlap of 2 images

parameters
    i1: image 1
    p1: position (vec2) of image1
    a1: alpha treshold to consider image1 pixel transparent
    i2: image 2
    p2: position (vec2) of image2
    a2: alpha treshold to consider image2 pixel transparent
--]]
function imageHitTest(i1,p1,a1,i2,p2,a2)

    local w1 = i1.width
    local h1 = i1.height
    local w2 = i2.width
    local h2 = i2.height
    
    local r1 = Rect(p1.x,p1.y,w1,h1)
    local r2 = Rect(p2.x,p2.y,w2,h2)
    if not r1:intersects(r2) then 
        return false 
    end
    if p1.x <= p2.x then
        r1.x = p2.x - p1.x
        r2.x = 0
        r1.w = r1.w - r1.x
    else
        r1.x = 0
        r2.x = p1.x - p2.x
        r1.w = r2.w - r2.x
    end
    if p1.y <= p2.y then
        r1.y = p2.y - p1.y
        r2.y = 0
        r1.h = r1.h - r1.y
    else
        r1.y = 0
        r2.y = p1.y - p2.y
        r1.h = r2.h - r2.y
    end
    for i = 1,r1.w do
        for j = 1,r1.h do
            local r,g,b,a = i1:get(r1.x+i,r1.y+j)
            if a > a1 then
                r,g,b,a = i2:get(r2.x+i,r2.y+j)
                if a > a2 then
                    return true
                end
            end
        end
    end
    return false

end

you could draw the screen to an img and then check the pixels of that image. Here’s an example. Doing it for the whole screen (like below) will be very slow but you can also keep track of a smaller portion of the screen based on your sprite’s position/size

function setup()
    watch("frames_per_second")
    __img = image(WIDTH,HEIGHT)

    local oldDraw = draw
    draw = function()
        setContext(__img)
        pushMatrix()
        pushStyle()
        oldDraw()
        popMatrix()
        popStyle()
        setContext()
        
        pushStyle()
        spriteMode(CORNER)
        sprite(__img)
        popStyle()
    end
end

function draw()
    frames_per_second = 1/DeltaTime
    background()
    scale(5)
    spriteMode(CENTER)
    sprite("Planet Cute:Character Boy",WIDTH/10,HEIGHT/10)
end

function touched(t)
    print(__img:get(t.x,t.y))
end

Hi again. Sorry, I’m kinda really busy with other stuff. I totally forgot about this forum. I’m so happy with recent updates, especially, import classes from other projects. Many thanks go to shrike, your example works fairly well. Simeon Thanks for the good wishes! I still have a problem. Problem with importing music created by other apps on iPad such as GarageBand. Can you solve this problem?

Hi @Estella_Fox, GarageBand doesn’t actually export in many friendly formats, eg MIDI. While there are ways around this, Codea doesn’t have native support for importing music either. If you are willing to mess around there is a basic music library I did (search for ABCplayer). Or some folks are looking into adding music post-Xcode export.