FAQ  •  Register  •  Login

Velocity levelgens

<<

tazinator

Posts: 351

Joined: Fri Jul 05, 2013 7:35 pm

Post Wed Mar 26, 2014 1:55 am

Velocity levelgens

if you want to try it, stick the big code in a level. It's nowhere near complete though.

This single line is working a bit differently from intended. Leaving aside that it isn't finished, I can't even figure this out.
1. + 100 was expected to simply increase the velocity in any direction
2. +100 instead moves the velocity to the right of the map

  Code:
    ship:setVel(point.new((vel.x + 100), (vel.y + 100)))


After getting that working, I want to set a maximum velocity. ergo, the code stops running if a ship reaches this speed and waits until the ship reaches normal speeds.
  Code:
function main()
    burst = Burst.new
--Timer:scheduleRepeating(bursttest, 100)
bf:subscribe(Event.Tick)

end
function onTick(delta)

--function bursttest()

    local players = bf:getGameInfo():getPlayers();
    for i,player in ipairs(players) do
        local ship = player:getShip();
    local vel = ship:getVel();
    --if(shipEnteredzone) then
    ship:setVel(point.new((vel.x + 100), (vel.y + 100)))
    end
end
Play my new level! Two different teams fight over a nexus: One mainly defends while the other attacks! is fun
viewtopic.php?f=33&p=21002#p21002
<<

tazinator

Posts: 351

Joined: Fri Jul 05, 2013 7:35 pm

Post Wed Mar 26, 2014 5:59 pm

Re: Velocity levelgens

OK I think I got the theory of this down

Goal
Create a levelgen which edits velocity of ships, such that it takes a while to slow down or turn around.

Previously learned lesson
trying to simply multiply a ship's velocity every tick can easily fail and is jerky. It's not cool. Also, when adding to any velocity, positive numbers are counted along an axis.

Hypothesis
If I capture a ship's velocity from Tick x, (a) and then capture the velocity from Tick y (z) (the next tick), then I can use the difference to determine if a ship is slowing down or speeding up. Therefore, special formula can modify the ship velocity better simply by multiplying or dividing the difference between each tick.

Code skeleton
  Code:
--Levelgen by Thomas of Hilo
--also known as tazinator
--Changes ship velocities

function main()
    subscribe(Event.Tick);
onEven = true -- starts the onEven tick
oddVel = (0, 0) -- so the first time I do evenVel - oddVel, I don't subtract a nil value
end
function onTick()
bf:findAllObjects(items, ObjType.Ship)
  local players = bf:getGameInfo():getPlayers();
    for i,player in ipairs(players) do
        local ship = player:getShip();
    end
end

function onEven()
evenVel = ship:getVel()

-- local evensChange
-- evenVel.x - oddVel.x
-- evenVel.y - oddVel.y
-- ship:setVel(evensChange)

onOdd = true --the next tick will run the function onOdd if i did this right
onEven = false --so I don't change the evenVel value on the next tick
    end

function onOdd()

oddVel = ship:getVel()

-- local oddsChange
-- oddVel.x - evenVel.x
-- oddVel.y - evenVel.y
-- ship:setVel(oddsChange)
onOdd = false
onEven = true

    end
Play my new level! Two different teams fight over a nexus: One mainly defends while the other attacks! is fun
viewtopic.php?f=33&p=21002#p21002
<<

Fordcars

User avatar

Posts: 983

Joined: Fri Apr 20, 2012 3:51 pm

Location: Some city, somewhere

Post Wed Mar 26, 2014 8:33 pm

Re: Velocity levelgens

Looks good so far!

I would detect if a ship is speeding up or slowing down by checking the current and last tick, similar to what you wrote. You could just declare a variable in the main():

  Code:
function main()
    lastVelocity = nil
end


'nil' means 'nothing'. You could probably remove the nil, but I am not sure you can declare a variable like this.

Then at each tick, you could compare the last velocity with the current one. But watch out! The first time the onTick() runs, you won't have a 'last velocity', so you can just setup another variable in main() to check if this is the first onTick():

  Code:
firstTick = true


