Object moves with different speeds problem! Help!

So I have a problem and I will try my best to describe it.

Here is my code:

-- this function moves the player local function movePlayer( event ) local key = event.keyName if "down" == event.phase and paused == false then if key == "escape" then escGame() end if key == "d" then down = true done = false dirX = speed elseif key == "a" then down = true done = false dirX = -speed elseif key == "w" then down = true done = false dirY = -speed elseif key == "s" then down = true done = false dirY = speed end elseif event.phase == "up" then down = false done = false dirX = 0 dirY = 0 player.angularVelocity = 0 local vx, vy = player:getLinearVelocity() player:setLinearVelocity( 0, 0 ) end end Runtime:addEventListener( "key", movePlayer ) -- move player by applying linear impulses to it local function movePlayer2( event ) playerText.x = player.x playerText.y = player.y - player.height if down == true and done == false then -- move the player done = true print("DIRX : "..dirX.." DIRY : "..dirY.."") if dirX ~= 0 and dirY ~= 0 then dirX = dirX / 2 dirY = dirY / 2 end player:applyLinearImpulse( dirX, dirY, player.x, player.y ) end -- send update moves to other player --[[local move = { code = "playerUpdate", x = player.x, y = player.y, pID = pID } appWarpClient.sendUpdatePeers( json.encode( move ) ) playerx = player.x playery = player.y--]] end Runtime:addEventListener( "enterFrame", movePlayer2 )

and here is a video describing the problem:

https://www.youtube.com/watch?v=7vOIHNCUKJs&feature=youtu.be

I have variable “speed” which is 4. The player gets linear impulses. For example if the W button (on the keyboard) is pressed down the dirY = -speed and then it will start go up because it gets linear impulses. And same thing for all 4 directions.

But however there is a problem. When I press; for instance, W and after second D the character goes faster up. But if I manage to press W and D at the exact same time it goes slower.

So the player goes with constant speed up, down, left, and right, but does not go upright, upleft, updown, opleft.

In my code I tried to make it so that dirX and dirY would be smaller if 2 keys are pressed same time:

if dirX ~= 0 and dirY ~= 0 then dirX = dirX / 2 dirY = dirY / 2 end

But it only works if two buttons are pressed exactly the same time.

I hope that anyone could give me answer to this. Thank you a lot for your time.

I haven’t done a full follow-through of the logic, but my suspicion is that there’s a logic issue with the “done” and “down” variables, where somehow they’re not being set properly or reset properly.

I assume you’re trying to track “is there at least one key pressed”? If so, I would suggest scrapping all of these “done” and “down” variables, and using one “keyCounter” type of variable, above everything else. It starts at 0, then when they press any key, add 1 to it. Similarly, subtract 1 from it when a key is released. When this variable is 0, you know that no keys are being pressed, so you can stop the  “enterFrame” movement temporarily… and of course if this value is at least 1, you start the function running again.

Also, I see potential conflict in your key “phase” handling with physics. Upon any key being released (“up” phase), you’re setting the player’s linear velocity to 0… that means you lose every bit of physical momentum in both directions. I’m not sure what your game is supposed to behave like, but you should probably only set one direction’s velocity to 0, depending on which key was released… for example, if they release the W or S key, then set vertical velocity to 0, but keep horizontal velocity the same (because they might be still pressing A or D).

Finally, that “appWarpClient.sendUpdatePeers()” call is very concerning, where you’ve placed it. That will literally run up to 60 times per second as the player moves around. I don’t know what AppWarp is doing with that call, but if it’s network-related (and it seems likely it is, if it’s sending an update), that will literally make a massive stack of network requests and potentially explode your game all over the place.

Hope this helps,

Brent

Warning: This will just sound like me complaining, but I’m really trying to help and there is a payoff at the end.

Tip 1:  You won’t get any more assistance by putting ‘Help!’ in your title.  In fact, some of us immediately mark titles like that as ‘ignore’.  (Just cranky guys like me, not the staff.  Brent, Rob and the rest are awesome.)

You’d be better served making the title a short but clear description of the issue or question.

Tip 2: Thanks so much for posting your code in a code block, but in the future please put a little more effort into making it legible.  I’m talking specifically about the unnecessary indentation that is causing the block to wrap needlessly, thus making it a pain to read.

I know it’s an extra step for you, but you will get more and better help the easier your posts are to consume and grok.

