Noob - move in random direction?

Hi

I know how to move an object to a point, but how to move in a random direction?

For an example, if I wan’t to create a car object, that rotates and drive in a random direction, how do I set the direction and move the car/object in that direction?

If anyone can link to a (very) simple tutorial - I’ll be happy :slight_smile:

Thanks

Is your car just a drawing or a drawing+physics object? With drawing you have to manage the movement steps youself, with physics object just set linearVelocity property.

It could be a simple line

.@Jorgensen if you know how to move an object to a point(say coordinates Targetx,Targety) you could make that point a random location.

Targetx=math.random(WIDTH)
Targety=math.random(HEIGHT)

If you put this in the setup it will generate a random location. If you put it in the main draw loop then it will generate a new location each cycle so you’ll want to control when you create a new location somehow.

Here’s a simple example of moving a circle to a random point. Depending on what you want to do will determine how much you change this.


displayMode(FULLSCREEN)

function setup()
    rx=math.random(WIDTH)
    ry=math.random(HEIGHT)
    x=rx
    y=ry
end

function draw()
    background(40, 40, 50)
    fill(255)
    ellipse(x,y,20)
    ellipse(rx,ry,5)
    if math.abs(x-rx)<5 and math.abs(y-ry)<5 then
        rx=math.random(WIDTH)
        ry=math.random(HEIGHT)
    else
        x=x+((rx-x)/60)
        y=y+((ry-y)/60)
    end
end

Thanks West - I’ll try that.

Do know how i best rotate my ‘car’ - Can one totate the global coordinates before drawing the car?

Thanks :slight_smile:

Here is my code so far

--# Main
-- car 1

-- Use this function to perform your initial setup
function setup()
    print("Hello World!")
    car_a = car(WIDTH, HEIGHT/2, -1.5, 0)
    --noStroke()
end

-- This function gets called once every frame
function draw()
    background(81, 188, 57, 255)
    
    car_a:draw()
    -- This sets a dark background color 
    --

    -- This sets the line thickness
    --strokeWidth(5)

    -- Do your drawing here
    
end

function touched(touch)
    if touch.state == BEGAN then
        car_a.color_lights_back = color(255, 5, 0, 255)
        car_a.breaking = true
        --print(touch)
    end
    if touch.state == ENDED then
        car_a.color_lights_back = color(222, 115, 116, 255)
        --print(touch)
        car_a.breaking = false
    end
end
--# car
car = class()

function car:init(_x, _y, _xspeed, _yspeed)
    -- you can accept and set parameters here
    self.breaking = false
    self.x = _x
    self.y = _y
    self.xspeed = _xspeed
    self.yspeed = _yspeed
    self.color_body            = color(100,100,100)
    self.color_lights_front    = color(255, 255, 255, 255)
    self.color_lights_back     = color(221, 127, 127, 255)
    self.dimensions_width      = 5
    self.dimensions_length     = 7
end

function car:draw()
    -- Codea does not automatically call this method
    self:body()
    self:lights_front()
    self:lights_back()
    self:move()
end

function car:touched(touch)
    -- Codea does not automatically call this method
end

function car:body()
    fill(self.color_body)
    y = self.y
    x = self.x
    rect(x, y, self.dimensions_length, self.dimensions_width)
end

function car:lights_front()
    fill(self.color_lights_front)
    y = self.y
    x = self.x
    rect(x-3, y, 3, self.dimensions_width)
end

function car:lights_back()
    fill(self.color_lights_back)
    y = self.y
    x = self.x
    rect(x+self.dimensions_length -1, y, 3, self.dimensions_width)
end

function car:move()
    if self.breaking == true and self.xspeed <=0 then
        self.xspeed = self.xspeed + 0.02
    --else self.xspeed = -1
    end
    
    if self.breaking == false and self.xspeed > -1.5 then
        self.xspeed = self.xspeed - 0.02
    end
    self.x = self.x + self.xspeed
end

Hmm this don’t look good :confused:

Hi Dave

Thanks for you input. I’ll try it out - but Can’t one use vectors for moving?

Put three ‘~’ before and after your code (—), it will lool good

.@Jorgensen the following modifications to your code will rotate your car body by 30 degrees. You’ll need something similar for the other parts of the car. Lookup the help to get an overview of the commands used

function car:body()
    fill(self.color_body)
    y = self.y
    x = self.x
    pushMatrix()
    translate(x,y)       
    rotate(30)
    translate(-x,-y)       
    rect(x, y, self.dimensions_length, self.dimensions_width)
    popMatrix()
end

@Jorgensen Maybe this will give you some ideas.


displayMode(FULLSCREEN)

