Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Detect collision without physics.?
Started by InfiSnyp Dec 23 2015 07:36 PM

- - - - -
22 replies to this topic

Best Answer Danny , 25 December 2015 - 08:29 AM

The goOnce function shouldn't even be there. It's just making things more confusing.

If you try my latest code sample you will get the same error.

--SonicX278

So, I tried your code. The problem was where I stated :)
Try the below code:

local physics = require("physics")
physics.start()
 
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local actualW = display.actualContentWidth
local actualH = display.actualContentHeight
 
local bullet = {}
local bCounter = 1
local bTimer
 
local wallLeft = display.newRect( centerX - actualW/2 + 20, centerY, 10, actualH )
local wallRight = display.newRect( centerX + actualW/2 - 20, centerY, 10, actualH )
local wallTop = display.newRect( centerX, centerY - actualH/2 + 20, actualW, 10 )
local wallBottom = display.newRect( centerX, centerY + actualH/2 - 20, actualW, 10 )
 
local count = 1
 
local function bob()
    if #bullet >= 1 then
        for i = 1, #bullet do
         print(bullet[i].x)
        end
     end
 
    return true
end
 
local function shootBullet(event)
    local count = 0
    local xB = math.random( -359, 359 )
    local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"
    bullet[bCounter]:setLinearVelocity( xB , yB )
    bCounter = bCounter + 1
end
 
bTimer = timer.performWithDelay( 100, shootBullet, 1 )
Runtime:addEventListener( "enterFrame", bob )

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

How would i go about detecting a collision without physics?

 

Here is the code. Its a sample so you can put it into a portrait simulator and see what i want.

 

I want it so when the bullet gets to a wall it gets removed. This would be easy with physics but i dont want to use physics for this collision.

local physics = require("physics")
physics.start()

local centerX = display.contentCenterX
local centerY = display.contentCenterY
local actualW = display.actualContentWidth
local actualH = display.actualContentHeight

local bullet = {}
local bCounter = 1
local bTimer

local wallLeft = display.newRect( centerX - actualW/2 + 20, centerY, 10, actualH )
local wallRight = display.newRect( centerX + actualW/2 - 20, centerY, 10, actualH )
local wallTop = display.newRect( centerX, centerY - actualH/2 + 20, actualW, 10 )
local wallBottom = display.newRect( centerX, centerY + actualH/2 - 20, actualW, 10 )

local function shootBullet()
	local xB = math.random( -359, 359 )
	local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"

    bullet[bCounter]:setLinearVelocity( xB , yB )

    bCounter = bCounter + 1 
end

bTimer = timer.performWithDelay( 100, shootBullet, -1 )

Thanks!

 

--SonicX278



[TOPIC: post.html]
#2

Alex@Panc

[GLOBAL: userInfoPane.html]
Alex@Panc
  • Corona Geek

  • 1,733 posts
  • Corona SDK

[TOPIC: post.html]
#3

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

I know how to detect collisions without physics but since I have my table I don't know how to do it with that.

--SonicX278

[TOPIC: post.html]
#4

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Any ideas?

--SonicX278

[TOPIC: post.html]
#5

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

If i put a print in 

local function shootBullet()
	local xB = math.random( -359, 359 )
	local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"

    bullet[bCounter]:setLinearVelocity( xB , yB )

    print( bullet[bCounter].x )

    bCounter = bCounter + 1 
end

bTimer = timer.performWithDelay( 100, shootBullet, 1 )

Then it works

 

But when i try to make a function with a Runtime enterFrame listener to it if give me an error.

local function shootBullet()
    local count = 0 
    local xB = math.random( -359, 359 )
    local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"
    bullet[bCounter]:setLinearVelocity( xB , yB )

    local function bob()
        print( bullet[bCounter].x )
    end

    local function goOnce()
        local count = 1 
        if count == 1 then 
            Runtime:addEventListener( "enterFrame", bob )
        end
    end

    timer.performWithDelay( 1, goOnce, -1 )

    bCounter = bCounter + 1 
end

bTimer = timer.performWithDelay( 100, shootBullet, 1 )

I really cant figure this out! Seems so easy tho!

 

--SonicX278 



[TOPIC: post.html]
#6

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,925 posts
  • Enterprise

What error?



[TOPIC: post.html]
#7

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Referring back to this code -- 

local physics = require("physics")
physics.start()

