Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Calculating new position based on movement speed along an angle?

edited May 28 in Questions Posts: 117

so I wanted to make the simplest thing I could think of before I went to sleep. 1 hour later, here it is, a ship jumping from the yellow star to the red star. Every turn, it moves at a speed of 50.

Problem is, I calculate the angle and distance, but I don't know how to actually use that information. I wanted the ship to go in a straight line in this example, dividing the movement along the two axes so the total distance it travels each turn would be 50. Instead it's traveling at the square root of 50^2*2...

-- Starship Jump

-- Use this function to perform your initial setup
function setup()
    print("Hello World!")

    home = {x = 312, y = 149}
    home.mesh = mesh()
    home.mesh.texture = readImage("Planet Cute:Star")
    home.mesh:addRect(0,0,32,32)
    home.mesh:setRectTex(1,0,0,1,1)
    enemy = {x = 293, y = 516}
    enemy.mesh = mesh()
    enemy.mesh.texture = readImage("Planet Cute:Star")
    enemy.mesh:addRect(0,0,32,32)
    enemy.mesh:setRectTex(1,0,0,1,1)
    enemy.mesh:setRectColor(1, color(155,0,0))
    function star(v)
        pushMatrix()
        translate(v.x, v.y)
        v.mesh:draw()
        popMatrix()
    end


    ship = {}
    ship.x = home.x 
    ship.y = home.y
    ship.from = home
    ship.destination = enemy
    ship.speed = 50 -- 1 lightyear = 50 pixels
    ship.mesh = mesh()
    ship.mesh:addRect(0,0,16,32)
    ship.mesh.texture = readImage("Space Art:Part Green Hull 1")
    ship.mesh:setRectTex(1, 0,0,1,1)
    function ship:draw()
        if self.destination then

                stroke(0,155,0)
                line(self.x, self.y, self.destination.x, self.destination.y)

        end
        pushMatrix()
        translate(self.x, self.y)
        self.mesh:draw()
        popMatrix()
    end

    function ship:updatePosition()
        local v1 = vec2(self.destination.x, self.destination.y)
        local v2 = vec2(self.x, self.y)
        local dist = v1:dist(v2)
        local angle = v1:angleBetween(v2)
        -- move along angle to destination
        -- i dont know how to calculate this properly
        if self.x < v1.x then
        self.x = self.x + self.speed 
        elseif self.x > v1.x then
        self.x = self.x - self.speed
        end

        if self.y < v1.y then
        self.y = self.y + self.speed
        elseif self.y > v1.y then
        self.y = self.y - self.speed
        end
        print("Current distance from destination: "..dist)

    end

    turn = {}
    turn.x = WIDTH-220
    turn.y = HEIGHT-150
    turn.w = 150
    turn.h = 100
    turn.active = false
    turn.mesh = mesh()
    turn.mesh2 = mesh()
    turn.mesh.texture = readImage("Cargo Bot:Fast Button Inactive")
    turn.mesh2.texture = readImage("Cargo Bot:Fast Button Active")
    turn.mesh:addRect(turn.w/2,turn.h/2,turn.w, turn.h)
    turn.mesh2:addRect(turn.w/2,turn.h/2,turn.w, turn.h)
    turn.mesh:setRectTex(1,0,0,1,1)
    turn.mesh2:setRectTex(1,0,0,1,1)
    turn.startedTouch = false
    function turn:draw()
        pushMatrix()
        translate(self.x, self.y)
        if turn.active then
            self.mesh2:draw()
        else
            self.mesh:draw()
        end
        popMatrix()
    end
    function turn:touched(t)
        if t.state == BEGAN then
            if t.x > self.x and t.x < self.x + self.w
            and t.y > self.y and t.y < self.y + self.h
            then
                self.active = true
            end
        elseif t.state == ENDED then
            if t.x > self.x and t.x < self.x + self.w
            and t.y > self.y and t.y < self.y + self.h
            then
                if self.active then 
                    self.active = false
                    ship:updatePosition()
                end
            else
                self.active = false
            end
        end
    end
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(0, 0, 0, 255)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    star(home)
    star(enemy)
    ship:draw()
    turn:draw()
end

function touched(touch)
    turn:touched(touch)
end

