Howdy, Stranger!

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

Hitbox

edited December 2017 in Questions Posts: 4

Hey everyone
I am currently doing a game, everything is going well so far, but I've found myself in a problem, i am trying to make a rectangular hitbox for a boat, and it works fine when it is at 90 degrees, but when it turns i am having problems with the hitbox, i kinda solved this issue with "vec2(bullet.x,bullet.y):dist(Enemy.pos) < 45"but this creates a circular hitbox and not a rectangular one :(, here i put a failed approach i tried, maybe i am doing something wrong, if anyone could help me i would thank you a lot :)

--[[
        local px= Enemy.pos.x
        local py= Enemy.pos.y
        pushMatrix()
        translate(Enemy.pos.x,Enemy.pos.y)
        rotate(Enemy.Angle)
        pushStyle()
        fill(255, 0, 0, 255)
        ellipse(bullet.x-px,bullet.y-py,10) --this is to see the bullets hitbox
        fill(28, 0, 255, 255)
        rectMode(CORNER)
        rect(-22,-54,44,108) --this is to see the boat hitbox
        popStyle()
        if (bullet.x-px) > -22 and (bullet.x-px) < 22 and (bullet.y-py) > -54 and (bullet.y-py) < 54 then
            sound("A Hero's Quest:Drop")
            table.remove(self.shots,i)
            if InfiniteLife == false then
            self.life=self.life-1
            end
        end
        popMatrix()]]

Comments

  • dave1707dave1707 Mod
    Posts: 6,963

    @CarlosSando What you need to do is convert your bullet position to the rotated box position. I haven’t tried doing that so I don’t have an example to share. I’ll look into it but maybe someone else has tried that and will share what they have.

  • dave1707dave1707 Mod
    Posts: 6,963

    @CarlosSando Here’s an example I put together that allows you to rotate a rectangle using the parameter slider and a bulle coming from the bottom. When the bullet hits the rectangle, it turns the rectangle red and then back to green once the bullet leaves the rectangle. This demonstrates the bullet hitting the rectangle with the rectangle bring in different degrees of rotation. I think this is what you’re after, if not let me know.

    function setup()
        rectMode(CENTER)    -- draw rectangle using center position
        cx,cy=WIDTH/2,HEIGHT/2  -- center point of rectangle
        w=100   -- width of rect
        h=50    -- height of rect
        parameter.integer("ang",-180,180,0,calc)    -- change angle of rectangle
        startBullet() -- start bullet position
    end
    
    function startBullet()
        mx=math.random((WIDTH//2-50),(WIDTH//2+50))
        my=HEIGHT/2-200
    end
    
    function calc() -- calculate rotated corner points of rectangle
        x1,y1=rot(cx-w/2,cy-h/2,ang)
        x2,y2=rot(cx+w/2,cy-h/2,ang)
        x3,y3=rot(cx+w/2,cy+h/2,ang)
        x4,y4=rot(cx-w/2,cy+h/2,ang)
        verts1={vec2(x1,y1),vec2(x2,y2),vec2(x3,y3),vec2(x4,y4)}
    end
    
    function rot(x,y,ang)
        theta=math.rad(ang)
        tempX=x-cx
        tempY=y-cy
        rotatedX=tempX*math.cos(theta)-tempY*math.sin(theta)
        rotatedY=tempX*math.sin(theta)+tempY*math.cos(theta)
        return rotatedX+cx,rotatedY+cy
    end
    
    function draw()
        background(40, 40, 50)
    
        -- draw rotated rectangle
        pushMatrix()
        fill(255)
        if hit then
            fill(255,0,0)
        end
        translate(cx,cy)
        rotate(ang)
        rect(0,0,w,h)
        popMatrix()
    
        -- draw bullet
        fill(0,255,0)
        ellipse(mx,my,10)     
        checkRect(mx,my)    -- check if bullet is within rectangle
        my=my+2             -- move bullet
        if my>HEIGHT/2+200 then -- draw another bullet
            startBullet()
        end
    end
    
    function checkRect(px,py)    -- check if point px,py is within rectangle
        j=#verts1
        hit=false
        for i=1,#verts1 do
            a1=false
            if verts1[i].y>py then
                a1=true
            end
            a2=false
            if verts1[j].y>py then
                a2=true
            end
            b1=verts1[j].x-verts1[i].x
            b2=py-verts1[i].y
            b3=(verts1[j].y-verts1[i].y)
            if a1~=a2 and px<(b1*b2/b3+verts1[i].x) then
                hit=not hit
            end
            j=i
        end 
    end
    
  • Here's a rewrite of @dave1707 's code using more vec2s and native functions to shorten it a bit. I also removed a few globals by packaging things into tables.

    -- HitBox
    
    function setup()
        rectMode(CENTER)    -- draw rectangle using center position
        box = {
            centre = vec2(WIDTH/2,HEIGHT/2),
            size = vec2(100,50),
            angle = 0
        }
        parameter.integer("ang",-180,180,0,function(a) box.angle = a end)    -- change angle of rectangle
        bullet = startBullet()
    end
    
    function startBullet()
        return vec2(math.random((WIDTH//2-50),(WIDTH//2+50)),HEIGHT/2-200)
    end
    
    function draw()
        background(40, 40, 50)
    
        -- draw rotated rectangle
        pushMatrix()
        fill(255)
        if checkRect(box,bullet) then
            fill(255,0,0)
        end
        translate(box.centre.x,box.centre.y)
        rotate(box.angle)
        rect(0,0,box.size.x,box.size.y)
        popMatrix()
    
        -- draw bullet
        fill(0,255,0)
        ellipse(bullet.x,bullet.y,10)     
        bullet.y = bullet.y + 2           -- move bullet
        if bullet.y>HEIGHT/2+200 then -- draw another bullet
            bullet = startBullet()
        end
    end
    
    function checkRect(r,p)    -- check if point p is within rectangle r
        p = (p - r.centre):rotate(-math.rad(r.angle))
        if math.abs(p.x) < r.size.x/2 and math.abs(p.y) < r.size.y/2 then
            return true
        end
        return false
    end
    
  • dave1707dave1707 Mod
    Posts: 6,963

    @LoopSpace I like your checkRect function. I tried something like that to start, but mine didn’t work right all the time. So I took my point inside a polygon routine instead and used that for the rectangle. I’ll have to dig into your function and see why it works.

  • dave1707dave1707 Mod
    Posts: 6,963

    @LoopSpace I see why your routine worked and mine didn’t. It’s hard to explain what’s happening, but I drew everything that you were doing and I saw what I was doing wrong as I rotated the rectangle. It all makes sense now.

Sign In or Register to comment.