local centerX = display.contentCenterX
local centerY = display.contentCenterY
local actualW = display.actualContentWidth
local actualH = display.actualContentHeight

local bullet = {}
local bCounter = 1
local bTimer

local wallLeft = display.newRect( centerX - actualW/2 + 20, centerY, 10, actualH )
local wallRight = display.newRect( centerX + actualW/2 - 20, centerY, 10, actualH )
local wallTop = display.newRect( centerX, centerY - actualH/2 + 20, actualW, 10 )
local wallBottom = display.newRect( centerX, centerY + actualH/2 - 20, actualW, 10 )

local function shootBullet(event)
    local count = 0 
    local xB = math.random( -359, 359 )
    local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"
    bullet[bCounter]:setLinearVelocity( xB , yB )

    local function bob()
        print( bullet[bCounter].x )
    end

    local function goOnce()
        local count = 1 
        if count == 1 then 
            Runtime:addEventListener( "enterFrame", bob )
        end
    end

    timer.performWithDelay( 1, goOnce, 1 )

    bCounter = bCounter + 1 
end

bTimer = timer.performWithDelay( 100, shootBullet, 1 )

The error is this -- 

C:\Users\ruvim\Documents\Corona Projects\Gun test\main.lua:30: attempt to index
field '?' (a nil value)
stack traceback:
        C:\Users\ruvim\Documents\Corona Projects\Gun test\main.lua:30: in function <C:\Users\ruvim\Documents\Corona Projects\Gun test\main.lua:29>
        ?: in function <?:205>

I also attched a screen shot.

 

Line 30 is the print().

 

--SonicX278

Attached Thumbnails

  • Screenshot 2015-12-24 19.57.21.png


[TOPIC: post.html]
#8

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

I'm seriously stuck! Ugh! Anyone!?

 

--SonicX278



[TOPIC: post.html]
#9

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

Why do you add a runtime listener for every bullet?

Also, do you remove the bullets anywhere? I bet the issue is that you remove the bullet from the bullets array at some stage, then you're attempting to print its value in the runtime listener, but it no longer exists.

If that is the case, your going to be trying to access a table element that doesn't exist (i.e. is nil), hence the error

[TOPIC: post.html]
#10

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

I only add the Runtime once...

The problem is scope. I think. I don't remove the bullets. I'm trying to print the x for the bullet when it moving. But when I put a print in a function inside spawn bullets then it doesn't see it and give me an error.

--SonicX278

[TOPIC: post.html]
#11

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

I only add the Runtime once...

The problem is scope. I think. I don't remove the bullets. I'm trying to print the x for the bullet when it moving. But when I put a print in a function inside spawn bullets then it doesn't see it and give me an error.

--SonicX278

local function goOnce()
    local count = 1 
    if count == 1 then 
        Runtime:addEventListener( "enterFrame", bob )
    end
end

timer.performWithDelay( 1, goOnce, 1 )
 

That timer is going to execute each time you call the bullet creation function, thus adding the runtime listener several times. It should override the previous one, but you should avoid doing that.

 

I'd move "count" to above the createBullet function, and move the "if count == 1" check to above the timer.perform... call



[TOPIC: post.html]
#12

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Yes but I only do

bTimer = timer.performWithDelay( 100, shootBullet, 1 )

Once.(For testing purposes)

--SonicX278

[TOPIC: post.html]
#13

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Merry Christmas btw!!!!

--SonicX278

[TOPIC: post.html]
#14

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

Yes but I only do

bTimer = timer.performWithDelay( 100, shootBullet, 1 )

Once.(For testing purposes)

--SonicX278

 

Please see my edit :)

And ah, so the code you posted isn't the same as the one in your internal side I guess?

 

Merry Christmas btw!!!!

--SonicX278

 

Same to you my friend :)

 

Btw, one way to see where it is going wrong is to do something like this:

print("bullet for index:", bCounter, "is", type(bullet[bCounter])


[TOPIC: post.html]
#15

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

The goOnce function shouldn't even be there. It's just making things more confusing.

If you try my latest code sample you will get the same error.

--SonicX278

[TOPIC: post.html]
#16

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

  Best Answer

The goOnce function shouldn't even be there. It's just making things more confusing.

If you try my latest code sample you will get the same error.

--SonicX278

So, I tried your code. The problem was where I stated :)
Try the below code:

