• Sign Up
• Login
• API
• FAQ
• Tools
• Archive
daily pastebin goal
64%
SHARE
TWEET

# Untitled

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

Top