function setup()
    car=image(20,10)    -- car image area
    
    -- head lights
    c=color(255, 255, 255, 255)
    for x=1,5 do
        for y=1,3 do
            car:set(x,y,c)
            car:set(x,y+7,c)
        end
    end
    
    -- car body
    c=color(250, 162, 13, 255)
    for x=6,20 do
        for y=1,10 do
            car:set(x,y,c)
        end
    end
    
    -- tail lights
    c=color(255, 0, 0, 255)
    for x=17,20 do
        for y=1,3 do
            car:set(x,y,c)
            car:set(x,y+7,c)
        end
    end

    cx=200
    cy=400
    rx=cx
    ry=cy
end

function draw()
    background(40, 40, 50)
    calcNext()
    fill(255)
    ellipse(rx,ry,5)
    pushMatrix()
    translate(cx,cy)
    rotate(270-direction)
    sprite(car,0,0)
    popMatrix()
end

function calcNext()    -- next random position
    if math.abs(cx-rx)<5 and math.abs(cy-ry)<5 then
        rx=math.random(WIDTH)
        ry=math.random(HEIGHT)
        dx=cx-rx
        dy=cy-ry
        speed=2/math.sqrt(dx*dx+dy*dy)
        sx=dx*speed
        sy=dy*speed
        carDirection()
    end
    cx = cx - sx
    cy = cy - sy
end

function carDirection()    -- direction facing forward
    direction=math.deg(math.atan2(rx-cx,ry-cy))
end

Hi @dave @west

Thanks - I’ll give it a try.

Below is my little contribution to things moving randomly:


--
-- Random Thing
--

supportedOrientations(LANDSCAPE_ANY)
function setup()
    myThing = Thing(WIDTH / 2, HEIGHT / 2, 0)
    img = image(WIDTH, HEIGHT) -- For breadcrumb trail
    spriteMode(CORNER)
end

function draw()
    background(64)
    sprite(img, 1, 1)
    myThing:draw()
    -- Update breadcrumb trail
    setContext(img)
    fill(127, 127, 0)
    ellipse(myThing.x, myThing.y, 5)
    setContext()
end

Thing = class()

-- Initialise the Thing
function Thing:init(x, y, angle)
    self.x = x
    self.y = y
    self.angle = angle
    self.speed = 100
    self.spin = 360
    self.colour = color(255, 255, 0)
    self:think(self.turn)
end

-- Tell the Thing to think a second about its next action
function Thing:think(nextAction)
    if self.state == "thinking" then return end
    self.state = "thinking"
    self.stopThinking = ElapsedTime + 1
    self.nextAction = nextAction
end

-- Tell the Thing to turn
function Thing:turn()
    self.state = "turning"
    local turn = math.random(15, 105) * (math.random(2) * 2 - 3)
    if turn * self.spin < 0 then
        self.spin = -self.spin
    end
    self.remainingTurn = turn
end

-- Tell the Thing to move
function Thing:move()
    self.state = "moving"
    local dx = self.x - WIDTH / 2
    local dy = self.y - HEIGHT / 2
    local strayDistance = math.sqrt(dx * dx + dy * dy)
    local maxRun = math.max(10, math.exp(-strayDistance / WIDTH * 5) *
        200)
    maxRun = math.min(200, maxRun)
    self.remainingDistance = math.random(10, maxRun)
end

-- Update and draw the Thing
function Thing:draw()
    -- Update the Thing given its state
    if self.state == "thinking" then
        if ElapsedTime > self.stopThinking then
            self.state = nil
            self.nextAction(self)
        end
    elseif self.state == "moving" then
        local distance = self.speed * DeltaTime
        self.x = self.x + math.cos(math.rad(self.angle)) *
            distance
        self.y = self.y + math.sin(math.rad(self.angle)) *
            distance
        self.remainingDistance = self.remainingDistance -
            distance
        if self.remainingDistance < 0 then
            self:think(self.turn) -- Think about turning
        end
    elseif self.state == "turning" then
        local turn = self.spin * DeltaTime
        self.angle = (self.angle + turn) % 360
        self.remainingTurn = self.remainingTurn - turn
        if self.spin * self.remainingTurn < 0 then
            self:think(self.move) -- Think about moving
        end
    end
    -- If doing nothing, a random thought may occur...
    if self.state == nil and math.random(60) == 1 then
        self:think(self.turn)
    end
    -- Draw the Thing
    pushMatrix()
    pushStyle()
    resetMatrix()
    translate(self.x, self.y)
    rotate(self.angle)
    noStroke()
    fill(self.colour)
    ellipseMode(CENTER)
    ellipse(0, 0, 50, 20)
    fill(0)
    ellipse(18, 3, 4)
    ellipse(18, -3, 4)
    popStyle()
    popMatrix()
end