Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Registering constant physics collisions
Started by tameem50 Jul 30 2019 09:16 AM

- - - - -
6 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

tameem50

[GLOBAL: userInfoPane.html]
tameem50
  • Contributor

  • 109 posts
  • Corona SDK

I'm making a top down dungeon crawler.

 

I have spike obstacles that go up and down.  my collision code looks like this.  pardon the weird indentation.

			elseif otherObj.name == 'spike' then
				
				if otherObj.isAttacking then
					player:setState('injured', otherObj)
				end

so my issue is that if i'm sitting on top the the spikes while theyre not in an "attacking" state then the collision has already fired and wont re-fire for when the spikes have changed into an "attacking" state.  My player will only take damage if he walks into the spikes when theyre already in an "attacking" state.

 

Is this is a limitation of the physics engine?  I'm managing this by just checking for rectangle intersection in my update loop.



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,103 posts
  • Corona SDK

I would approach this problem by adding values to the player character or the spikes themselves, depending on what your ultimate goal is. For instance,

local spike = {}
spike[1] = display.newRect( 0, 0, 10, 10 )
spike[1].hitsPlayer = false

Now, when your collision event begins, you'd set the ".hitsPlayer" value to true, and when the collision event ends, you'd set it back to false. Then, depending on your approach, whenever you set the spikes to "attacking state", you'd simply check the spikes to see if ".hitsPlayer" is true for any one of them.



[TOPIC: post.html]
#3

tameem50

[GLOBAL: userInfoPane.html]
tameem50
  • Contributor

  • 109 posts
  • Corona SDK

I'm already doing what you suggested..

The issue is if I'm sitting on the spike in it's dormant state and then it changes to its attacking state nothing happens because the physics event won't fire again unless the player moves. The collision already happened so it's not registering the new state of the spike

[TOPIC: post.html]
#4

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,103 posts
  • Corona SDK

Based on what you've written, you aren't doing what I just told you and you've simply misunderstood what I said.

 

Here's quick sample code that demonstrates what I'm telling you.

display.setStatusBar( display.HiddenStatusBar )

local physics = require("physics")
physics.start()
physics.setDrawMode( "hybrid" )
physics.setGravity( 0, 0 )

local platform = display.newRect( display.contentCenterX, display.contentCenterY, 100, 200 )
platform.isDangerous = true
platform.hitsPlayer = false
platform:setFillColor( 1, 0, 0 )
physics.addBody( platform, "static" )

local player = display.newRect( display.contentCenterX+100, display.contentCenterY, 28, 28 )
player:setFillColor( 0, 0.4, 1 )
physics.addBody( player, "dynamic" )

local textCollision = display.newText( "No collision", display.contentCenterX, display.contentCenterY - 180, native.systemFont, 42 )
local textDangerous = display.newText( "platform.isDangerous = "..tostring( platform.isDangerous ), display.contentCenterX, display.contentCenterY - 140, native.systemFont, 42 )
local textIsHit = display.newText( "Player is safe", display.contentCenterX, display.contentCenterY + 140, native.systemFont, 42 )

local function wasPlayerHit()
	if platform.isDangerous and platform.hitsPlayer then
		textIsHit.text = "Player is hit!"
	else
		textIsHit.text = "Player is safe."
	end
end

local function onLocalCollision( self, event )
    if ( event.phase == "began" ) then
        platform.hitsPlayer = true
		textCollision.text = "Collision"
		wasPlayerHit()

    elseif ( event.phase == "ended" ) then
        platform.hitsPlayer = false
		textCollision.text = "No collision"
    end
end
platform.collision = onLocalCollision
platform:addEventListener( "collision" )

player.collision = onLocalCollision
player:addEventListener( "collision" )

local function togglePlatform()
	platform.isDangerous = not platform.isDangerous
	textDangerous.text = "platform.isDangerous = "..tostring( platform.isDangerous )
	wasPlayerHit()
	if platform.isDangerous then
		platform:setFillColor( 1, 0, 0 )
	else
		platform:setFillColor( 0.8 )
	end
end
timer.performWithDelay( 1200, togglePlatform, 0 )

local transitionA
local function transitionB()
	transition.to( player, { time=1000, x=display.contentCenterX+100, onComplete=transitionA } )
end

function transitionA()
	transition.to( player, { time=1000, x=display.contentCenterX-100, onComplete=transitionB } )
end
transitionA()


[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,103 posts
  • Corona SDK

And just to be extra clear:

You need to monitor for
1) when a collision between your player and a spike begins and when it ends, and
2) if the spike is active or not.

Then, whenever you activate a spike or when a collision begins, you need to check if both of these conditions are met.



[TOPIC: post.html]
#6

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

perhaps just add/remove the spike's physics body in response to activation.  when not active, thus no physics body, no contact will occur.  when active, thus a physics body, contact will occur - including even if player happens to be already in contact at that moment.



[TOPIC: post.html]
#7

tameem50

[GLOBAL: userInfoPane.html]
tameem50
  • Contributor

  • 109 posts
  • Corona SDK

thanks for the code example Xedur.  it helped!




[topic_controls]
[/topic_controls]