Howdy, Stranger!

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

Polar Coordinates and NaN errors

edited September 2017 in Questions Posts: 35

Hey all,

I am trying to use polar coordinates to make a guided missile, the concept is that the code works out the vector between the rocket and its target and works out the angle difference between this and the rockets velocity vector and then tries to slowly correct for this angle.

The code seems to work best to my knowledge, but then suddenly all my vector values become NaN and I don't know why, I have tried to check for reasons why such as a divide by 0 but no luck.

If anyone could share some light on this that would be greatly appreciated, Thanks!

I've posted the code for the missile logic below and have commented it all, if anyone wants to read it.

Ps I have also attached some pictures below to show the error





Rocket = class() function Rocket:init(x,y) -- you can accept and set parameters here -- initial position self.pos = vec2(x,y) -- inital velocity self.vel = vec2(0,1) -- vector that links rocket position to its target self.aim = target.pos - self.pos self.speed = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) -- the rockets angle, a vector pointing directly up has an angle of 0 self.angle = 0 end function Rocket:draw() pushMatrix() pushStyle() ellipse(self.pos.x + 5,self.pos.y + 15,10) -- the translation is used so that the rotate function rotates the rectangle from the centre translate(self.pos.x + w/2 ,self.pos.y + h/2) rotate(-self.angle) fill(255, 0, 229, 255) stroke(255, 255, 255, 255) rect(-w/2,-h/2,w,h) popStyle() popMatrix() end function Rocket:update(target) -- update position self.pos = self.pos + self.vel print(self.pos) print(self.vel) print(self.aim) -- update vector connecting ship and target position self.aim = target.pos - self.pos -- magnitude of the aim vector self.aimMag = math.pow(((self.aim.x)*(self.aim.x)+ (self.aim.y)*(self.aim.y)),0.5) -- angle between the ships velocity and vector between the ship to its target self.angleRelToTarget = math.acos((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag) self.out = math.deg(self.angleRelToTarget) -- print(self.angleRelToTarget) text(self.out , self.pos.x + 50, self.pos.y + 50) pushStyle() strokeWidth(2) stroke(0, 0, 0, 255) -- this line shows the vector connecting the rocket to its target line(self.pos.x + w/2,self.pos.y + h/2,target.pos.x,target.pos.y) popStyle() -- this changes the ships velocity angle self.angle = self.angle + self.angleRelToTarget/2 -- print(math.deg(self.angle)) -- updates velocity with this new angle self.vel = vec2(math.sin(self.angle),math.cos(self.angle))*self.speed end

Comments

  • dave1707dave1707 Mod
    Posts: 7,606

    @rydergaz Having an example with workable code would help a lot. Include minimum code for the setup, draw, and touched functions so your code can be run. That way anyone who wants to help doesn't have to figure out the other functions just to explain your problem.

  • Sorry

  • Here we go

  • @dave1707 here's the whole programme



    --# Main -- Rocket displayMode(FULLSCREEN) w = 10 h = 30 TURN_ANGLE = 0.09 -- Use this function to perform your initial setup function setup() target = Target(WIDTH/2, HEIGHT/2,WIDTH*0.05) rocket = Rocket(200,HEIGHT*0.1) end -- This function gets called once every frame function draw() background(200, 201, 212, 255) target:draw() rocket:draw() rocket:update(target) end function touch() target.touched(touch) end --# Rocket Rocket = class() function Rocket:init(x,y) -- you can accept and set parameters here -- initial position self.pos = vec2(x,y) -- inital velocity self.vel = vec2(0,1) -- vector that links rocket position to its target self.aim = target.pos - self.pos self.speed = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) -- the rockets angle, a vector pointing directly up has an angle of 0 self.angle = 0 end function Rocket:draw() pushMatrix() pushStyle() ellipse(self.pos.x + 5,self.pos.y + 15,10) -- the translation is used so that the rotate function rotates the rectangle from the centre translate(self.pos.x + w/2 ,self.pos.y + h/2) rotate(-self.angle) fill(255, 0, 229, 255) stroke(255, 255, 255, 255) rect(-w/2,-h/2,w,h) popStyle() popMatrix() end function Rocket:update(target) -- update position self.pos = self.pos + self.vel print(self.pos) print(self.vel) print(self.aim) -- update vector connecting ship and target position self.aim = target.pos - self.pos -- magnitude of the aim vector self.aimMag = math.pow(((self.aim.x)*(self.aim.x)+ (self.aim.y)*(self.aim.y)),0.5) -- angle between the ships velocity and vector between the ship to its target self.angleRelToTarget = math.acos((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag) self.out = math.deg(self.angleRelToTarget) -- print(self.angleRelToTarget) text(self.out , self.pos.x + 50, self.pos.y + 50) pushStyle() strokeWidth(2) stroke(0, 0, 0, 255) -- this line shows the vector connecting the rocket to its target line(self.pos.x + w/2,self.pos.y + h/2,target.pos.x,target.pos.y) popStyle() -- this changes the ships velocity angle self.angle = self.angle + self.angleRelToTarget/2 -- print(math.deg(self.angle)) -- updates velocity with this new angle self.vel = vec2(math.sin(self.angle),math.cos(self.angle))*self.speed end --# Target Target = class() function Target:init(x,y,radius) -- you can accept and set parameters here self.pos = vec2(x,y) self.radius = radius end function Target:draw() pushStyle() fill(0, 0, 0, 255) ellipse(self.pos.x,self.pos.y,self.radius) -- Codea does not automatically call this method popStyle() end function Target:touched(touch) -- Codea does not automatically call this method self.x = CurrentTouch.x self.y = CurrentTouch.y end
  • dave1707dave1707 Mod
    Posts: 7,606

    You have a problem with math.acos() in rocket:update in the line

    self.angleRelToTarget = math.acos((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag)
    

    the result of the calculation

    (self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag
    

    is greater than 1.0 which results in a nan when doing math.acos.

    One way to fix this is to do something like

    val=(self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag)
    if val>1 then
       val=1
    end
    self.angleRelToTarget = math.acos(val)
    
  • The result shouldn't be over 1.0 since I'm taking the dot product right?

  • I've sorted the Nan error now, the issue was that when relative angle between the missiles velocity vector and the vector connecting it to its target become nearly 180 degrees (i.e the rocket is flying away from target.) the code gets stuck at 180 and the rocket doesn't turn

  • The new code is



    --# Main -- Rocket displayMode(FULLSCREEN) w = 10 h = 30 TURN_ANGLE = 0.09 -- Use this function to perform your initial setup function setup() target = Target(WIDTH/2, HEIGHT/2,WIDTH*0.05) rocket = Rocket(200,HEIGHT*0.1) end -- This function gets called once every frame function draw() background(200, 201, 212, 255) target:draw() rocket:draw() rocket:update(target) end function touched(t) target.pos.x = CurrentTouch.x target.pos.y = CurrentTouch.y end --# Rocket Rocket = class() function Rocket:init(x,y) -- you can accept and set parameters here -- initial position self.pos = vec2(x,y) -- inital velocity self.vel = vec2(0,1) -- vector that links rocket position to its target self.aim = target.pos - self.pos -- self.speed = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) self.speed = 1 parameter.integer("speed",2,10) -- the rockets angle, a vector pointing directly up has an angle of 0 self.angle = 0 end function Rocket:draw() pushMatrix() pushStyle() ellipse(self.pos.x + 5,self.pos.y + 15,10) -- the translation is used so that the rotate function rotates the rectangle from the centre translate(self.pos.x + w/2 ,self.pos.y + h/2) rotate(-self.angle) fill(255, 0, 229, 255) stroke(255, 255, 255, 255) rect(-w/2,-h/2,w,h) popStyle() popMatrix() end function Rocket:update(target) -- print("----start----") -- print(self.vel) -- print(self.speed) --print(self.aim) -- update position self.pos = self.pos + self.vel*speed -- print(self.pos) -- print(self.vel) -- print(self.aim) -- update vector connecting ship and target position self.aim = target.pos - self.pos -- magnitude of the aim vector self.aimMag = math.pow(((self.aim.x)*(self.aim.x)+ (self.aim.y)*(self.aim.y)),0.5) self.velMag = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) val=((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/(self.aimMag*self.velMag)) -- angle between the ships velocity and vector between the ship to its target self.angleRelToTarget = math.acos((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag) relAngle = self.angleRelToTarget -- angle of direction rocket wants to head in self.aimAngle = math.atan(self.aim.x/self.aim.y) -- angle of velocity of rocket self.aimVel = math.atan(self.vel.x/self.vel.y) self.out = math.deg(self.angleRelToTarget) -- print(self.angleRelToTarget) text(self.out , self.pos.x + 50, self.pos.y + 50) pushStyle() strokeWidth(2) stroke(0, 0, 0, 78) -- this line shows the vector connecting the rocket to its target line(self.pos.x + w/2,self.pos.y + h/2,target.pos.x,target.pos.y) popStyle() if self.aimVel > self.aimAngle then print("left") self.turn = -5 if math.abs(self.out) < 1 then self.turn = 1 end elseif self.aimVel < self.aimAngle then self.turn = 5 print("right") if math.abs(self.out) < 1 then self.turn = 1 end end -- this changes the ships velocity angle self.angle = self.angle + self.turn -- print(math.deg(self.angle)) -- updates velocity with this new angle self.vel = vec2(math.sin(math.rad(self.angle)),math.cos(math.rad(self.angle))) print(self.out) end --# Target Target = class() function Target:init(x,y,radius) -- you can accept and set parameters here self.pos = vec2(x,y) self.radius = radius end function Target:draw() pushStyle() fill(0, 0, 0, 255) ellipse(self.pos.x,self.pos.y,self.radius) -- Codea does not automatically call this method popStyle() end function Target:touched(touch) -- Codea does not automatically call this method self.pos.x = CurrentTouch.x self.pos.y = CurrentTouch.y end
  • dave1707dave1707 Mod
    edited September 2017 Posts: 7,606

    @rydergaz Here's an image from the guided missile program that I completed yesterday. The missile starts in the lower left corner and goes at a 45 degree angle to the right leaving a white trail. I'm using backingmode(RETAINED) to keep all the plotted point on the screen as the missile moves. When I tap the screen, a target point is created in red and a blue missile point is created where the missile was when the target point was created. After the missile passes thru a red target point, I tap the screen again creating another red target point and a blue missile position point. I did it several times to show the path of the missile as it seeked out each target point as I created them.

    PS. I ran this in portrait mode.

    IMG_1125.PNG 301.2K
  • Ah nice yours looks like it's working really smoothly, this is the latest update on mine it's almost there but for some reason the rocket chooses to turn away from the target sometimes. This screenshot shows you my rocket path, the orange dot is where I placed the target. You can see on the last target the rocket goes in the wrong direction.

  • Here is my rocket path

    IMG_0141.PNG 145.9K
  • How are you guiding your rocket ?

  • @dave1707 this is the code for my latest rocket programme


    --# Main -- Rocket V2 displayMode(FULLSCREEN) w = 10 h = 30 -- Use this function to perform your initial setup function setup() target = Target(WIDTH/2, HEIGHT/2,WIDTH*0.05) rocket = Rocket(200,HEIGHT*0.1) end -- This function gets called once every frame function draw() background(255, 255, 255, 255) target:draw() rocket:draw() rocket:update(target) end function touched(t) target.pos.x = CurrentTouch.x target.pos.y = CurrentTouch.y end --# Rocket Rocket = class() function Rocket:init(x,y) -- you can accept and set parameters here -- initial position self.pos = vec2(x,y) -- inital velocity self.vel = vec2(0,1) -- vector that links rocket position to its target self.aim = target.pos - self.pos -- self.speed = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) parameter.integer("speed",2,10) -- the rockets angle, a vector pointing directly up has an angle of 0 self.angle = 0 end function Rocket:draw() pushMatrix() pushStyle() ellipse(self.pos.x + 5,self.pos.y + 15,10) -- the translation is used so that the rotate function rotates the rectangle from the centre translate(self.pos.x + w/2 ,self.pos.y + h/2) rotate(-self.angle) fill(255, 0, 229, 255) stroke(0, 0, 0, 255) strokeWidth(1) rect(-w/2,-h/2,w,h) popStyle() popMatrix() end function Rocket:update(target) -- update position self.pos = self.pos + self.vel*speed -- update vector connecting ship and target position self.aim = target.pos - self.pos -- magnitude of the aim vector -- self.aimMag = math.pow(((self.aim.x)*(self.aim.x)+ (self.aim.y)*(self.aim.y)),0.5) -- self.velMag = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) -- val=((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/(self.aimMag*self.velMag)) -- angle between the ships velocity and vector between the ship to its target -- self.angleRelToTarget = math.acos((self.vel.x*self.aim.x + self.vel.y*self.aim.y)/self.aimMag) -- relAngle = self.angleRelToTarget -- angle of direction rocket wants to head in --self.aimAngle = math.deg(math.atan(self.aim.x/self.aim.y)) self.aimAngle = self:angleMachine(self.aim) -- angle of velocity of rocket --self.velAngle = math.deg(math.atan(self.vel.x/self.vel.y)) self.velAngle = self:angleMachine(self.vel) -- self.out = math.deg(self.angleRelToTarget) -- print(self.angleRelToTarget) -- text(self.out , self.pos.x + 50, self.pos.y + 50) pushStyle() strokeWidth(2) stroke(0, 0, 0, 78) -- this line shows the vector connecting the rocket to its target line(self.pos.x + w/2,self.pos.y + h/2,target.pos.x,target.pos.y) popStyle() -- pushMatrix() -- translate(500,500) -- text(self.aimAngle - self.aimVel, WIDTH*0.5,HEIGHT*0.7,100) -- print("------------") -- print(self.aimAngle) -- print(self.aimVel) -- print(self.aimAngle - self.aimVel) -- popMatrix() if self.angle> self.aimAngle then if self.angle - self.aimAngle> 180 then print("working") self.turn = -10 end self.turn = -1 -- print("left") -- if math.abs(self.aimVel - self.aimAngle) < 1 then -- self.turn = 1 -- end elseif self.angle < self.aimAngle then if self.aimAngle - self.angle > 180 then print("working2") self.turn = -50 speed = 0.1 end speed = 2 self.turn = 1 -- print("right") -- if math.abs(self.aimVel - self.aimAngle) < 1 then -- self.turn = 1 -- end end -- this changes the ships velocity angle self.angle = self.angle + self.turn -- print(math.deg(self.angle)) -- updates velocity with this new angle self.vel = vec2(math.sin(math.rad(self.angle)),math.cos(math.rad(self.angle))) pushStyle() stroke(0, 0, 0, 255) strokeWidth(3) line(target.pos.x,target.pos.y,target.pos.x+math.sin(math.rad(self.angle))*16,target.pos.y+math.cos(math.rad(self.angle))*16) pushMatrix() translate(600,800,0) text(self.aimAngle,600,900,10) translate(0,-50) text(self.velAngle,600,800,10) translate(0,-50) text(self.angle,600,700,10) translate(0,-50) text(self.aimAngle - self.velAngle,600,600,10) popMatrix() popStyle() end function Rocket:angleMachine(aim) angle = math.deg(math.atan(aim.x/aim.y)) if aim.x > 0 and aim.y > 0 then angle = angle elseif aim.x > 0 and aim.y < 0 then angle = 180 + angle elseif aim.x < 0 and aim.y < 0 then angle = 180 + angle elseif aim.x < 0 and aim.y > 0 then angle = 360 + angle end return angle end --# Target Target = class() function Target:init(x,y,radius) -- you can accept and set parameters here self.pos = vec2(x,y) self.radius = radius end function Target:draw() pushStyle() fill(241, 119, 44, 255) ellipse(self.pos.x,self.pos.y,self.radius) -- Codea does not automatically call this method popStyle() end function Target:touched(touch) -- Codea does not automatically call this method self.pos.x = CurrentTouch.x self.pos.y = CurrentTouch.y end
  • Update: managed to get it fully functioning runs like a dream now.


    --# Main -- Rocket V2 displayMode(FULLSCREEN) w = 10 h = 30 -- Use this function to perform your initial setup function setup() target = Target(WIDTH/2, HEIGHT/2,WIDTH*0.02) rocket = Rocket(200,HEIGHT*0.1) end -- This function gets called once every frame function draw() background(225, 224, 224, 255) target:draw() rocket:draw() rocket:update(target) end function touched(t) target.pos.x = CurrentTouch.x target.pos.y = CurrentTouch.y end --# Rocket Rocket = class() function Rocket:init(x,y) -- you can accept and set parameters here -- initial position self.pos = vec2(x,y) -- inital velocity self.vel = vec2(0,1) -- vector that links rocket position to its target self.aim = target.pos - self.pos -- self.speed = math.pow(((math.pow(self.vel.x,2))+ (math.pow(self.vel.y,2))),0.5) parameter.integer("speed",2,10) -- the rockets angle, a vector pointing directly up has an angle of 0 self.angle = 0 self.aimAngle = 0 self.velAngle = 0 out = "nothing" end function Rocket:draw() pushMatrix() pushStyle() ellipse(self.pos.x + 5,self.pos.y + 15,10) -- the translation is used so that the rotate function rotates the rectangle from the centre translate(self.pos.x + w/2 ,self.pos.y + h/2) rotate(-self.velAngle) fill(1, 255, 0, 255) stroke(0, 0, 0, 255) strokeWidth(1) rect(-w/2,-h/2,w,h) popStyle() popMatrix() end function Rocket:update(target) -- update position self.pos = self.pos + self.vel*speed -- update vector connecting ship and target position self.aim = target.pos - self.pos self.aimAngle = self:angleMachine(self.aim) self.velAngle = self:angleMachine(self.vel) pushStyle() strokeWidth(2) stroke(0, 0, 0, 78) -- this line shows the vector connecting the rocket to its target line(self.pos.x + w/2,self.pos.y + h/2,target.pos.x,target.pos.y) popStyle() if self.velAngle> self.aimAngle then if self.velAngle - self.aimAngle> 180 then -- print("right2") out = "right2" self.turn = 3 else -- print("left") out = "left" self.turn = -3 end elseif self.velAngle < self.aimAngle then if self.aimAngle - self.velAngle > 180 then -- print("left2") -- print(self.aimAngle-self.angle) out = "left2" self.turn = -3 else self.turn = 3 -- print("right") out = "right" end end -- this changes the ships velocity angle self.velAngle = self.velAngle + self.turn -- print(math.deg(self.angle)) -- updates velocity with this new angle self.vel = vec2(math.sin(math.rad(self.velAngle)),math.cos(math.rad(self.velAngle))) pushStyle() stroke(0, 0, 0, 255) strokeWidth(3) line(target.pos.x,target.pos.y,target.pos.x+math.sin(math.rad(self.velAngle))*16,target.pos.y+math.cos(math.rad(self.velAngle))*16) pushMatrix() translate(500,500) text(self.aimAngle,350,600,20) translate(0,-15) text(self.velAngle,350,590,20) translate(0,-15) -- text(self.angle,350,590,20) -- translate(0,-15) text(self.aimAngle - self.velAngle,350,580,20) translate(0,-15) text(self.velAngle - self.aimAngle,350,570,20) translate(0,-15) text(out,350,560,20) translate(0,-15) popMatrix() popStyle() end function Rocket:angleMachine(aim) angle = math.deg(math.atan(aim.x/aim.y)) if aim.x > 0 and aim.y > 0 then angle = angle elseif aim.x > 0 and aim.y < 0 then angle = 180 + angle elseif aim.x < 0 and aim.y < 0 then angle = 180 + angle elseif aim.x < 0 and aim.y > 0 then angle = 360 + angle end return angle end --# Target Target = class() function Target:init(x,y,radius) -- you can accept and set parameters here self.pos = vec2(x,y) self.radius = radius end function Target:draw() pushStyle() fill(241, 119, 44, 255) ellipse(self.pos.x,self.pos.y,self.radius) -- Codea does not automatically call this method popStyle() end function Target:touched(touch) -- Codea does not automatically call this method self.pos.x = CurrentTouch.x self.pos.y = CurrentTouch.y end
  • @dave1707 I'm still interested to see how you went about designing your homing missile. I took the bearings from the velocity vector and the vector connecting the rocket position to the target position and changed the velocity vectors angle till it's at the same angle as the position vector. If that makes sense

  • dave1707dave1707 Mod
    edited September 2017 Posts: 7,606

    @rydergaz Here's my version. I removed the blue dot since it isn't necessary. I left the backingMode in here. You can comment it out and uncomment background. The value of speed can be changed.

    displayMode(FULLSCREEN)
    
    function setup()
        mx,my=0,0
        x,y=0,0
        vx,vy=1,1
        speed=2
        backingMode(RETAINED)
    end
    
    function draw()
        --background(0)
        fill(255)
        ellipse(x,y,5)
        if px~=nil then
            fill(255,0,0)
            ellipse(px,py,10)
            dx=px-x
            dy=py-y
            if not hit then
                move()
                if math.abs(dx)<3 and math.abs(dy)<3 then
                    hit=true
                end
            end
        end
        x=x+vx*speed
        y=y+vy*speed
    end
    
    function move()
        v1=vec2(dx,dy)
        v1=v1:normalize()
        if vx<v1.x then
            vx=vx+speed*.005
        else
            vx=vx-speed*.005
        end
        if vy<v1.y then
            vy=vy+speed*.005
        else
            vy=vy-speed*.005
        end
    end
    
    function touched(t)
        if t.state==BEGAN then
            px=t.x
            py=t.y
            hit=false
        end
    end
    
  • Thanks! Your programme works so well and it's very fluid. The move() function is so smart, would it be okay if I used this same concept in a bigger project of mine?

  • dave1707dave1707 Mod
    Posts: 7,606

    @rydergaz Anything that's posted in the forum is free to use by anyone unless it says that it's not. So go ahead and use it wherever you want.

  • dave1707dave1707 Mod
    Posts: 7,606

    @rydergaz I'm not sure how you're going to use the code, but here's another version. I removed things not used. Try holding the iPad in portrait and landscape position. This is just a missile targeting another missile.

    displayMode(FULLSCREEN)
    
    function setup()
        x,y,vx,vy=0,0,0,0
        speed=5
        px=WIDTH
        py=HEIGHT*.8
        backingMode(RETAINED)
    end
    
    function draw()
        fill(255)
        dx=px-x
        dy=py-y
        if not hit then
            ellipse(x,y,5)
            px=px-3.1
            py=py+.3
            move()
            if math.abs(dx)<3 and math.abs(dy)<3 then
                hit=true
            end
        end
        fill(255,0,0)
        ellipse(px,py,10)
        x=x+vx*speed
        y=y+vy*speed
    end
    
    function move()
        v1=vec2(dx,dy)
        v1=v1:normalize()
        if vx<v1.x then
            vx=vx+(v1.x-vx)/4
        else
            vx=vx-(vx-v1.x)/4
        end
        if vy<v1.y then
            vy=vy+(v1.y-vy)/4
        else
            vy=vy-(vy-v1.y)/4
        end
    end
    
  • edited September 2017 Posts: 35
    @dave1707 thanks! I'll post an image of your rocket in use in the game I'm making. Here are the changes I made to your code so that it suits the style of my game, I'm very happy with how it's turned out.

    ~~~

    --# Main
    -- Rocket V3

    displayMode(FULLSCREEN)

    function setup()
    mx,my=0,0
    x,y=WIDTH/2,0
    vx,vy=0,1
    speed=4
    gas = {}
    --backingMode(RETAINED)
    end

    function draw()
    aim = vec2(vx,vy)

    angle = angleMachine(aim)

    background(0)

    fumes(x,y)




    fill(255)

    pushMatrix()

    translate(x,y)



    rotate(-angle)


    rect(-5,-15,10,30)
    popMatrix()


    if px~=nil then
    fill(255,0,0)
    ellipse(px,py,10)
    dx=px-x
    dy=py-y
    if not hit then
    move()
    if math.abs(dx) 0 then

    angle = 360 + angle

    end

    return angle
    end

    function fumes(xx,yy)

    randomNum = math.random(1,10)

    if randomNum > 5 then

    table.insert(gas,Smoke(xx,yy))

    end

    for a,b in pairs(gas) do

    b:draw()

    if b.status == "delete" then

    table.remove(gas)



    end



    end

    end


    --# Smoke
    Smoke = class()

    function Smoke:init(xx,yy)

    -- you can accept and set parameters here
    self.startPos = vec2(xx,yy)

    self.radius = math.random(1,30)
    self.alpha = 255
    self.angle = angle
    self.timer = 0
    self.status = "alive"


    pushMatrix()

    translate(x,y)

    rotate(-angle)

    fill(255,0,228,255)

    ellipse(0,-15,self.radius)

    popMatrix()

    end

    function Smoke:draw()
    self.r = math.random(1,255)
    self.g = math.random(1,255)
    self.b = math.random(1,255)


    pushMatrix()

    translate(self.startPos.x,self.startPos.y)

    rotate(-self.angle)




    self.alpha = self.alpha*0.97
    fill(self.r, self.g,self.b, self.alpha)
    ellipse(0,-15,self.radius)
    popMatrix()

    self.timer = self.timer + 1

    if self.timer > 800 then
    self.status = "delete"
    end

    end
    ~~~
Sign In or Register to comment.