Then, in onTick(), you can just set that variable to false when it runs for the first time:

  Code:
function onTick()
    -- Get ship here

    if(firstTick==true) then
        firstTick = false -- Set the variable to false, like that the if will not run again
        lastVelocity = ship:getVel() -- Put the ship's velocity in the variable
        return -- Get out of the function, so nothing else of that function is ran this time
    end
end


Then, in onTick(), under the 'if', you can compare both velocities:
  Code:
local shipVelocityNumber = convertToPositive(ship:getVel().x) + convertToPositive(ship:getVel().y) -- Make sure number is positive

local lastVelocityNumber =convertToPositive(lastVelocity.x) + convertToPositive(lastVelocity.y) -- Make sure number is positive

if(shipVelocityNumber<lastVelocityNumber) then
    -- Slowing down!
elseif(shipVelocityNumber>lastVelocityNumber) then
    -- Speeding up
else
    -- Same speed!
end


The problem is: velocity x and y are sometimes negative, even if you are going fast. So, I am using this little function to make sure the values are positive. You can just include this code somewhere in your code :)

  Code:
function convertToPositive(value) -- value is a local variable for this function only
    if(value<0) then -- If it is negative
        return -value -- Return positive value
    else
        return value -- Return unchanged (positive) value
    end
end


But, you need to update the lastVelocity constantly, so just do that again right over the onTicks()'s end:
  Code:
lastVelocity = ship:getVel()


So, the whole function would technically look like this, implying that you have a ship:

  Code:
function onTick()
    local shipVelocityNumber = 0 -- Using variables to be more efficient
    local lastVelocityNumber = 0

    -- Get ship here

    if(firstTick==true) then
        firstTick = false -- Set the variable to false, like that the if will not run again
        lastVelocity = ship:getVel() -- Put the ship's velocity in the variable
        return -- Get out of the function, so nothing else of that function is ran this time
    end

    shipVelocityNumber = convertToPositive(ship:getVel().x) + convertToPositive(ship:getVel().y) -- Make sure number is positive

    lastVelocityNumber =convertToPositive(lastVelocity.x) + convertToPositive(lastVelocity.y) -- Make sure number is positive

    if(shipVelocityNumber<lastVelocityNumber) then
        -- Slowing down!
    elseif(shipVelocityNumber>lastVelocityNumber) then
        -- Speeding up
    else
        -- Same speed!
    end

    lastVelocity = ship:getVel()
end


And the main() would have this:
  Code:
lastVelocity = nil
firstTick = true


I didn't have the time to test this, so it might not work.

If you have any questions, ask away :D
Last edited by Fordcars on Wed Mar 26, 2014 9:38 pm, edited 1 time in total.
skybax: Why is this health pack following me?
bobdaduck: uh, it likes you.
<<

tazinator

Posts: 351

Joined: Fri Jul 05, 2013 7:35 pm

Post Wed Mar 26, 2014 9:18 pm

Re: Velocity levelgens

looking at your code, I see a possible mistake, but im not sure. I can't wrap my brain around it, it's vague.

with velocity, a positive value on the x axis means moving to the right and a negative # the opposite. The y axis behaves similarly.

So shipVelocityNumber>lastVelocityNumber.... i really cant figure it out. you might be right, but in the meantime, I've doubled the code :mrgreen:

  Code:
function main()
lastVelocity = nil
firstTick = true

end

function onTick()
    local shipVelocityNumberX = 0 -- Using variables to be more efficient
    local lastVelocityNumberX = 0
    local shipVelocityNumberY = 0 -- Using variables to be more efficient
    local lastVelocityNumberY = 0