The payoff:

  1. If you want the player to keep moving, impulses are NOT the way to go here.  setting linear velocity is better

  2. I think you’ve got errors in your key listener.  Will correct below.

  3. I suggest using table listeners instead of function listeners.

  4. It looks like you want your diagonal rates to be the same as your horizontal and vertical rates, but you have the calculation a little wrong.

You need to multiply vx and vy by sqrt(2)/2 not just divide by 2.

  1. In my sample below I removed your appwarp code.

  2. This code is quite different from  yours so I suggest making a copy of yours in case you don’t end up using this.  Also this may have syntax errors in it as I didn’t run it.

    – Start off NOT moving player._mx = 0 player._my = 0 – Used to equalize diagonal velocities (used in enterFrame listener below) local speedAdjust = math.sqrt(2)/2 – Better: Add ‘key’ table-style listener directly to player – function player.key( self, event ) local key = event.keyName – I assume you don’t want to do anything while paused? if( paused ) then return end if( event.phase == “down” ) then if( key == “w” ) then self._my = self._my - 1 elseif( key == “s” ) then self._my = self._my + 1 elseif( key == “a” ) then self._my = self._mx - 1 elseif( key == “d” ) then self._my = self._mx + 1 elseif ( key == “escape”) then escGame() end else if( key == “w” ) then self._my = self._my + 1 elseif( key == “s” ) then self._my = self._my 1 1 elseif( key == “a” ) then self._my = self._mx + 1 elseif( key == “d” ) then self._my = self._mx - 1 end player.angularVelocity = 0 end end – Better: Add ‘enterFrame’ table-style listener directly to player – function player.enterFrame( self ) – Trick: Catch errors where you’ve somehow accumulatd too many moves in a specific direction – if( math.abs(self._mx) > 1 ) then self._mx = (mx < 0) and -1 or 1 end if( math.abs(self._my) > 1 ) then self._my = (self._my < 0) and -1 or 1 end – Calculate vx, vy local vx = self._mx * speed local vy = self._my * speed – Ensure equal velocity in all directions: up, down, left, right, and along diagonals if( vx ~= 0 and vy ~= 0 ) then vx = vx * speedAdjust vy = vy * speedAdjust end self:setLinearVelocity( vx, vy ) --print( vx, vy ) end – Add the listeners (notice change in syntax) – Runtime:addEventListener( “key”, player ) Runtime:addEventListener( “enterFrame”, player ) – -- Tip: Later listeners can be removed like this: – -- Runtime:removeEventListener( “key”, player ) – Runtime:removeEventListener( “enterFrame”, player ) –

Hey I forgot to say.  It was also awesome you attached a video.  

I hope the code above helps.

Thanks a lot for answering! Programminggamer I will try that what you wrote me, and in the future if I have questions here I’ll make them more clear to read.

Brent Sorrentino, you reminded me about the appwarp update thingie.

Yes it is for server & multiplayer realtime purposes. I know that it sends alot of updates in second but if I drop it down to like 10? 20? per second it will get even More buggier. That update thing is for sending the player’s cordinates to his/hers opponents.

Is there a better way to send and receive player cordinate updates? I would like to know.

Anyways thank you very much for answering.

Oh, and yes, Roaminggamer, I want the speed to be constant in all directions (e.g. left, right, diagonal)

Thank you :)!

Thanks alot! It works!!

I haven’t done a full follow-through of the logic, but my suspicion is that there’s a logic issue with the “done” and “down” variables, where somehow they’re not being set properly or reset properly.

I assume you’re trying to track “is there at least one key pressed”? If so, I would suggest scrapping all of these “done” and “down” variables, and using one “keyCounter” type of variable, above everything else. It starts at 0, then when they press any key, add 1 to it. Similarly, subtract 1 from it when a key is released. When this variable is 0, you know that no keys are being pressed, so you can stop the  “enterFrame” movement temporarily… and of course if this value is at least 1, you start the function running again.

Also, I see potential conflict in your key “phase” handling with physics. Upon any key being released (“up” phase), you’re setting the player’s linear velocity to 0… that means you lose every bit of physical momentum in both directions. I’m not sure what your game is supposed to behave like, but you should probably only set one direction’s velocity to 0, depending on which key was released… for example, if they release the W or S key, then set vertical velocity to 0, but keep horizontal velocity the same (because they might be still pressing A or D).

