color collision

Hello, this is my first post here. I was programming in basic! By Mysoft but they no longer have an online community so I found Codea and I’m pumped! Unfortunately I don’t see any color collision options. Am I missing something. If there is no color collision what would u recommend?

What is color collision.

I could set up code so if l Had… say… a red ball I could have it run into a white wall and It would execute a command because I set it up so it would interact with the color white. In basic! a snip it of code would look like.


'-----------Color Collision Detect ---------
' checks 8 positions around the ball
FOR ii = 0 TO 359 STEP 45
    ReadX = JotX + COS(ii/180*PI)*JotR*1.1
    ReadY = JotY + SIN(ii/90*PI) * JotR 
    READPIXEL ReadX,ReadY
    'Map Collision
    IF ReadPixelR > 199 AND ReadPixelR < 202 AND ReadPixelG > 199 AND ReadPixelG < 202 AND ReadPixelB > 199 AND ReadPixelB < 202 THEN
        t0.1.1d = TickCount
        FOR n=0 TO 2500
            x1=RND *scw
            y1=RND *sch
            x2=RND *scw
            y2=RND *sch
            c=RND *14
            w=RND *9
            COLOR 100,0,0
            LINE INT(x1), INT(y1), INT(x2), INT(y2), w 
            COLOR 200,0,0
            TEXTFONT (.08 * sch + .08* scw)
            DRAWTEXT "OUCH!!!", .22* scw,  .30* sch
        NEXT

What was cool about this color collision is that anything that was white would interact the same with the red ball. So if I wanted to make a maze with white large letters,lines, blocks, whatever if it was white I would interact the came. I would not have set individual parameters for each item.

So basically, you’re just testing the color value at an x,y screen position. If that’s all you’re doing, then Codea can do that using the image get function. Also, anytime you post code, to have it show correctly, put 3 ~'s on a line before and after the code. I added them to your code above.

Another way that it can be done with Codea is to use the physics engine and use a mask to determine what objects can collide or not. By using the physics engine all of the collision movement is done automatically.

@BaptistBenton Here’s an example. The green ball will bounce off the green line. The white ball will bounce off the white line. The green and white balls will bounce off each other or the side and top lines that l’m not drawing. A lot of different combinations can be done depending on what objects you have and what you want to do.

displayMode(FULLSCREEN)

function setup()
    e1=physics.body(EDGE,vec2(0,50),vec2(WIDTH,50))
    e1.categories={1}
    e2=physics.body(EDGE,vec2(0,300),vec2(WIDTH,300))
    e2.categories={2}
    e3=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
    e3.categories={1,2}
    e4=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
    e4.categories={1,2}
    e5=physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
    e5.categories={1,2}
    b1=physics.body(CIRCLE,40)
    b1.x=200
    b1.y=500
    b1.restitution=1
    b1.linearVelocity=vec2(300,500)
    b1.mask={1}
    b1.friction=0
    b1.categories={2}
    b2=physics.body(CIRCLE,40)
    b2.x=400
    b2.y=700
    b2.restitution=1
    b2.mask={2}
    b2.categories={1}
    b2.friction=0
    strokeWidth(2)
end

function draw()
    background(0)
    noStroke()
    fill(255)
    ellipse(b1.x,b1.y,80)
    fill(0,255,0)
    ellipse(b2.x,b2.y,80)
    strokeWidth(2)
    stroke(255)
    line(0,50,WIDTH,50)
    stroke(0,255,0)
    line(0,300,WIDTH,300)
end

Nice’ I’m going to look more into this “image get function” stuff. Thanks for the physics engine example. I appreciate the help…

Generally, you’ll find it’s easier to keep a table of maze positions and test your ball position against that. Using pixels is a bit kludgy.

I would only use this kind of bitmap query collision for certain types of projects. I believe it’s used for Lemmings and Worms, where you need to modify the landscape dynamically, and have very small objects that benefit from pixel collisions

@BaptistBenton Here’s another way to check if something runs into something else. Hold the iPad flat and tilt to move the ball. I set up a simple maze, a square and a point. If the ball hits something, it turns red.

displayMode(FULLSCREEN)

function setup()
    tab={}
    -- maze
    table.insert(tab,vec4(200,200,400,200))
    table.insert(tab,vec4(400,200,400,550))
    table.insert(tab,vec4(200,250,350,250))
    table.insert(tab,vec4(350,250,350,600))
    table.insert(tab,vec4(350,600,600,600))
    table.insert(tab,vec4(400,550,600,550))
    
    -- square
    table.insert(tab,vec4(200,400,220,400))
    table.insert(tab,vec4(220,400,220,420))
    table.insert(tab,vec4(200,420,200,400))
    table.insert(tab,vec4(200,420,220,420))
    
    -- point
    table.insert(tab,vec4(230,480,230,480))

    p=vec2(WIDTH-200,HEIGHT-200)  -- circle starting position
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(2)
    p=p+vec2(Gravity.x*10,Gravity.y*10)
    fill(255)
    for a,b in pairs(tab) do
        line(b.x,b.y,b.z,b.w)
        distPointToLineSeg(p,vec2(b.x,b.y),vec2(b.z,b.w))
        if d1<20 then
            fill(255,0,0)
        end
    end
    noStroke()
    ellipse(p.x,p.y,40)
