Advertisement
Guest User

Untitled

a guest
Feb 25th, 2017
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.63 KB | None | 0 0
  1.  
  2.  
  3. -- Use this function to perform your initial setup
  4. function setup()
  5.     joint = nil
  6.     parameter.action("Play",play)
  7.     parameter.action("Stop",stop)
  8.     parameter.action("Pause",pause)
  9.     parameter.action("Undo",undo)
  10.     parameter.action("Redo",redo)
  11.     parameter.action("Save",save)
  12.     parameter.action("Load",lode)
  13.     parameter.watch("scan")
  14.     parameter.watch("#points")
  15.     physics.continuous = true
  16.     physics.pixelToMeterRatio = 32
  17.     physics.iterations(1,4)
  18.     physics.gravity(0,physics.gravity().y)
  19.     fps = 60
  20.     points = {}
  21.     newpoint = false
  22.     pedit = nil
  23.     adjust = vec2(WIDTH/2,HEIGHT/2)
  24.     ply = Ply(adjust)
  25.     playing = false
  26.     joints = {}
  27.     scr = vec2()
  28.     scan = vec2()
  29.     scl = 1
  30.     odist = nil
  31.     oscl = nil
  32.     opos = nil
  33.     oscr = nil
  34.     touches = {}
  35.     undone = {}
  36.     tmpobj = nil
  37.     id = 0
  38.     --joint:setCV(300,0.9)
  39.     --joint:setFriction(10)
  40. end
  41.  
  42. function save()
  43.     local str = ""
  44.     for k,v in pairs(points) do
  45.         str=str.."^"
  46.         for i,j in pairs(v) do
  47.             str=str.."-"..tostring(j.x)..","..tostring(j.y)
  48.         end
  49.     end
  50.     print(str)
  51.     saveLocalData("lr",str)
  52. end
  53.  
  54. function lode() --load
  55.     local str = readLocalData("lr")
  56.     if not str then return end
  57.     print(str)
  58.     local objsplit = split(str,"^")
  59.     for k,v in pairs(objsplit) do
  60.         local pnts = {}
  61.         local pntsplit = split(v,"-")
  62.         for i,j in pairs(pntsplit) do
  63.             local vecsplit = split(j,",")
  64.             local x = vecsplit[1]
  65.             local y = vecsplit[2]
  66.             pnts[i] = vec2(x,y)
  67.         end
  68.         table.insert(points,pnts)
  69.     end
  70. end
  71.  
  72. function moveScreen()
  73.     if playing then
  74.         local ball = ply:getPos()-adjust
  75.         if scr.x~=ball.x and scr.y~=ball.y then
  76.             scr = scr + ((adjust-ball)-scr)
  77.         end
  78.         local mt = adjust/scl-adjust
  79.         scale(scl)
  80.         translate(-ball.x+mt.x,-ball.y+mt.y)
  81.     else
  82.         local ball = scan
  83.         if scr.x~=ball.x and scr.y~=ball.y then
  84.             scr = scr + ((adjust-ball)-scr)
  85.         end
  86.         local mt = adjust/scl-adjust
  87.         scale(scl)
  88.         translate(-ball.x+mt.x,-ball.y+mt.y)
  89.     end  
  90. end
  91.  
  92.  
  93. function play()
  94.     if playing then return end
  95.     undone = {}
  96.     for i=1,#points do
  97.         id = i
  98.         joints[i] = RailJoint(points[i],ply)
  99.     end
  100.     ply.body.type = DYNAMIC
  101.     if tmpobj then
  102.         ply.body.linearVelocity = tmpobj.vel
  103.         ply.body.angle = tmpobj.ang
  104.         ply.body.angularVelocity = tmpobj.angvel
  105.     end
  106.     playing = true
  107. end
  108.  
  109. function stop()
  110.      if not playing then return end
  111.     for i=1,#joints do
  112.         joints[i]=nil
  113.     end
  114.     tmpobj = nil
  115.     ply.body.position = ply.initp
  116.     ply.body.linearVelocity = vec2()
  117.     ply.body.type = STATIC
  118.     scr = adjust
  119.     scl = 1
  120.     scan = ply:getPos()-adjust
  121.     playing = false
  122. end
  123.  
  124. function pause()
  125.     if not playing then return end
  126.     for i=1,#joints do
  127.         joints[i]=nil
  128.     end
  129.     --ply.body.position = ply.initp
  130.     tmpobj = {vel = ply.body.linearVelocity, ang = ply.body.angle, angvel = ply.body.angularVelocity}
  131.     ply.body.type = STATIC
  132.     scr = adjust
  133.     scl = 1
  134.     scan = ply:getPos()-adjust
  135.     playing = false
  136. end
  137.  
  138. function undo()
  139.     if not playing then
  140.         table.insert(undone,points[#points])
  141.         table.remove(points,#points)
  142.     end
  143. end
  144.  
  145. function redo()
  146.     if not playing then
  147.         table.insert(points,undone[#undone])
  148.         table.remove(undone,#undone)
  149.     end
  150. end
  151.  
  152. function touched(t)
  153.     if playing then return end
  154.     local tp = ((vec2(t.x,t.y)-adjust)/scl+(scan+adjust))
  155.     local jedit = false--currently does nothing
  156.     local td = Touch(t)
  157.     if t.state == BEGAN then
  158.         table.insert(touches,td)
  159.     end
  160.     if t.state == MOVING then
  161.         for k,v in pairs(touches) do
  162.             if v.id == td.id then
  163.                 touches[k] = td
  164.             end
  165.         end
  166.     end
  167.     if t.state == ENDED then
  168.         for k,v in pairs(touches) do
  169.             if v.id == td.id then
  170.                 --touches[k] = nil
  171.                 table.remove(touches,k)
  172.             end
  173.         end
  174.     end
  175.     if not jedit then
  176.         if t.state == BEGAN then
  177.             cedit = {math.huge,nil}
  178.             for k,v in pairs(points) do
  179.                 for i=1,#v do
  180.                     local pnt = v[i]
  181.                     if tp:dist(pnt)<10/scl and tp:dist(pnt)<cedit[1] then
  182.                         cedit = {tp:dist(pnt),points[k][i]}
  183.                     end
  184.                 end
  185.             end
  186.             pedit = cedit[2]
  187.             if not pedit then
  188.                 newpoint = true
  189.             end
  190.        
  191.             if newpoint and #touches == 1 then
  192.                 points[#points+1] = {tp}
  193.             end
  194.             if #touches==2 then
  195.                 newpoint = nil
  196.                 pedit = nil
  197.                 table.remove(points,#points)
  198.                 if points[#points] and #points[#points]==1 then
  199.                     table.remove(points,#points)
  200.                 end
  201.                 odist = touches[1].pos:dist(touches[2].pos)
  202.                 oscl = scl
  203.                 opos = (touches[1].pos+touches[2].pos)/2
  204.                 oscr = scan
  205.             end
  206.         end
  207.    
  208.         if t.state == MOVING then
  209.             if #touches == 1 then
  210.                 if pedit then
  211.                     pedit.x = tp.x
  212.                     pedit.y = tp.y
  213.                 end
  214.                 if newpoint then
  215.                     --print(vec2(tp.x,tp.y))
  216.                     --print(points[#points][#points[#points]])
  217.                     if vec2(tp.x,tp.y):dist(points[#points][#points[#points]])>10 then
  218.                         table.insert(points[#points],tp)
  219.                     end
  220.                 end
  221.             end
  222.             if #touches == 2 then
  223.                 local tf = touches
  224.                 local dps = (tf[1].pos+tf[2].pos)/2
  225.                 local dst = tf[1].pos:dist(tf[2].pos)
  226.                 scl = oscl+(dst-odist)/(vec2(WIDTH,HEIGHT):len()/2)*scl
  227.                 scan = oscr+(opos-dps)
  228.                 --print(scl)
  229.             end
  230.         end
  231.         if t.state == ENDED then
  232.             if pedit then
  233.                 pedit = nil
  234.             end
  235.             if newpoint then
  236.                 undone = {}
  237.                 newpoint = false
  238.             end
  239.             --scl = oscl+(dist-odist)/vec2(WIDTH,HEIGHT):len()
  240.             oscl = nil
  241.             odist = nil
  242.             oscr = nil
  243.         end
  244.     end
  245.    
  246. end
  247.  
  248. function clear()
  249.     for k,v in pairs(bodies) do
  250.         bodies[k]=nil
  251.     end
  252.     collectgarbage("collect")
  253.     bodies = {}
  254.     joint = nil
  255. end
  256.  
  257.  
  258. function unpackbodies(tbl)
  259.     local btbl = {}
  260.     for k,v in pairs(tbl) do
  261.         btbl[k] = v.body
  262.     end
  263.     return unpack(btbl)
  264. end
  265. function draw()
  266.     background(40, 40, 50)
  267.     strokeWidth(5)
  268.     fps=fps*0.95+(1/DeltaTime)*0.05
  269.     text(fps,100,100)
  270.     text(#touches,100,50)
  271.     pushMatrix()
  272.         moveScreen()
  273.     ply:draw()
  274.     if not playing then
  275.         for k,v in pairs(points) do
  276.             ellipse(v[1].x,v[1].y,10)
  277.             for i=2,#v do
  278.                 local p1 = v[i-1]
  279.                 local p2 = v[i]
  280.                 line(p1.x,p1.y,p2.x,p2.y)
  281.             end
  282.         end
  283.     else
  284.         scl = 1-ply.body.linearVelocity:len()/(ply.body.linearVelocity:len()/3+2000)
  285.         for k,v in pairs(joints) do
  286.             v:draw()
  287.         end
  288.     end
  289.     popMatrix()
  290.     if newpoint then
  291.         local tbl = points[#points]
  292.         for i=2,#tbl do
  293.             local p1 = tbl[i-1]
  294.             local p2 = tbl[i]
  295.             --line(p1.x,p1.y,p2.x,p2.y)
  296.         end
  297.     end
  298.  
  299. end
  300. --closest point on line (point,start,end)
  301. function cpol(p,a,b)
  302.         local c = p - a;      
  303.         local v = (b - a):normalize()  
  304.         local d = (b - a):len();
  305.         local t = v:dot(c)
  306.         if t < 0 then return a end
  307.         if t > d then return b end
  308.         v = v * t
  309.         return a + v;
  310. end
  311.  
  312. function angleOfPoint(pt) return math.deg(math.atan2(pt.y,pt.x)) end
  313.  
  314. linesIntersect = function( a, b, c, d )
  315.         -- parameter conversion
  316.         local L1 = {X1=a.x,Y1=a.y,X2=b.x,Y2=b.y}
  317.         local L2 = {X1=c.x,Y1=c.y,X2=d.x,Y2=d.y}
  318.        
  319.         -- Denominator for ua and ub are the same, so store this calculation
  320.         local d = (L2.Y2 - L2.Y1) * (L1.X2 - L1.X1) - (L2.X2 - L2.X1) * (L1.Y2 - L1.Y1)
  321.        
  322.         -- Make sure there is not a division by zero - this also indicates that the lines are parallel.
  323.         -- If n_a and n_b were both equal to zero the lines would be on top of each
  324.         -- other (coincidental).  This check is not done because it is not
  325.         -- necessary for this implementation (the parallel check accounts for this).
  326.         if (d == 0) then
  327.                 return false
  328.         end
  329.        
  330.         -- n_a and n_b are calculated as seperate values for readability
  331.         local n_a = (L2.X2 - L2.X1) * (L1.Y1 - L2.Y1) - (L2.Y2 - L2.Y1) * (L1.X1 - L2.X1)
  332.         local n_b = (L1.X2 - L1.X1) * (L1.Y1 - L2.Y1) - (L1.Y2 - L1.Y1) * (L1.X1 - L2.X1)
  333.        
  334.         -- Calculate the intermediate fractional point that the lines potentially intersect.
  335.         local ua = n_a / d
  336.         local ub = n_b / d
  337.        
  338.         -- The fractional point will be between 0 and 1 inclusive if the lines
  339.         -- intersect.  If the fractional calculation is larger than 1 or smaller
  340.         -- than 0 the lines would need to be longer to intersect.
  341.         if (ua >= 0 and ua <= 1 and ub >= 0 and ub <= 1) then
  342.                 local x = L1.X1 + (ua * (L1.X2 - L1.X1))
  343.                 local y = L1.Y1 + (ua * (L1.Y2 - L1.Y1))
  344.                 return {true, x=x, y=y}
  345.         end
  346.        
  347.         return false
  348. end
  349.  
  350. function linesIntersects(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y)
  351.    
  352.     local s1x, s1y, s2x, s2y;
  353.     s1x = p1x - p0x;
  354.     s1y = p1y - p0y;
  355.     s2x = p3x - p2x;
  356.     s2y = p3y - p2y;
  357.  
  358.     local s, t;
  359.     s = (-s1y * (p0x - p2x) + s1x * (p0y - p2y)) / (-s2x * s1y + s1x * s2y);
  360.     t = ( s2x * (p0y - p2y) - s2y * (p0x - p2x)) / (-s2x * s1y + s1x * s2y);
  361.  
  362.     if s >= 0 and s <= 1 and t >= 0 and t <= 1 then
  363.         return true
  364.     end
  365.  
  366.     return false
  367. end
  368. function vec(vec)
  369.     return vec2(math.floor(vec.x*10)/10,math.floor(vec.y*10)/10)
  370. end
  371.  
  372. function cross(i,b)
  373.   return -i * b.y - i * b.x;
  374. end
  375. function crossvec(a,b)
  376.     return -a.x*b.y - a.y*b.x
  377. end
  378.  
  379. function split(inputstr, sep)
  380.         local t={}
  381.         local i=1
  382.         for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
  383.                 t[i] = str
  384.                 i = i + 1
  385.         end
  386.         return t
  387. end
  388.  
  389. Ply = class()
  390.  
  391. function Ply:init(pos)
  392.     self.body = physics.body(POLYGON,vec2(-30,-10),vec2(-30,10),vec2(30,10),vec2(30,-10))
  393.     self.initp = pos
  394.     self.body.position = pos
  395.     self.body.type = STATIC
  396.     self.body.gravityScale = 1
  397.     self.body.mass = 1
  398.     self.body.inertia = 1
  399.     self.gravity = vec2(0,-100)
  400. end
  401.  
  402.  
  403. function Ply:getPos()
  404.     return self.body.position
  405. end
  406.  
  407.  
  408. function Ply:draw()
  409.     self.body.x = self.body.position.x
  410.     self.body.y = self.body.position.y
  411.     --self.body.linearVelocity = (self.body.linearVelocity)
  412.     pushMatrix()
  413.         translate(self.body.x,self.body.y)
  414.         rotate(self.body.angle)
  415.         sprite("SpaceCute:Rocketship",0,0,60,40)
  416.     popMatrix()
  417. end
  418.  
  419. --# RailJoint
  420. RailJoint = class()
  421.  
  422. function RailJoint:init(points,...)
  423.     self.id = id
  424.     self.points = points
  425.     local args = {...}
  426.     self.bodies = {}
  427.     for k,v in pairs(args) do
  428.         self.bodies[k] = v
  429.         self.bodies[k].body = v.body
  430.         v.linearDamping=0
  431.     end
  432.     self.m = mesh()
  433.     self.r = {}
  434.     for i=2,#self.points do
  435.         local p1,p2 = self.points[i-1],self.points[i]
  436.         local ang,pos,len = math.rad(angleOfPoint(p1-p2)),(p1+p2)/2,p1:dist(p2)
  437.         self.r[i] = self.m:addRect(pos.x,pos.y,len,2,ang)
  438.     end
  439.     self.conveyor = nil
  440. end
  441.  
  442. function RailJoint:setCV(speed,stiffness)
  443.     self.conveyor = {speed,stiffness}
  444. end
  445.  
  446. function RailJoint:setFriction(f)
  447.     for k,v in pairs(self.bodies) do
  448.         v.body.linearDamping = f
  449.     end
  450. end
  451.  
  452. function RailJoint:cp(body)
  453.     local cart = body.body
  454.     local cld = vec2(1,0):rotate(math.rad(cart.angle))
  455.     local clp = (cart.linearVelocity)
  456.     local tposr = (cart.position+vec2(25,-20):rotate(math.rad(cart.angle)))
  457.     local cposr = (cart.position+vec2(25,10):rotate(math.rad(cart.angle)))
  458.     local bposr = (cart.position+vec2(25,20):rotate(math.rad(cart.angle)))
  459.     local tposl = (cart.position+vec2(-25,-20):rotate(math.rad(cart.angle)))
  460.     local cposl = (cart.position+vec2(-25,10):rotate(math.rad(cart.angle)))
  461.     local bposl = (cart.position+vec2(-25,20):rotate(math.rad(cart.angle)))
  462.     --right intersection--
  463.     local closest = {math.huge,0,nil,nil,nil}
  464.     local intersectr
  465.     for i=2,#self.points do
  466.         local p1,p2 = self.points[i-1],self.points[i]
  467.         local cp = cpol(tposr,p1,p2)
  468.         if not intersectr then
  469.             intersectr = linesIntersects(cposr.x,cposr.y,tposr.x,tposr.y,p1.x,p1.y,p2.x,p2.y)
  470.         end
  471.         if closest[1]>cp:dist(tposr) then
  472.             closest = {cp:dist(tposr),i,cp,p1,p2}
  473.         end
  474.     end
  475.     local distr = closest[1]
  476.     local posr = closest[3]
  477.     local p1r,p2r = closest[4],closest[5]
  478.     local dlr = (tposr-posr):normalize()
  479.     local posrr = cposr+((posr)-cposr):normalize()*30
  480.     --intersectr = linesIntersects(cposr.x,cposr.y,posrr.x,posrr.y,p1r.x,p1r.y,p2r.x,p2r.y)
  481.     pushStyle()
  482.         resetStyle()
  483.         fill(255,0,0)
  484.         ellipse(posr.x,posr.y,10)
  485.         stroke(255,0,0,255)
  486.         strokeWidth(3)
  487.         line(p1r.x,p1r.y,p2r.x,p2r.y)
  488.         line(cart.x,cart.y,cart.x+cld.x*50,cart.y+cld.y*50)
  489.     popStyle()
  490.    
  491.     --left intersection--
  492.     local closest = {math.huge,0,nil,nil,nil}
  493.     local intersectl
  494.     for i=2,#self.points do
  495.         local p1,p2 = (self.points[i-1]),(self.points[i])
  496.         local cp = cpol(tposl,p1,p2)
  497.         if not intersectl then
  498.             intersectl = linesIntersects(cposl.x,cposl.y,tposl.x,tposl.y,p1.x,p1.y,p2.x,p2.y)
  499.         end
  500.         if closest[1]>cp:dist(tposl) then
  501.             closest = {cp:dist(tposl),i,cp,p1,p2}
  502.         end
  503.     end
  504.     local distl = closest[1]
  505.     local posl = closest[3]
  506.     local p1l,p2l = closest[4],closest[5]
  507.     local dll = (tposl-posl):normalize()
  508.     local posll = cposl+((posl)-cposl):normalize()*30
  509.     --intersectl = linesIntersects(cposl.x,cposl.y,posll.x,posll.y,p1l.x,p1l.y,p2l.x,p2l.y)
  510.     pushStyle()
  511.         resetStyle()
  512.         fill(0,0,255)
  513.         ellipse(posl.x,posl.y,12)
  514.         stroke(0, 0, 255, 255)
  515.         strokeWidth(3)
  516.         line(p1l.x,p1l.y,p2l.x,p2l.y)
  517.     popStyle()
  518.    
  519.    
  520.     --[[if intersectr and intersectl then
  521.         local cang = angleOfPoint(posr-posl)-cart.angle
  522.         while cang>180 do cang = cang-360 end
  523.         while cang<-180 do cang = cang+360 end
  524.         cart.angularVelocity = cart.angularVelocity+(cart.mass*(cang*32-cart.angularVelocity))/2
  525.     end]]
  526.     local impr = 0
  527.     if intersectl and posl:dist(tposl)>1 then
  528.         --
  529.         ellipse(tposl.x,tposl.y,8)
  530.         local vapl = cart:getLinearVelocityFromWorldPoint(tposl)*cart.mass*0.5
  531.         local normal = (p1l-p2l):rotate(math.pi/2):normalize()
  532.         cart:applyForce(cart.mass*((posl-tposl)*4)-(dll):dot(vapl)*(dll),tposl)
  533.     end
  534.     local impl = 0
  535.     if intersectr and posr:dist(tposr)>1 then
  536.         ellipse(tposr.x,tposr.y,8)
  537.         local vapr = cart:getLinearVelocityFromWorldPoint(tposr)*cart.mass*0.5
  538.         local normal = (p1r-p2r):rotate(math.pi/2):normalize()
  539.         cart:applyForce(cart.mass*((posr-tposr)*4)-(dlr):dot(vapr)*(dlr),tposr)
  540.     end
  541.    
  542.     if intersectl or intersectr then
  543.        
  544.     end
  545. end
  546.  
  547. function RailJoint:json()
  548.     local str = "&"
  549.     for k,v in pairs(self.points) do
  550.         str = str..tostring(v.x)..","..tostring(v.y)
  551.     end
  552.     return str
  553. end
  554.  
  555. function RailJoint:draw()
  556.     self.m:draw()
  557.     for k,v in pairs(self.bodies) do
  558.         self:cp(v)
  559.         if self.conveyor then
  560.             local sd,sf = self.conveyor[1],self.conveyor[2]
  561.         end
  562.     end
  563. end
  564.  
  565. function RailJoint:touched(touch)
  566.     -- Codea does not automatically call this method
  567. end
  568.  
  569.  
  570. Touch = class()
  571.  
  572. function Touch:init(t)
  573.     if t then
  574.     self.x = t.x
  575.     self.y = t.y
  576.     self.pos = vec2(t.x,t.y)
  577.     self.id = t.id
  578.     self.deltaX = t.deltaX
  579.     self.deltaY = t.deltaY
  580.     self.prevX = t.prevX
  581.     self.prevY = t.prevY
  582.     self.state = t.state
  583.     self.tapCount = t.tapCount
  584.         self.time = 2
  585.     return self
  586.     end
  587. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement