Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Moving with setPosition, MovieClip and bump. - Gideros Forum

Moving with setPosition, MovieClip and bump.

Hello again!

So I'm about to add some movement to the NPCs in my game. They have bump bodies but, the way I have been moving my player, for example, is by doing:
player:setPosition(x+1, y)
world:move(player, x+1, y)
... Inside onEnterFrame().

But I feel that I shouldn't have decoupled movement like that. My question is, would I be better off doing something like creating a physics body, then adding the player table to that? That way, when the body moves in world:move(), the player class is dragged around too?

Or does bump handle that automatically now? Like, it moves the bitmap and not just the physics body? And so if I did player:getX() it would accurately reflect where the player is, without ever having explicitly used setPosition()?

I'm not really sure that would work but one thing I am sure of; I've gone and confused myself again. :blush:


  • antixantix Member
    Accepted Answer
    @Astirian that's the only way to do it (moving the NPC with setPosition() and then moving it's collision rect with move()).

    If you look at Box2d you will see that even though the physics objects move about and collide in the simulation.. you still have to extract their world position and use setPosition() on the sprite that represents that object on the display anyway :)

    Likes: Astirian

    +1 -1 (+1 / -0 ) Share on Facebook
  • AstirianAstirian Member
    Thanks @Antix, but does that then mean that given a destination, I need to manage the speed of the NPC somehow outside of bump:move()?

    I could use MovieClip to move the NPC and give him a time based on distance but then his physics body won't move. The only other options I can think of, is to either base it on a vector line (ew?) or use delta time:

    1. Get the co-ords along a line to the destination and in each update() increment the x and y values based on points on a line, that seems terribly messy.


    2. Use speed and delta time, I'm still trying to get head head around this but I've seen code snippets with it before and it feels more correct in terms of game coding patterns.

    In terms of the latter, it looks like people usually do something like this in the frame update method:

    player_speed = 60
    player.y = player.y - player_speed * dt
    player.x = player.x - player_speed * dt

    Then invoke bump:move() with the new x and y coords. I need to understand per frame events more I think, but it looks to me like in this example, the player would move 60 "units" per frame. (I guess the dt is related to different processing speeds per device etc...)

    The 60 can be anything I suppose, but I keep seeing FPS! :smiley:


    Update: OK, I started this post this morning and thought maybe I've answered my own question... Buuut, I'm having really weird effects with this code snippet I discovered. It's close I feel but it's also completely nutso:
    function npc:move(dt)
    	local speed = 6000; -- I've used all sorts here, from 0.5 to 60 to 6000.
    	self.x = self.directionX * speed * dt;
            self.y = self.directionY * speed * dt;
    	print("Yo, Ima go to here now: ", self.x, self.y)
            if (math.sqrt(math.pow(self.x - self.startX, 2) + math.pow(self.y - self.startY, 2)) >= self.distance) then
                self.x = self.endX;
                self.y = self.endY;
                self.state = "ready"
    	if self.x ~= nil and self.y ~= nil then
    	    self:setPosition(self.x, self.y);
    Anyway, the end result is, the enemy teleports straight to the player and then goes bananas... My maths skills are horrible so I'm not quite sure why this is failing. The co-ords I'm spitting out in my print look reasonable enough...
  • hgy29hgy29 Maintainer
    @Astirian, the idea is to first check for collision with bump, and use the resulting actualX and actualY to update your sprite's position.
    	local targetX = self.directionX * speed * dt;
            local targetY = self.directionY * speed * dt;
    	local actualX, actualY, cols, len = world:move(npc, targetX,targetY,colfilter)
    Do something like that each frame and you won't need a movieclip or anything.

  • rrraptorrrraptor Member
    edited May 6 Accepted Answer
    Astirian said:

    the player would move 60 "units" per frame.

    The player would move 60 pixels per second. Without using dt, it would move 60 pixels per frame.

    Also, take a look on a Vectors. They are pretty useful ;) Here is a playlist on youtube where you can find some info about this (search for "Character Movement" videos), and many other things.

    Likes: Astirian, Apollo14

    +1 -1 (+2 / -0 ) Share on Facebook
  • antixantix Member
    edited May 6 Accepted Answer
    @Astirian.. @rrraptor is correct.. use vectors :)
    -- create player object
    local player = Pixel.new(0x44cc88, 1, 32, 32)
    player:setAnchorPoint(0.5, 0.5)
    player.position = {x = 160, y = 240}
    player.velocity = {x = 0, y = 0}
    -- set player moving in direction (0 - 360 degrees) at speed (pixels per second)
    local function setPlayerSpeedDirection(speed, direction)
      local sin, cos, rad = math.sin, math.cos, math.rad
      local v = player.velocity
      local vx = speed * cos(rad(direction - 90))
      local vy = speed * sin(rad(direction - 90))
      v.x, v.y = vx, vy  
    setPlayerSpeedDirection(60, 90)
    -- update every frame
    local function onEnterFrame(e)
      -- time elapsed (in seconds) since last enterframe event
      local dt = e.deltaTime
      -- get position and velocity
      local p = player.position
      local v = player.velocity
      -- get desired position
      local px = p.x + v.x * dt
      local py = p.y + v.y * dt
      -- get actual position (after collision has been accounted for)
      local ax, ay, cols, len = bump:move(player, px, py)
      -- save updated position
      p.x, p.y = ax, ay
      -- set player in actual position
      player:setPosition(ax, ay)
    stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)
    Vectors.. just use them ;)

    Likes: Astirian

    +1 -1 (+1 / -0 ) Share on Facebook
  • antixantix Member
    As a side note.. I tried to use the new fast trig instructions in my example above (^>) but then the code is truncated when reading in the forum.. is there a way to make the code block able to use those???
  • AstirianAstirian Member
    Thanks guys! Looks like vectors it is then, time to brush up on my maths skills as well. :) Those videos look invaluable @rrraptor
Sign In or Register to comment.