end

function distPointToLineSeg(p,s1,s2)
    local v = s2 - s1
    local w = p - s1
    local c1=w:dot(v)
    if c1<=0 then
        d1=p:dist(s1)  -- distance
        return
    end
    local c2=v:dot(v)
    if c2<=c1 then
        d1=p:dist(s2)  -- distance
        return
    end
    d1=p:dist(s1+(c1/c2)*v)  -- distance
end

Dave Love your code… I added a shrink rate to the ellipse. Now I need to find out how to make the ellipse interact differently from the Maze line and the box. Say when the ellipse touches the box the box disappears and the ellipse’s radius grows +20 to keep him alive… Until he gets to the end of the maze/puzzle. If he hits a radius of 0 he’s dead.

displayMode(FULLSCREEN)

function setup()
    tab={}
    -- maze
    table.insert(tab,vec4(200,200,400,200))
    table.insert(tab,vec4(400,200,400,550))
    table.insert(tab,vec4(200,250,350,250))
    table.insert(tab,vec4(350,250,350,600))
    table.insert(tab,vec4(350,600,600,600))
    table.insert(tab,vec4(400,550,600,550))
    

    -- square
    table.insert(tab,vec4(200,400,220,400))
    table.insert(tab,vec4(220,400,220,420))
    table.insert(tab,vec4(200,420,200,400))
    table.insert(tab,vec4(200,420,220,420))

    -- point
    table.insert(tab,vec4(230,480,230,480))

    p=vec2(WIDTH-200,HEIGHT-200)  -- circle starting position
    r=40 --circle radius
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(2)
    p=p+vec2(Gravity.x*10,Gravity.y*10)
    r=r-.02--circle radius shrink rate
    fill(255)
    for a,b in pairs(tab) do
        line(b.x,b.y,b.z,b.w)
        distPointToLineSeg(p,vec2(b.x,b.y),vec2(b.z,b.w))
        if d1<r/2 then
            fill(255,0,0)
        end
    end
    noStroke()
    ellipse(p.x,p.y,r)
    if r<0 then 
        print "death"
    
    end
end

function distPointToLineSeg(p,s1,s2)
    local v = s2 - s1
    local w = p - s1
    local c1=w:dot(v)
    if c1<=0 then
        d1=p:dist(s1)  -- distance
        return
    end
    local c2=v:dot(v)
    if c2<=c1 then
        d1=p:dist(s2)  -- distance
        return
    end
    d1=p:dist(s1+(c1/c2)*v)  -- distance
end

I changed the table entries to add a type. Now when the distance is less than r/2 I check the type. If the type is 1 ( the box) I set a flag to stop drawing it and increase the radius. There’s probably a better way to do this, but this was the first thing that came to mind.

EDIT: You probably shouldn’t put a print statement in draw. It will print 60 times per second and eventually crash the code. You can display “death” on the screen with a text statement.

EDIT:.Another table could be used to control what shows and what gets hidden.

displayMode(FULLSCREEN)


function setup()
    tab={}
    -- maze
    table.insert(tab,{xy=vec4(200,200,400,200),type=0})
    table.insert(tab,{xy=vec4(400,200,400,550),type=0})
    table.insert(tab,{xy=vec4(200,250,350,250),type=0})
    table.insert(tab,{xy=vec4(350,250,350,600),type=0})
    table.insert(tab,{xy=vec4(350,600,600,600),type=0})
    table.insert(tab,{xy=vec4(400,550,600,550),type=0})

    -- square
    table.insert(tab,{xy=vec4(200,400,220,400),type=1})
    table.insert(tab,{xy=vec4(220,400,220,420),type=1})
    table.insert(tab,{xy=vec4(200,420,200,400),type=1})
    table.insert(tab,{xy=vec4(200,420,220,420),type=1})

    -- point
    table.insert(tab,{xy=vec4(230,480,230,480),type=2})

    p=vec2(WIDTH-200,HEIGHT-200)  -- circle starting position
    r=40 --circle radius
    hide2=false
end

function draw()
    background(40, 40, 50)
    stroke(255)
    strokeWidth(2)
    p=p+vec2(Gravity.x*10,Gravity.y*10)
    r=r-.02--circle radius shrink rate
    fill(255)
    for a,b in pairs(tab) do
        if hide1 and b.type==1 then
            --
        else
            line(b.xy.x,b.xy.y,b.xy.z,b.xy.w)
            distPointToxySeg(p,vec2(b.xy.x,b.xy.y),vec2(b.xy.z,b.xy.w))
            if d1<r/2 then
                fill(255,0,0)
                if b.type==1 then
                    hide1=true
                    r=r+20
                end
            end
        end
    end
    noStroke()
    ellipse(p.x,p.y,r)
    if r<0 then 
        print "death"
    end
end

function distPointToxySeg(p,s1,s2)
    local v = s2 - s1
    local w = p - s1
    local c1=w:dot(v)
    if c1<=0 then
        d1=p:dist(s1)  -- distance
        return
    end
    local c2=v:dot(v)
    if c2<=c1 then
        d1=p:dist(s2)  -- distance
        return
    end
    d1=p:dist(s1+(c1/c2)*v)  -- distance
end