local physics = require("physics")
physics.start()
 
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local actualW = display.actualContentWidth
local actualH = display.actualContentHeight
 
local bullet = {}
local bCounter = 1
local bTimer
 
local wallLeft = display.newRect( centerX - actualW/2 + 20, centerY, 10, actualH )
local wallRight = display.newRect( centerX + actualW/2 - 20, centerY, 10, actualH )
local wallTop = display.newRect( centerX, centerY - actualH/2 + 20, actualW, 10 )
local wallBottom = display.newRect( centerX, centerY + actualH/2 - 20, actualW, 10 )
 
local count = 1
 
local function bob()
    if #bullet >= 1 then
        for i = 1, #bullet do
         print(bullet[i].x)
        end
     end
 
    return true
end
 
local function shootBullet(event)
    local count = 0
    local xB = math.random( -359, 359 )
    local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"
    bullet[bCounter]:setLinearVelocity( xB , yB )
    bCounter = bCounter + 1
end
 
bTimer = timer.performWithDelay( 100, shootBullet, 1 )
Runtime:addEventListener( "enterFrame", bob )


[TOPIC: post.html]
#17

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Yes. That works. But when i change count to 1 in the shootBullet function then it gives the same error and doesn't print the x of the bullet on every frame.

 

--SonicX278



[TOPIC: post.html]
#18

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

Yes. That works. But when i change count to 1 in the shootBullet function then it gives the same error and doesn't print the x of the bullet on every frame.

 

--SonicX278

 

Please try the code in my previous post again (I have edited it). I posted up the wrong thing before.

That demonstrates a better way of handling your situation.

 

Hope this helps



[TOPIC: post.html]
#19

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

That worked! I tweaked it to my liking but your method worked! Thanks a bunch!

 

--SonicX278



[TOPIC: post.html]
#20

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

That worked! I tweaked it to my liking but your method worked! Thanks a bunch!

--SonicX278


You're most welcome :)

[TOPIC: post.html]
#21

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Hey! I have another question. With this code. How would i go about detecting a collision?

local physics = require("physics")
physics.start()
 
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local actualW = display.actualContentWidth
local actualH = display.actualContentHeight
 
local bullet = {}
local bCounter = 1
local bTimer

local i = 1
 
local wallLeft = display.newRect( centerX - actualW/2 + 20, centerY, 10, actualH )
wallLeft.myName = "wallLeft"
local wallRight = display.newRect( centerX + actualW/2 - 20, centerY, 10, actualH )
local wallTop = display.newRect( centerX, centerY - actualH/2 + 20, actualW, 10 )
local wallBottom = display.newRect( centerX, centerY + actualH/2 - 20, actualW, 10 )
 
local function bob()
    if #bullet >= 1 then
        print("hi")
    end
    return true
end
 
local function shootBullet(event)
    local xB = math.random( -359, 359 )
    local yB = math.random( -359, 359 )
    bullet[bCounter] = display.newRect( centerX, centerY, 6, 6 )
    bullet[bCounter].value = bCounter
    physics.addBody( bullet[bCounter], "dynamic", { isSensor = true } )
    bullet[bCounter].gravityScale = 0
    bullet[bCounter].myName = "bullet"
    bullet[bCounter]:setLinearVelocity( -100 , 0 )
    bCounter = bCounter + 1
end
 
bTimer = timer.performWithDelay( 100, shootBullet, 1 )

Runtime:addEventListener( "enterFrame", bob )

--SonicX278



[TOPIC: post.html]
#22

InfiSnyp

[GLOBAL: userInfoPane.html]
InfiSnyp
  • Corona Geek

  • 1,494 posts
  • Corona SDK

Is it even possible?

 

--SonicX278



[TOPIC: post.html]
#23

Danny

[GLOBAL: userInfoPane.html]
Danny
  • Corona Geek

  • 2,597 posts
  • Corona Staff

Is it even possible?

 

--SonicX278

 

It is of course possible :)

 

You'll want to do one of two possible options:

 

1) A runtime listener for collisions that handles all physics objects

2) Per object listeners for collisions.

 

In that listener you would do the following:

 

1) Add a physics body to each of your walls.

2) In your collision listener, if the bullet collides the wall then destroy it.

 

Take a look at the following guide: https://docs.coronalabs.com/daily/guide/physics/collisionDetection/index.html




[topic_controls]
[/topic_controls]