Enemies get stuck after moving sometime im moving them with constant speed using linear velocity and apply force

Enemies get stuck after moving sometime im moving them with constant speed using linear velocity and apply force

here is my code for enemies 

main movement code is in enterFrame function

Please help

-- tiled Plugin template -- Use this as a template to extend a tiled object with functionality local M = {} function M.new(instance) if not instance then error("ERROR: Expected display object") end local left=-1 local right = 0 local accleration = 2000 local dx = 0 local max=50 --stores initial values instance.isVisible = false local parent = instance.parent local x, y = instance.x, instance.y --initialize instance local sheetInfo = require("character.zombie\_male") local myImageSheet = graphics.newImageSheet( "character/zombie\_male.png", sheetInfo:getSheet() ) instance= display.newSprite(parent, myImageSheet ,sheetInfo.sequenceData) instance.x=x instance.y=y physics.addBody(instance ,{bounce=0.0,friction=1.0,density=3}) instance.isFixedRotation=true instance.xScale=-1 instance:setSequence("walk") instance:play() --camera offset stepping function within map local function enterFrame() if instance and instance.x and instance.y and not instance.isDead then local dir=left+right dx=dir\*accleration vx,vy=instance:getLinearVelocity() instance:setLinearVelocity(dir\*max,vy) instance:applyForce(dx or 0,0,instance.x,instance.y) end end function instance:collision(event) local other=event.other local phase = event.phase if phase=="began" then if other.type~="bricks" and other.type~="hero" then instance:setSequence("walk") instance:play() if right==1 then right=0 left=-1 instance.xScale=-1 else right=1 left=0 instance.xScale=1 end end elseif phase=="end" then end end --add listeners instance:addEventListener("collision") Runtime:addEventListener( "enterFrame", enterFrame ) instance.name="zombie\_male" instance.type="zombie\_male" return instance end return M

Hi @kudchikarsk,

With a quick overview, it seems that if you’re using this module to create several instances of zombies, you should be attaching properties like “left” and “right” to the zombie object itself (“instance”). What likely occuring now is that it’s not properly associating those values with each individual instance you’re creating, but rather with the module as a whole, which doesn’t apply to every instance of zombie as you create more than one.

So instead of what you’re doing, I’d suggest more like this:

[lua]

instance.left = -1

instance.right = 0

instance.accleration = 2000

instance.dx = 0

instance.max = 50

[/lua]

And…

[lua]

local function enterFrame()

   if instance and instance.x and instance.y and not instance.isDead then

      local dir = instance.left + instance.right

      instance.dx = dir * instance.accleration

[/lua]

And…

[lua]

if instance.right == 1 then

   instance.right = 0

   instance.left = -1

   instance.xScale = -1

[/lua]

There are a few other places to substitute this concept in, easy enough to locate.

Also, you shouldn’t be applying both linear velocity and force to the same object. They’re somewhat different physical behaviors that might not play nicely together.

See what happens with this approach and post back please.

Brent

still not working here is my updated code

-- tiled Plugin template -- Use this as a template to extend a tiled object with functionality local M = {} function M.new(instance) if not instance then error("ERROR: Expected display object") end --stores initial values instance.isVisible = false local parent = instance.parent local x, y = instance.x, instance.y --initialize instance local sheetInfo = require("character.zombie\_male") local myImageSheet = graphics.newImageSheet( "character/zombie\_male.png", sheetInfo:getSheet() ) instance= display.newSprite(parent, myImageSheet ,sheetInfo.sequenceData) instance.x=x instance.y=y instance.left=-1 instance.right = 0 instance.dx = 0 instance.accleration = 1000 instance.max=80 physics.addBody(instance ,{bounce=0.0,friction=1.0,density=3}) instance.isFixedRotation=true instance.xScale=-1 instance:setSequence("walk") instance:play() --camera offset stepping function within map local function enterFrame() if instance and instance.x and instance.y and not instance.isDead and instance.left and instance.right and instance.dx then local dir=instance.left+instance.right instance.dx=dir\*instance.accleration vx,vy=instance:getLinearVelocity() instance:setLinearVelocity(dir\*instance.max,vy) instance:applyForce(instance.dx or 0,0,instance.x,instance.y) end end function instance:collision(event) local other=event.other local phase = event.phase if phase=="began" then if other.type~="bricks" and other.type~="hero" then instance:setSequence("walk") instance:play() if instance.right==1 then instance.right=0 instance.left=-1 instance.xScale=-1 else instance.right=1 instance.left=0 instance.xScale=1 end end elseif phase=="end" then end end --add listeners instance:addEventListener("collision") Runtime:addEventListener( "enterFrame", enterFrame ) instance.name="zombie\_male" instance.type="zombie\_male" return instance end return M

