Change outline together with frames

Hi again!

So today I have a problem with the outline of my player.
I created an outline of my player and implemented physics on it. My player is a sprite object, with 3 sequences. The dafault is “walk”, then with a tap event it changes to jump or crouch.
I need the outline to change together with the display object (so to change when the frame changes).

This is my code:
local sheetOptions = {
width = 450,
height = 500,
numFrames = 40
}
local sheet_runningPeste =graphics.newImageSheet( “img/player.png”, sheetOptions)
–struttura dati per definire i frame da riprodurre
local seqs = {
{ name = “walk”,
start = 1,
count = 16,
time = 750,
loopCount = 0,
loopDirection = “forward”
}, {
name = “jump”,
start= 17,
count = 9,
time = 1500,
loopCount = 1,
loopDirection = “forward”
},{
name = “crouch”,
start= 26,
count = 11,
time=1200,
loopCount = 1,
loopDirection = “forward”
}}
–creo oggetto sprite
player = display.newSprite ( sheet_runningPeste, seqs)
player.x = display.contentCenterX-670
–player.y = display.contentHeight-300
player.offset=0
– imposto di default la sequenza walk
player:setSequence(“walk”)
player.isNotWalking = false
player.isJumping=false
player.isCrouching=false
player.isVisible = true
– aggiunta di un corpo fisico dinamico all’oggetto player
– la cui forma e’ esattamente il contorno dell’immagine spritePeste.png

	local frameOutline = player.frame
		local pesteOutline = graphics.newOutline(5, sheet_runningPeste, 1)
		physics.addBody(player,"dynamic",{outline=pesteOutline, bounce=0.0})

	player.isFixedRotation = true	-- Si impedisca che l'oggetto player ruoti
	player.myName = "player"

Here I tried to do it with object.frame saved in local frameOutline and giving tis variable as frameIndex for outline image sheet (https://docs.coronalabs.com/api/library/graphics/newOutline.html)

local frameOutline = player.frame
local pesteOutline = graphics.newOutline(5, sheet_runningPeste, frameOutline)

But it doesn’t work.
:confused:

Once you’ve created a physics body, you can’t update it like that. You’d need to destroy the existing body and recreate it again. However, in 2D games, the way how collision detection is typically handled is that there’s the “core body” that has a physics body and any moving arms and such aren’t a part of it.

1 Like

thank you!
i’m struggling because i nave enemies on the ground and in the air so my player jump and crouch to avoid collision. the problem is when it crouches it collides anyway cause the physics outline is fixed.

You can create multiple shapes for the player to detect collisions with.

Then just add conditional logic, for instance, if the player is crouching, then you’d ignore hits to the “standing up” body.

Or, alternatively, you could have a single dynamic physics body on the player, but you just add collision sensors to the player (and update their position in an enterFrame loop) and you create/destroy the sensors based on what key is held down, etc.

You just need to be careful with destroying non-sensor physics bodies for objects, because the moment that they are removed, the associated display object could start moving inside other objects.

1 Like

Many thanks!! I’ll try that later!
I’m working on another issue right now :frowning:

I used this code
local playerPieces = {
upbody = { 0,-0, -100,-0,-100,-200,0,-200, 130, -170, 130, -140, 10, -140, 30, 0, 0, 0 },
downbody = { 0,0,-100,-0,-100,200,0,200,60, 100, 60, 0 }
}
physics.addBody( player, “dynamic”,
{ shape = playerPieces[“upbody”] },
{ shape = playerPieces[“downbody”] }
)

And I think it may work BUT I have no idea how to ignore collision only for the upbody part :confused:

When you create your collision listener, you just need to add “player states” there.

For instance, if your player can crouch, then you could just check that if there is a collision with the player’s (standing body), then if the player is not crouching, then the player is hit.

1 Like

That worked! I feel dumb to not thinking about this easy solution! thank you

Sorry to bother you but there’s still a problem. In collision function yes it does ignore the collision but it “move” y player body anyway… I tried fix this with isBodyActive=false but is returned ERROR “display object property isBodyActive cannot be set cannot be called when the world is locked and in the middle of number crunching, such as during a collision event”

This is the collision event function

local function onPesteCollision(event)

--se la collisione avviene con la piattaforma rimuovi l'ascolatore
if (event.object1.myName=="platform" or event.object1.myName=="platform_next") or 
(event.object2.myName=="platform" or event.object2.myName=="platform_next")then
	self:removeEventListener("collision",onPesteCollision)
--se la collisione avviene con cloud e player si è abbassato rimuovi l'ascoltatore e disattiva il corpo fisico
elseif (event.object1.myName=="cloud" or event.object2.myName== "cloud") and player.isCrouching then
	
	self:removeEventListener("collision",onPesteCollision)
	cloud.isBodyActive = false	--disattivo il corpo fisico di player così la collisione con cloud
								--non causerà spostamenti dell'oggetto
--se la collisione avviene con le enemy esegui gameOver() e nascondi player
elseif (event.object1.myName=="mouse" or "teschio" or "cloud" or event.object2.myName=="mouse"or  "teschio" or "cloud") then
	
	if event.phase=="began" then
			--player:removeEventListener("touch",swipeEvent)
			player.isVisible=false
			gameover()
	end
	return true

end
	end

Runtime:addEventListener("collision",onPesteCollision)	

So how can I ignore collision event and also collision in generale between a dynamic and a static body?

You shouldn’t remove the collision listeners in there.

You can simply add a property, like object.whichBody = 1 and you’d use that to determine which body element should collide. In your collision listener, you’d use this: https://docs.coronalabs.com/tutorial/games/multiElementCollision/index.html#using-the-physics-contact to determine if the correct body element is colliding or not.

Also, you have a mistake in your conditional clauses there. For instance,
elseif (event.object1.myName=="mouse" or "teschio" or "cloud" or event.object2.myName=="mouse"or "teschio" or "cloud") then

You probably mean to say that if the name of the object is mouse, teschio or cloud, but that clause is interpreted as event.object1.myName=="mouse" or if “teschio” is not false or nil, or if “cloud” is not false or nil, and since they are strings, they will always be true.

You also shouldn’t remove event listeners during collision like that while the event is active.

And right, the way how you “ignore collisions” is by just checking if the colliding objects are what you want, like you are doing with the .myName property. In addition, you can add other properties to the objects to determine whether something should happen during collision, like that .whichBody property.

You could check on collision began phase if the object has whichBody property and if the property matches what you want, then you’d go into a conditional block.