Finally, that “appWarpClient.sendUpdatePeers()” call is very concerning, where you’ve placed it. That will literally run up to 60 times per second as the player moves around. I don’t know what AppWarp is doing with that call, but if it’s network-related (and it seems likely it is, if it’s sending an update), that will literally make a massive stack of network requests and potentially explode your game all over the place.

Hope this helps,

Brent

Warning: This will just sound like me complaining, but I’m really trying to help and there is a payoff at the end.

Tip 1:  You won’t get any more assistance by putting ‘Help!’ in your title.  In fact, some of us immediately mark titles like that as ‘ignore’.  (Just cranky guys like me, not the staff.  Brent, Rob and the rest are awesome.)

You’d be better served making the title a short but clear description of the issue or question.

Tip 2: Thanks so much for posting your code in a code block, but in the future please put a little more effort into making it legible.  I’m talking specifically about the unnecessary indentation that is causing the block to wrap needlessly, thus making it a pain to read.

I know it’s an extra step for you, but you will get more and better help the easier your posts are to consume and grok.

The payoff:

  1. If you want the player to keep moving, impulses are NOT the way to go here.  setting linear velocity is better

  2. I think you’ve got errors in your key listener.  Will correct below.

  3. I suggest using table listeners instead of function listeners.

  4. It looks like you want your diagonal rates to be the same as your horizontal and vertical rates, but you have the calculation a little wrong.

You need to multiply vx and vy by sqrt(2)/2 not just divide by 2.

  1. In my sample below I removed your appwarp code.

  2. This code is quite different from  yours so I suggest making a copy of yours in case you don’t end up using this.  Also this may have syntax errors in it as I didn’t run it.

    – Start off NOT moving player._mx = 0 player._my = 0 – Used to equalize diagonal velocities (used in enterFrame listener below) local speedAdjust = math.sqrt(2)/2 – Better: Add ‘key’ table-style listener directly to player – function player.key( self, event ) local key = event.keyName – I assume you don’t want to do anything while paused? if( paused ) then return end if( event.phase == “down” ) then if( key == “w” ) then self._my = self._my - 1 elseif( key == “s” ) then self._my = self._my + 1 elseif( key == “a” ) then self._my = self._mx - 1 elseif( key == “d” ) then self._my = self._mx + 1 elseif ( key == “escape”) then escGame() end else if( key == “w” ) then self._my = self._my + 1 elseif( key == “s” ) then self._my = self._my 1 1 elseif( key == “a” ) then self._my = self._mx + 1 elseif( key == “d” ) then self._my = self._mx - 1 end player.angularVelocity = 0 end end – Better: Add ‘enterFrame’ table-style listener directly to player – function player.enterFrame( self ) – Trick: Catch errors where you’ve somehow accumulatd too many moves in a specific direction – if( math.abs(self._mx) > 1 ) then self._mx = (mx < 0) and -1 or 1 end if( math.abs(self._my) > 1 ) then self._my = (self._my < 0) and -1 or 1 end – Calculate vx, vy local vx = self._mx * speed local vy = self._my * speed – Ensure equal velocity in all directions: up, down, left, right, and along diagonals if( vx ~= 0 and vy ~= 0 ) then vx = vx * speedAdjust vy = vy * speedAdjust end self:setLinearVelocity( vx, vy ) --print( vx, vy ) end – Add the listeners (notice change in syntax) – Runtime:addEventListener( “key”, player ) Runtime:addEventListener( “enterFrame”, player ) – -- Tip: Later listeners can be removed like this: – -- Runtime:removeEventListener( “key”, player ) – Runtime:removeEventListener( “enterFrame”, player ) –

Hey I forgot to say.  It was also awesome you attached a video.  

I hope the code above helps.

Thanks a lot for answering! Programminggamer I will try that what you wrote me, and in the future if I have questions here I’ll make them more clear to read.

Brent Sorrentino, you reminded me about the appwarp update thingie.

Yes it is for server & multiplayer realtime purposes. I know that it sends alot of updates in second but if I drop it down to like 10? 20? per second it will get even More buggier. That update thing is for sending the player’s cordinates to his/hers opponents.

Is there a better way to send and receive player cordinate updates? I would like to know.

Anyways thank you very much for answering.

Oh, and yes, Roaminggamer, I want the speed to be constant in all directions (e.g. left, right, diagonal)

Thank you :)!

Thanks alot! It works!!