Still waiting for solutions guys and idea for solution?

Hi @kudchikarsk,

Upon looking closer, I think you can eliminate the “enterFrame” listener entirely. Instead, just roll some of that code directly into the collision handling function. Basically:

  1. When a zombie collides, check its current velocity with “instance:getLinearVelocity()”.

  2. If it’s going right (vx>0), turn the zombie around by setting its velocity to the other way (left). If it’s going left (vx<0), turn it right.

In that case, you could get rid of several instance-related properties like “.left”, “.right”, “.dx”, “.accleration”, etc.

Brent

Unless each instance uses a separate metaTable then each instance will just be a copy of the other.  So if you have 10 instances and you say instance.x=10 then all instances will be at x=10.

This doc might explain things (not sure if will help)

Hi @kudchikarsk,

With a quick overview, it seems that if you’re using this module to create several instances of zombies, you should be attaching properties like “left” and “right” to the zombie object itself (“instance”). What likely occuring now is that it’s not properly associating those values with each individual instance you’re creating, but rather with the module as a whole, which doesn’t apply to every instance of zombie as you create more than one.

So instead of what you’re doing, I’d suggest more like this:

[lua]

instance.left = -1

instance.right = 0

instance.accleration = 2000

instance.dx = 0

instance.max = 50

[/lua]

And…

[lua]

local function enterFrame()

   if instance and instance.x and instance.y and not instance.isDead then

      local dir = instance.left + instance.right

      instance.dx = dir * instance.accleration

[/lua]

And…

[lua]

if instance.right == 1 then

   instance.right = 0

   instance.left = -1

   instance.xScale = -1

[/lua]

There are a few other places to substitute this concept in, easy enough to locate.

Also, you shouldn’t be applying both linear velocity and force to the same object. They’re somewhat different physical behaviors that might not play nicely together.

See what happens with this approach and post back please.

Brent

still not working here is my updated code

-- tiled Plugin template -- Use this as a template to extend a tiled object with functionality local M = {} function M.new(instance) if not instance then error("ERROR: Expected display object") end --stores initial values instance.isVisible = false local parent = instance.parent local x, y = instance.x, instance.y --initialize instance local sheetInfo = require("character.zombie\_male") local myImageSheet = graphics.newImageSheet( "character/zombie\_male.png", sheetInfo:getSheet() ) instance= display.newSprite(parent, myImageSheet ,sheetInfo.sequenceData) instance.x=x instance.y=y instance.left=-1 instance.right = 0 instance.dx = 0 instance.accleration = 1000 instance.max=80 physics.addBody(instance ,{bounce=0.0,friction=1.0,density=3}) instance.isFixedRotation=true instance.xScale=-1 instance:setSequence("walk") instance:play() --camera offset stepping function within map local function enterFrame() if instance and instance.x and instance.y and not instance.isDead and instance.left and instance.right and instance.dx then local dir=instance.left+instance.right instance.dx=dir\*instance.accleration vx,vy=instance:getLinearVelocity() instance:setLinearVelocity(dir\*instance.max,vy) instance:applyForce(instance.dx or 0,0,instance.x,instance.y) end end function instance:collision(event) local other=event.other local phase = event.phase if phase=="began" then if other.type~="bricks" and other.type~="hero" then instance:setSequence("walk") instance:play() if instance.right==1 then instance.right=0 instance.left=-1 instance.xScale=-1 else instance.right=1 instance.left=0 instance.xScale=1 end end elseif phase=="end" then end end --add listeners instance:addEventListener("collision") Runtime:addEventListener( "enterFrame", enterFrame ) instance.name="zombie\_male" instance.type="zombie\_male" return instance end return M

Still waiting for solutions guys and idea for solution?

Hi @kudchikarsk,

Upon looking closer, I think you can eliminate the “enterFrame” listener entirely. Instead, just roll some of that code directly into the collision handling function. Basically:

  1. When a zombie collides, check its current velocity with “instance:getLinearVelocity()”.

  2. If it’s going right (vx>0), turn the zombie around by setting its velocity to the other way (left). If it’s going left (vx<0), turn it right.

In that case, you could get rid of several instance-related properties like “.left”, “.right”, “.dx”, “.accleration”, etc.

Brent

Unless each instance uses a separate metaTable then each instance will just be a copy of the other.  So if you have 10 instances and you say instance.x=10 then all instances will be at x=10.

This doc might explain things (not sure if will help)