bf:findAllObjects(items, ObjType.Ship)
  local players = bf:getGameInfo():getPlayers();
    for i,player in ipairs(players) do
        local ship = player:getShip();
    end

    if(firstTick==true) then
        firstTick = false -- Set the variable to false, like that the if will not run again
        lastVelocity = ship:getVel() -- Put the ship's velocity in the variable
        return -- Get out of the function, so nothing else of that function is ran this time
    end

    shipVelocityNumberX = ship:getVel().x
    lastVelocityNumberX = lastVelocity.x
    shipVelocityNumberY = ship:getVel().y
    lastVelocityNumberY = lastVelocity.y
    xVelocityDifference = shipVelocityNumberX - lastVelocityNumberX
    yVelocityDifference = shipVelocityNumberY - lastVelocityNumberY
    slowNextVelocityX   = shipVelocityNumberX + .8*(xVelocityDifference)
    slowNextVelocityY   = shipVelocityNumberY + .8*(yVelocityDifference)
    fastNextVelocityX   = shipVelocityNumberX + .5*(xVelocityDifference)
    fastNextVelocityY   = shipVelocityNumberY + .5*(yVelocityDifference)
   
    if(shipVelocityNumberX<lastVelocityNumberX) then
    ship:setVel(slowNextVelocityX).x
        -- Slowing down! (slowing down takes longer now)
    --elseif(shipVelocityNumberX>lastVelocityNumberX) then
    --ship:setVel(1.2*(fastNextVelocityX).x
        -- Speeding up!!! (even faster than before!)
    --else
        -- Same speed!
    end

    if(shipVelocityNumberY<lastVelocityNumberY) then
    ship:setVel(slowNextVelocityY).y
        -- Slowing down!
   -- elseif(shipVelocityNumberY>lastVelocityNumberY) then
    --ship:setVel(fastNextVelocityY).y
        -- Speeding up
    --else
        -- Same speed!
    end

    lastVelocity = ship:getVel()
end


It does not run all the way though. :/
Play my new level! Two different teams fight over a nexus: One mainly defends while the other attacks! is fun
viewtopic.php?f=33&p=21002#p21002
<<

bobdaduck

User avatar

Global Moderator

Posts: 741

Joined: Thu Mar 11, 2010 1:39 pm

Location: Utah

Post Wed Mar 26, 2014 10:01 pm

Re: Velocity levelgens

Yeah, and that's where you'd want to use math.abs.

Also, the code will do really funky things if there are multiple players. You might want to learn/use arrays here.
Little_Apple wrote:DnD: the REAL bitfighter levelgen documentation
<<

tazinator

Posts: 351

Joined: Fri Jul 05, 2013 7:35 pm

Post Thu Mar 27, 2014 12:12 am

Re: Velocity levelgens

at this point im like ready to faint or something. Hardest code ever

  Code:
function main()
lastVelocity = nil
firstTick = true
    subscribe(Event.Tick);

end

function onTick()
    local shipVelocityNumberX = 0 -- Using variables to be more efficient
    local lastVelocityNumberX = 0
    local shipVelocityNumberY = 0 -- Using variables to be more efficient
    local lastVelocityNumberY = 0
  local players = bf:getGameInfo():getPlayers();
    for i,player in ipairs(players) do
        ship = player:getShip();
    end

    if(firstTick==true) then
        firstTick = false -- Set the variable to false, like that the if will not run again
        lastVelocity = ship:getVel() -- Put the ship's velocity in the variable
        return -- Get out of the function, so nothing else of that function is ran this time
    end
    shipVelocityNumberX = ship:getVel().x
    lastVelocityNumberX = lastVelocity.x
    shipVelocityNumberY = ship:getVel().y
    lastVelocityNumberY = lastVelocity.y



    xVelocityDifference = shipVelocityNumberX - lastVelocityNumberX
    yVelocityDifference = shipVelocityNumberY - lastVelocityNumberY

    decelerationX   = shipVelocityNumberX + .5*(xVelocityDifference)
    decelerationY   = shipVelocityNumberY + .5*(yVelocityDifference)
   




    ship:setVel(point.new(decelerationX, decelerationY))


    lastVelocity = ship:getVel()
end


I think I'll do my own code instead of finishing fordcars version. Cuz I feel like pukin :o :shock: :?
Play my new level! Two different teams fight over a nexus: One mainly defends while the other attacks! is fun
viewtopic.php?f=33&p=21002#p21002

Return to Technical Support

Who is online

Users browsing this forum: No registered users and 1 guest

cron