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
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.