Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Bump — Gideros Forum

Bump

misterhupmisterhup Member
edited March 2016 in General questions
Hi! I am trying to detect a simple collision between 2 bitmaps and then do something if they do collide. I am thinking to use bump, so I was wondering if it handles bitmaps and/or other types of objects. (for example I have an objected imported using Spriter, and I was wondering if I can detect a collision with it).
Also I tried detecting collisions with the following code, but the response is way to slow for what I need so I was wondering if bumb can do any better.
function Sprite:collision(sprite2)
 	local myX = self:getX()
 	local myY = self:getY()
 	local myWidth = self:getWidth()
 	local myHeight = self:getHeight()
 	local otherX = sprite2:getX()
 	local otherY = sprite2:getY()
 	local otherWidth = sprite2:getWidth()
 	local otherHeight = sprite2:getHeight()
 
	if myY + myHeight < otherY or myY > otherY + otherHeight then
		return false
	end
 
	if myX > otherX + otherWidth or myX  + myWidth < otherX then
		return false
	end
 
	return true
end

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    You can try this, should be faster:
    function Sprite:collidesWith(sprite2)
    	local x,y,w,h = self:getBounds(stage)
    	local x2,y2,w2,h2 = sprite2:getBounds(stage)
     
    	return not ((y+h < y2) or (y > y2+h2) or (x > x2+w2) or (x+w < x2))
    end

    Likes: misterhup

    +1 -1 (+1 / -0 )Share on Facebook
  • Thanks! :) The difference is visible and it works way faster but I think I discovered something. I check for collision with a sprite which is rotated but I think it detects the collision with the previous position of the sprite so the collision is made with the unrotated object...Changing the rotation of an object shouldn't change it's position too?
  • What I'm trying to say is should this function work with a rotated sprite?
  • chuz0chuz0 Member
    I think that it only works on x-axis aligned boxes.
    There's another function that tells you whether a point is inside a box or not, so you can check the 4 points of a rotated box and check if any of them is inside the other box.
  • ar2rsawseenar2rsawseen Maintainer
    yes, this approach uses bounding box and I think bounding box of rotated sprite is just a figure that can include the rotated sprite.

    So it won't work in those cases
  • So, is there any other way to check for collision with a rotated object?
  • I could write a function and create an invisible sprite to rotate and resize on the axis based on the rotation of the main sprite, and use that main sprite just as graphic and not as a collision object. But I fear that would impact the performance of the app a lot.
  • antixantix Member
    @misterhup, bump only works with AABB's (Axis Aligned Bounding Boxes) so you can't use it for rectangles that have been rotated.

    Are you needing to detect collisions with rotated rectangles?
  • @antix Sadly yes... And even more, rotated sprites/imported objects. Is there any way I can do that? Box2D maybe? :|
  • antixantix Member
    @misterhup, okay box2D is one way to solve your collision issue but it is kind of like hitting an ant with a sledgehammer :)
    +1 -1 (+2 / -0 )Share on Facebook
  • Well is there any better way to do it then? I just want to detect collision between 2 rotated sprites. That's all. :-/
  • ar2rsawseenar2rsawseen Maintainer
    There was also TNT collision engine.

    But about Sprite implementation, I remember there were hacks, like transforming coordinates yourself, or using your own sprite local bounds and transforming coordinates to global.

    Theoretically it could work, but not 100% sure :)

    This thread could help you:
    http://giderosmobile.com/forum/discussion/1733/spritegetboundstargetsprite/p1

    Likes: misterhup

    +1 -1 (+1 / -0 )Share on Facebook
  • antixantix Member
    edited March 2016
    Okay here is a little example project that can detect collisions between rotated rectangles. The collision stuff is from this page.. https://bitbucket.org/RudenkoPaint/sat-lua. The version included here has been modified slightly to better work with Gideros. It's a bit messy but it works.

    When you run the example project you can click and drag one of the boxes around. If it collides with the other, both turn red.

    NOTE: The example is fairly basic and does not perform any collision resolution but with a bit of work it could easily do so. The "response" table in the main loop contains pretty much everything you need to resolve the collisions.

    Anyway, it should be enough to get you up and running :)

    EDIT: See further down the thread for the latest version of the example
    +1 -1 (+3 / -0 )Share on Facebook
  • antixantix Member
    I am just tidying up the SAT code and will post it in a few days as we are off for Easter weekend now and most likely will have no internet :((
  • Thanks a lot! I got it to work :D Also I found a way to do it using a bunch of rectangles positioned on the sprites axis and checking the collision with every one of them. It is a little too grindy and your method is better in my opinion, so Ill go with it :P Ill post my method here anyways after I optimize it a little. :)

    Likes: antix

    +1 -1 (+1 / -0 )Share on Facebook
  • antixantix Member
    As promised, I have updated the example...
    --[[
     
    SAT Rectangle Collision Example for Gideros
    by Cliff Earl
    Antix Software
    March 2016
     
    Example  project that  creates and  displays 2  rotating boxes  that can  be 
    dragged  about the  screen by  their center  points, and  detects collisions 
    between them. 
     
    Collision  detection  is a  2 part  process. First  the bounding  boxes  are 
    checked to see  if they overlap  (it is pointless  to waste CPU  time on SAT 
    calculations  unless that is the case). Once the  boxes overlap they will be 
    tinted yellow and  SAT collision detection will then  be applied to test for 
    intersection  (one rectangle partially  inside the other  rectengle). If the 
    rectangles do intersect then they will be tinted red.
     
    There is one class (Draggable) and 1 library (GSAT) included in the example. 
     
    Draggable
    An  extension  of  Bitmap  that can  be dragged  about by  its  center.  See 
    Draggable.lua for more information.
     
    GSAT
    A  simple library for  performing collision  detection (and projection-based 
    collision response) of rectangular shapes in  2 dimensions. See GSAT.lua for 
    more information.
     
    --]]
     
    --require("mobdebug").start() -- ONLY REQUIRED FOR ZEROBRANE
     
    local GSAT = require("gsat") -- THE COLLISION LIBRARY
     
    local function newBox(actor) -- CREATE A NEW COLLISION BOX
      local x, y, w, h = actor:getBounds(stage)
      local box = GSAT.Box(x + (w * 0.5), y + (h * 0.5), w, h)
      box:setRotation(actor:getRotation())
      return box
    end
     
    local function actorInActor(actor1, actor2) -- TEST 2 BOUNDING BOX FOR OVERLAP
    	local x, y, w, h = actor1:getBounds(stage)
    	local x2, y2, w2, h2 = actor2:getBounds(stage)
    	return not ((y+h < y2) or (y > y2+h2) or (x > x2+w2) or (x+w < x2))
    end
     
    local info = TextField.new(nil, "Drag the boxes by their centers to move them")
    info:setPosition(20, 20)
     
    local player = Draggable.new(Texture.new("images/box.png", true), {x = 160, y = 128}) -- CREATE PLAYER
    player.box = newBox(player)
    player.onDragged = function() player.box:setPosition(player:getPosition()) end
     
    local enemy = Draggable.new(Texture.new("images/box.png", true), {x = 160, y = 352}) -- CREATE ENEMY
    enemy.box = newBox(enemy)
    enemy.onDragged = function() enemy.box:setPosition(enemy:getPosition()) end
     
    local function onEnterFrame(event) -- MAIN LOOP
     
      local angle = enemy:getRotation() - 0.284 -- ROTATE ENEMY CCW
      enemy:setRotation(angle)
      enemy.box:setRotation(angle)
     
      angle = player:getRotation() + 0.284 -- ROTATE PLAYER CW
      player:setRotation(angle)
      player.box:setRotation(angle)
     
      if actorInActor(player.box, enemy.box) then
        stage:setColorTransform(1, 1, 0, 1) -- BOXES OVERLAP, TINT YELLOW
     
        local response = GSAT.Response() -- CHECK FOR COLLISION BETWEEN BOXES
        local collided = GSAT.checkCollision(player.box, enemy.box, response)
        if collided then
          stage:setColorTransform(1, 0, 0, 1) -- BOXES COLLIDED,  TINT BOXES RED
     
          --
          -- PERFORM COLLISION RESOLUTIONS HERE
          --
     
        end
      else
        stage:setColorTransform(1, 1, 1, 1) -- NO COLLISION, TINT BOXES BACK TO NORMAL
      end
     
    end
     
    stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)
     
    stage:addChild(enemy)
    stage:addChild(player)
     
    stage:addChild(info)
    zip
    zip
    SAT Collision.zip
    19K
    SAT Collision.png
    336 x 540 - 33K

    Likes: misterhup, pie

    +1 -1 (+2 / -0 )Share on Facebook
Sign In or Register to comment.