Comments

  • dave1707dave1707 Mod
    Posts: 6,929

    @xThomas You can use the vector command normalize. It always calculates a distance of 1 between the 2 points. Then by using the x and y value from normalize and multiplying them by a speed, you always have the same speed going from one point to the other. Here’s a simple example of using normalize.

    function setup()
        p1=vec2(100,100)
        p2=vec2(400,600)
        p0=p1
        dx,dy=0,0
        v1=vec2(0,0)
        speed=5
    end
    
    function draw()
        background(0)
        fill(255)
        text("tap screen to start",WIDTH/2,HEIGHT-100)
        fill(255,0,0)
        ellipse(p1.x,p1.y,10)
        ellipse(p2.x,p2.y,10)
        fill(0,255,0)
        p0=p0+v1
        ellipse(p0.x+v1.x,p0.y+v1.y,10)
        dx=math.abs(p0.x-p2.x)
        dy=math.abs(p0.y-p2.y)
        if dx<3 and dy<3 then
            v1=vec2(0,0)
        end
    end
    
    function touched(t)
        if t.state==BEGAN then
            v1=p2-p1
            v1=v1:normalize()*speed
        end
    end
    
  • Posts: 117

    Thank you!


    -- Starship Jump -- Use this function to perform your initial setup function setup() print("Hello World!") home = {x = 312, y = 149} home.mesh = mesh() home.mesh.texture = readImage("Planet Cute:Star") home.mesh:addRect(0,0,32,32) home.mesh:setRectTex(1,0,0,1,1) enemy = {x = 293, y = 516} enemy.mesh = mesh() enemy.mesh.texture = readImage("Planet Cute:Star") enemy.mesh:addRect(0,0,32,32) enemy.mesh:setRectTex(1,0,0,1,1) enemy.mesh:setRectColor(1, color(155,0,0)) function star(v) pushMatrix() translate(v.x, v.y) v.mesh:draw() popMatrix() end ship = {} ship.from = enemy ship.destination = home ship.position = vec2(ship.from.x, ship.from.y) ship.speed = 50 -- 1 lightyear = 50 pixels ship.mesh = mesh() ship.mesh:addRect(0,0,16,32) ship.mesh.texture = readImage("Space Art:Part Green Hull 1") ship.mesh:setRectTex(1, 0,0,1,1) function ship:draw() if self.destination then stroke(0,155,0) line(self.position.x, self.position.y, self.destination.x, self.destination.y) end pushMatrix() translate(self.position.x, self.position.y) self.mesh:draw() popMatrix() end function ship:updatePosition() local v1 = vec2(self.destination.x, self.destination.y) local v2 = vec2(self.position.x, self.position.y) local v3 = v1-v2 v3 = v3:normalize()*self.speed self.position = self.position+v3 -- print("Current distance from destination: "..dist) end turn = {} turn.x = WIDTH-220 turn.y = HEIGHT-150 turn.w = 150 turn.h = 100 turn.active = false turn.mesh = mesh() turn.mesh2 = mesh() turn.mesh.texture = readImage("Cargo Bot:Fast Button Inactive") turn.mesh2.texture = readImage("Cargo Bot:Fast Button Active") turn.mesh:addRect(turn.w/2,turn.h/2,turn.w, turn.h) turn.mesh2:addRect(turn.w/2,turn.h/2,turn.w, turn.h) turn.mesh:setRectTex(1,0,0,1,1) turn.mesh2:setRectTex(1,0,0,1,1) turn.startedTouch = false function turn:draw() pushMatrix() translate(self.x, self.y) if turn.active then self.mesh2:draw() else self.mesh:draw() end popMatrix() end function turn:touched(t) if t.state == BEGAN then if t.x > self.x and t.x < self.x + self.w and t.y > self.y and t.y < self.y + self.h then self.active = true end elseif t.state == ENDED then if t.x > self.x and t.x < self.x + self.w and t.y > self.y and t.y < self.y + self.h then if self.active then self.active = false ship:updatePosition() end else self.active = false end end end end -- This function gets called once every frame function draw() -- This sets a dark background color background(0, 0, 0, 255) -- This sets the line thickness strokeWidth(5) -- Do your drawing here star(home) star(enemy) ship:draw() turn:draw() end function touched(touch) turn:touched(touch) end
Sign In or Register to comment.