Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

What is the best collision detection method for moving controlled sprite

in Questions Posts: 124

I have this method (project below) but I’m searching for a better way. I don’t want the sprite character to go through walls,enemys..etc
The reason I’m asking is because I’m having trouble with this method when I attach a joystick to the character sprite.

Also if you use a if then statement like I did below what else can I put after then to make the collision happen

currentposition=vec2
currentposition2=vec2

function setup()
    a=5
    currentposition=vec2(WIDTH/2,HEIGHT/2)
    currentposition2=vec2(WIDTH/2+300,HEIGHT/2)
    image1=asset.builtin.Space_Art.Part_Yellow_Hull_2
    wall=asset.builtin.Blocks.Stone_Browniron
end

function draw()

    background(40, 40, 50)
    spriteMode(CORNER)

    sprite(asset.builtin.Blocks.Stone_Browniron,currentposition2.x,currentposition2.y)
    sprite(image1,currentposition.x,currentposition.y)
    currentposition.x =  currentposition.x + a

    if currentposition.x == currentposition2.x-45 or currentposition.y == currentposition2.y-45 then
        a=-5 -- make sprite key bounce off
        --a=0 -- make sprite keystop
    end 
end

Comments

  • Posts: 124

    If I’m going about this the wrong way or overthinking let me know.
    Links and tutorials are much appreciated as well, I just want to understand how to manually calculate collisions without the use of a physics engine.

  • dave1707dave1707 Mod
    edited April 28 Posts: 8,398

    @Jarc Here's some code, but I only have it working going in the down direction. The bottom and top line stops you going in the down direction, but the other directions just give you the collision warning. When the line stops you, you can move in the up direction once you get into the up area of the joystick.

    PS. Added more code. Works in all directions, but needs more work.

    displayMode(FULLSCREEN)
    
    function setup()
        hdx,hdy=0,0
        Stop=0
        parameter.watch("dy")
        cx,cy=0,0
        sx,sy=WIDTH/2,HEIGHT/2
        dx,dy=0,0
    
        fill(255)
        stroke(255)
        strokeWidth(1)
    
        c1 = physics.body(CIRCLE,50)    -- sprite collision circle
        c1.type=DYNAMIC
        c1.x=WIDTH/2
        c1.y=400
        c1.sleepingAllowed=false
        c1.bullet=true
    
        c2 = physics.body(CIRCLE,50)    -- sprite collision circle
        c2.type=STATIC
        c2.x=WIDTH/2
        c2.y=700
        c2.sleepingAllowed=false
        c2.bullet=true
    
        l1= physics.body (EDGE, vec2(50,50),vec2(WIDTH-50,50))
        l2= physics.body (EDGE, vec2(50,HEIGHT-50),vec2(WIDTH-50,HEIGHT-50))
        l3= physics.body (EDGE, vec2(50,50),vec2(50,HEIGHT-50))
        l4= physics.body (EDGE, vec2(WIDTH-50,50),vec2(WIDTH-50,HEIGHT-50))
    end
    
    function draw()
        background(40, 40, 50)
        noFill()
        if cx>0 and cy>0 then
            drawCirc()
        end    
        line(50,50,WIDTH-50,50)
        line(50,HEIGHT-50,WIDTH-50,HEIGHT-50)
        line(50,50,50,HEIGHT-50)
        line(WIDTH-50,50,WIDTH-50,HEIGHT-50)
    
    
        if Stop==1 then
            if hdx<0 then
                if dx>0 then
                    Stop=0
                end
            end
            if hdx>0 then
                if dx<0 then
                    Stop=0
                end
            end
            if hdy<0 then
                if dy>0 then
                    Stop=0
                end
            end
            if hdy>0 then
                if dy<0 then
                    Stop=0
                end
            end
        else
            sx=sx+dx
            sy=sy+dy
        end
    
        c1.x=sx 
        c1.y=sy
    
        ellipse(c1.x,c1.y,100)
        ellipse(c2.x,c2.y,100)
        fill(255)
        fontSize(20)
        msg="No collision"
        if Stop==1 then
            msg="Collision"
        end
        text(msg,WIDTH/2,HEIGHT/2)
    end
    
    function touched(t)
        if t.state==BEGAN then
            cx,cy=t.x,t.y      
        end
        if t.state==MOVING then
            if insideCircle(t.x,t.y) then
                dx=(t.x-cx)/10
                dy=(t.y-cy)/10
            else
                cx,cy=0,0
                dx,dy=0,0
            end
        end
        if t.state==ENDED then
            cc,cy=0,0
            dx,dy=0,0
        end
    end
    
    function insideCircle(x,y)
        -- check if touch is inside of circle or ellipse
        a,b=100,100 -- radius of circle or a,b of ellipse
        if (x-cx)^2/a^2+(y-cy)^2/b^2 <= 1 then 
            return true
        end
        return false
    end
    
    function drawCirc()
        fill(255, 255, 255, 50)
        ellipse(cx,cy,50) -- draw circle center
        fontSize(15)
        fill(233, 80, 133)
        text("Up",cx,cy+80)
        text("Down",cx,cy-80)
        text("Right",cx+80,cy)
        text("Left",cx-80,cy)
        fontSize(10)
        text("DTL",cx-60,cy+60)
        text("DTR",cx+60,cy+60)
        text("DBL",cx-60,cy-60)
        text("DBR",cx+60,cy-60)
        noFill()
        stroke(255,255,255,50)
        strokeWidth(4)
        ellipse(cx,cy,200) -- draw outer circle     
    end
    
    function collide(c)  -- this gets called when a collision occurs
        if c.state==BEGAN then
            print("\ncollision")
            print("radius of body A ",c.bodyA.radius)
            print("radius of body B ",c.bodyB.radius)
            Stop=1 
            hdx=dx
            hdy=dy      
        end 
    end
    
  • dave1707dave1707 Mod
    Posts: 8,398

    @Jarc I updated the above code to work in all directions. It still needs work though.

  • Posts: 124

    @dave1707 Thanks for working on it. I’ve been trying on both codes since you posted. I’ve noticed that in both codes the initial collision stops the ellipse but if keep trying to go in that direction it will eventually go through.

    I think I found the solution that stops the ellipse and makes it so you can’t get through but I’m not sure how to write the code.

    function touched(t)
        if t.state==BEGAN then
            cx,cy=t.x,t.y  
            Stop=1
        end
    

    If the Stop=1 can only be true when touching the edge line and in the direction of the edge line then it will stop the ellipse from getting through no matter what.

  • dave1707dave1707 Mod
    Posts: 8,398

    @Jarc Try this code.

    displayMode(FULLSCREEN)
    
    function setup()
        physics.gravity(0,0)
        cx,cy=0,0
        sx,sy=0,0
        dx,dy=0,0
    
        fill(255)
        stroke(255)
        strokeWidth(1)
    
        c1 = physics.body(CIRCLE,50)    -- sprite collision circle
        c1.type=DYNAMIC
        c1.x=WIDTH/2
        c1.y=400
        c1.sleepingAllowed=false
    
        c2 = physics.body(CIRCLE,50)    -- sprite collision circle
        c2.type=STATIC
        c2.x=WIDTH/2
        c2.y=600
        c2.sleepingAllowed=false
    
        l1= physics.body (EDGE, vec2(50,50),vec2(WIDTH-50,50))
        l2= physics.body (EDGE, vec2(50,HEIGHT-50),vec2(WIDTH-50,HEIGHT-50))
        l3= physics.body (EDGE, vec2(50,50),vec2(50,HEIGHT-50))
        l4= physics.body (EDGE, vec2(WIDTH-50,50),vec2(WIDTH-50,HEIGHT-50))
    end
    
    function draw()
        background(40, 40, 50)
        noFill()
        if cx>0 and cy>0 then
            drawCirc()
        end    
        line(50,50,WIDTH-50,50)
        line(50,HEIGHT-50,WIDTH-50,HEIGHT-50)
        line(50,50,50,HEIGHT-50)
        line(WIDTH-50,50,WIDTH-50,HEIGHT-50)
    
        c1.x=c1.x+dx
        c1.y=c1.y+dy
    
        ellipse(c1.x,c1.y,100)
        ellipse(c2.x,c2.y,100)
    end
    
    function touched(t)
        if t.state==BEGAN then
            cx,cy=t.x,t.y      
        end
        if t.state==MOVING then
            if insideCircle(t.x,t.y) then
                dx=(t.x-cx)/10
                dy=(t.y-cy)/10
            else
                cx,cy=0,0
                dx,dy=0,0
            end
        end
        if t.state==ENDED then
            cc,cy=0,0
            dx,dy=0,0
        end
    end
    
    function insideCircle(x,y)
        -- check if touch is inside of circle or ellipse
        a,b=100,100 -- radius of circle or a,b of ellipse
        if (x-cx)^2/a^2+(y-cy)^2/b^2 <= 1 then 
            return true
        end
        return false
    end
    
    function drawCirc()
        fill(255, 255, 255, 50)
        ellipse(cx,cy,50) -- draw circle center
        fontSize(15)
        fill(233, 80, 133)
        text("Up",cx,cy+80)
        text("Down",cx,cy-80)
        text("Right",cx+80,cy)
        text("Left",cx-80,cy)
        fontSize(10)
        text("DTL",cx-60,cy+60)
        text("DTR",cx+60,cy+60)
        text("DBL",cx-60,cy-60)
        text("DBR",cx+60,cy-60)
        noFill()
        stroke(255,255,255,50)
        strokeWidth(4)
        ellipse(cx,cy,200) -- draw outer circle     
    end
    
  • Posts: 124

    @dave1707 wow it works! Applying gravity solved the problem.

  • dave1707dave1707 Mod
    Posts: 8,398

    @Jarc Not applying gravity worked. The statement physics.gravity(0,0) turned off the gravity for the x and y direction. Once I did that I was able to eliminate a lot of code.

Sign In or Register to comment.