Guest User

Boxing - 2 players for Codea

a guest
May 5th, 2012
634
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --# Main
  2. supportedOrientations(PORTRAIT)
  3. debug = false
  4.  
  5. headsize = 100
  6. headweight = 5
  7.  
  8. bodywidth = 160
  9. bodyheight = 55
  10. bodyweight = 0
  11.  
  12. armlength = 100
  13. armwidth = 35
  14. armweight = 0
  15.  
  16. handsize = 50
  17. handweight = 0
  18.  
  19. hitforce = 10
  20. playerWon = 0
  21. maxhealth = 5000.0
  22. health = { maxhealth, maxhealth }
  23.  
  24. function setup()
  25. objects = Objects()
  26. lineCapMode(PROJECT)
  27. if debug ~= true then displayMode(FULLSCREEN) end
  28. physics.gravity(0, 0)
  29. physics.iterations(1, 8)
  30.  
  31. createBounds()
  32.  
  33. colors = { color(30, 73, 32, 255), color(32, 31, 111, 255) }
  34.  
  35. lh1, rh1, lb1, rb1, head1 = createBoxer(WIDTH/2, 150, 1, colors[1])
  36. lh2, rh2, lb2, rb2, head2 = createBoxer(WIDTH/2, HEIGHT - 150, -1, colors[2])
  37.  
  38. head1.info.collectDamage = vec2(10, 1)
  39. lb1.info.collectDamage = vec2(1, 1)
  40. rb1.info.collectDamage = vec2(1, 1)
  41.  
  42. lh1.info.inflictDamage = vec2(1, 1)
  43. rh1.info.inflictDamage = vec2(1, 1)
  44.  
  45. head2.info.collectDamage = vec2(10, 2)
  46. lb2.info.collectDamage = vec2(1, 2)
  47. rb2.info.collectDamage = vec2(1, 2)
  48.  
  49. lh2.info.inflictDamage = vec2(1, 2)
  50. rh2.info.inflictDamage = vec2(1, 2)
  51.  
  52. end
  53.  
  54. function draw()
  55. pushMatrix()
  56. background(0, 0, 0, 255)
  57. objects:draw()
  58. drawJoysticks()
  59. drawHealth()
  60. applyCorrections(200)
  61. popMatrix()
  62. end
  63.  
  64. function touched(touch)
  65. --objects:touched(touch)
  66. if playerWon == 0 then
  67. controlBoxers(touch)
  68. end
  69. end
  70.  
  71. function applyCorrections(correction)
  72. if playerWon ~= 2 then
  73. local v1 = vec2(0,1):rotate(math.rad(head1.angle))
  74. local v2 = vec2(head2.x - head1.x, head2.y - head1.y)
  75. local w = math.deg(v1:angleBetween(v2))
  76. w = w*w*w/10000
  77. head1:applyTorque(w * correction)
  78. end
  79.  
  80. if playerWon ~= 1 then
  81. local v1 = vec2(0,-1):rotate(math.rad(head2.angle))
  82. local v2 = vec2(head1.x - head2.x, head1.y - head2.y)
  83. local w = math.deg(v1:angleBetween(v2))
  84. w = w*w*w/10000
  85. head2:applyTorque(w * correction)
  86. end
  87. end
  88.  
  89. function controlBoxers(touch)
  90. local player = 1 + math.floor(touch.y / (HEIGHT/2))
  91. local lh, rh = lh1, rh1
  92. if player == 2 then
  93. lh, rh = rh2, lh2
  94. end
  95.  
  96. local side = 1 + math.floor(touch.x / (WIDTH/2))
  97. local hand = lh
  98. if side == 2 then hand = rh end
  99.  
  100. local px = (WIDTH / 4) * (1 + (side - 1) * 2)
  101. local py = (HEIGHT / 4) * (1 + (player - 1) * 2)
  102.  
  103. local vx = (touch.x - px) * hitforce
  104. local vy = (touch.y - py) * hitforce
  105.  
  106. hand:applyForce(vec2(vx, vy))
  107.  
  108. end
  109.  
  110. function drawJoysticks()
  111. pushStyle()
  112. stroke(255,255,255,32)
  113. strokeWidth(5)
  114. noFill()
  115. local d = WIDTH/4
  116. ellipse(WIDTH/4, HEIGHT/4, d)
  117. ellipse(WIDTH*3/4, HEIGHT/4, d)
  118. ellipse(WIDTH/4, HEIGHT*3/4, d)
  119. ellipse(WIDTH*3/4, HEIGHT*3/4, d)
  120. popStyle()
  121. end
  122.  
  123. function drawHealth()
  124. pushStyle()
  125. strokeWidth(0)
  126. fill(colors[1])
  127. rect(0, 0, health[1] * WIDTH / maxhealth, 30)
  128. fill(colors[2])
  129. rect(0, HEIGHT - 30, health[2] * WIDTH / maxhealth, 30)
  130. popStyle()
  131. end
  132.  
  133. function collide(contact)
  134. --objects:collide(contact)
  135. if contact.state == BEGAN then
  136. local b1 = contact.bodyA
  137. local b2 = contact.bodyB
  138. local dInfo = b1.info.inflictDamage or b2.info.inflictDamage
  139. if dInfo ~= nil then
  140. local damage, from = dInfo[1], dInfo[2]
  141. local collect = b1.info.collectDamage or b2.info.collectDamage
  142. if collect ~= nil then
  143. local force = contact.normalImpulse
  144. local injure = collect[1] * damage * force
  145. local player = collect[2]
  146. if player ~= from then
  147. if collect[1] > 1 then
  148. sound(SOUND_HIT, 2663)
  149. else
  150. sound(SOUND_HIT, 2664)
  151. end
  152.  
  153. health[player] = health[player] - injure
  154. if health[player] < 0 then
  155. playerWon = 3 - player
  156. local dead = color(40, 40, 40, 255)
  157. if player == 1 then
  158. head1.info.fillColor = dead
  159. head1.mass = 10000
  160. else
  161. head2.info.fillColor = dead
  162. head2.mass = 10000
  163. end
  164. end
  165. end
  166. end
  167. end
  168. end
  169. end
  170.  
  171. function createBounds()
  172. local r
  173. r = createBox(WIDTH/2, 15, WIDTH, 30)
  174. r.type = STATIC
  175. r = createBox(WIDTH/2, HEIGHT - 15, WIDTH, 30)
  176. r.type = STATIC
  177. r = createBox(-15, HEIGHT/2, 30, HEIGHT)
  178. r.type = STATIC
  179. r = createBox(WIDTH + 15, HEIGHT/2, 30, HEIGHT)
  180. r.type = STATIC
  181. end
  182.  
  183. function createBoxer(x, y, d, c)
  184.  
  185. -- arms
  186.  
  187. local diff = bodywidth/2 + (bodyheight - armwidth) / 2
  188.  
  189. local lUpperArm = createBox(x-d*diff, y+d*armlength/2, armwidth, armlength)
  190. lUpperArm.mass = armweight
  191. lUpperArm.info.fillColor = c
  192.  
  193. local rUpperArm = createBox(x+d*diff, y+d*armlength/2, armwidth, armlength)
  194. rUpperArm.mass = armweight
  195. rUpperArm.info.fillColor = c
  196.  
  197. local lElbow = createCircle(x-d*diff, y+d*armlength, armwidth/2)
  198. lElbow.mass = armweight
  199. lElbow.info.fillColor = c
  200.  
  201. local rElbow = createCircle(x+d*diff, y+d*armlength, armwidth/2)
  202. rElbow.mass = armweight
  203. rElbow.info.fillColor = c
  204.  
  205. weldParts(lUpperArm, lElbow)
  206. weldParts(rUpperArm, rElbow)
  207.  
  208. local lLowerArm = createBox(x-d*diff, y+d*armlength*3/2, armwidth, armlength)
  209. lLowerArm.mass = armweight
  210. lLowerArm.info.fillColor = c
  211.  
  212. local rLowerArm = createBox(x+d*diff, y+d*armlength*3/2, armwidth, armlength)
  213. rLowerArm.mass = armweight
  214. rLowerArm.info.fillColor = c
  215.  
  216. connectParts(lUpperArm, lLowerArm, lElbow.position, -10, 90)
  217. connectParts(rUpperArm, rLowerArm, rElbow.position, -90, 10)
  218.  
  219. -- hands
  220.  
  221. local lHand = createCircle(x-d*diff, y+d*armlength*2, handsize/2)
  222. lHand.mass = handweight
  223. lHand.info.fillColor = color(160, 25, 25, 255)
  224.  
  225. local rHand = createCircle(x+d*diff, y+d*armlength*2, handsize/2)
  226. rHand.mass = armweight
  227. rHand.info.fillColor = color(160, 25, 25, 255)
  228.  
  229. weldParts(lLowerArm, lHand)
  230. weldParts(rLowerArm, rHand)
  231.  
  232. -- torso
  233.  
  234. local lBody = createBox(x-d*bodywidth/4, y, bodywidth/2, bodyheight)
  235. lBody.mass = bodyweight
  236. lBody.info.fillColor = c
  237.  
  238. local rBody = createBox(x+d*bodywidth/4, y, bodywidth/2, bodyheight)
  239. rBody.mass = bodyweight
  240. rBody.info.fillColor = c
  241.  
  242. local lShoulder = createCircle(x-d*bodywidth/2, y, bodyheight/2)
  243. lShoulder.mass = bodyweight
  244. lShoulder.info.fillColor = c
  245.  
  246. local rShoulder = createCircle(x+d*bodywidth/2, y, bodyheight/2)
  247. rShoulder.mass = bodyweight
  248. rShoulder.info.fillColor = c
  249.  
  250. weldParts(lBody, lShoulder)
  251. weldParts(rBody, rShoulder)
  252.  
  253. local lUpperJoint = connectParts(lBody, lUpperArm, lShoulder.position, -90, 90)
  254. local rUpperJoint = connectParts(rBody, rUpperArm, rShoulder.position, -90, 90)
  255.  
  256. -- head
  257.  
  258. local head = createCircle(x, y, headsize/2)
  259. head.mass = headweight
  260. head.info.fillColor = color(255, 255, 255, 255)
  261.  
  262. weldParts(lBody, head)
  263. weldParts(rBody, head)
  264.  
  265. return lHand, rHand, lBody, rBody, head
  266. end
  267.  
  268. -- object creation routines ----------------------------------
  269.  
  270. function createCircle(x,y,r)
  271. local circle = physics.body(CIRCLE, r)
  272. circle.interpolate = false
  273. circle.x = x
  274. circle.y = y
  275. circle.info = {}
  276. circle.sleepingAllowed = false
  277. circle.interpolate = true
  278. objects:addBody(circle)
  279. return circle
  280. end
  281.  
  282. function createBox(x,y,w,h)
  283. local box = physics.body(POLYGON, vec2(-w/2,h/2), vec2(-w/2,-h/2), vec2(w/2,-h/2), vec2(w/2,h/2))
  284. box.x = x
  285. box.y = y
  286. box.info = {}
  287. box.info.isRect = true
  288. box.sleepingAllowed = false
  289. box.interpolate = true
  290. objects:addBody(box)
  291. return box
  292. end
  293.  
  294. function createPoly(points, x, y)
  295. local poly = physics.body(POLYGON, unpack(points))
  296. poly.interpolate = false
  297. poly.x = x
  298. poly.y = y
  299. poly.info = {}
  300. poly.sleepingAllowed = false
  301. poly.interpolate = true
  302. objects:addBody(poly)
  303. return poly
  304. end
  305.  
  306. function createLine(x1, y1, x2, y2)
  307. local edge = physics.body(EDGE, vec2(x1, y1), vec2(x2, y2))
  308. edge.interpolate = false
  309. edge.type = EDGE
  310. edge.info = {}
  311. edge.sleepingAllowed = false
  312. edge.interpolate = true
  313. objects:addBody(edge)
  314. return edge
  315. end
  316.  
  317. function createRandPoly(x,y)
  318. local count = math.random(3,10)
  319. local r = math.random(25,75)
  320. local a = 0
  321. local d = 2 * math.pi / count
  322. local points = {}
  323. for i = 1,count do
  324. local r1 = math.random(-10,10)
  325. local r2 = math.random(-10,10)
  326. local v = vec2(r,0):rotate(a) + vec2(r1, r2)
  327. a = a + d
  328. table.insert(points, v)
  329. end
  330. createPoly(points, x, y)
  331. end
  332.  
  333. function weldParts(part1, part2, where)
  334. local joint = connectParts(part1, part2, where)
  335. restrictAngle(joint, 0, 0)
  336. return joint
  337. end
  338.  
  339. function connectParts(part1, part2, where, minAngle, maxAngle)
  340. where = where or part2.position
  341. local joint = physics.joint(REVOLUTE, part1, part2, where)
  342. objects:addJoint(joint)
  343. if minAngle and maxAngle then
  344. restrictAngle(joint, minAngle, maxAngle)
  345. end
  346. return joint
  347. end
  348.  
  349. function restrictAngle(joint, minAngle, maxAngle)
  350. joint.enableLimit = true
  351. joint.upperLimit = -minAngle
  352. joint.lowerLimit = -maxAngle
  353. end
  354.  
  355.  
  356.  
  357.  
  358. --# Objects
  359. Objects = class()
  360.  
  361. function Objects:init()
  362. self.bodies = {}
  363. self.joints = {}
  364. self.touchMap = {}
  365. self.contacts = {}
  366. end
  367.  
  368. function Objects:addBody(body)
  369. table.insert(self.bodies, body)
  370. end
  371.  
  372. function Objects:removeBody(body)
  373. for i,b in ipairs(self.bodies) do
  374. if b == body then
  375. table.remove(self.bodies, i)
  376. return
  377. end
  378. end
  379. end
  380.  
  381. function Objects:addJoint(joint)
  382. table.insert(self.joints, joint)
  383. end
  384.  
  385. function Objects:removeJoint(joint)
  386. for i,j in ipairs(self.joints) do
  387. if j == joint then
  388. table.remove(self.joints, i)
  389. return
  390. end
  391. end
  392. end
  393.  
  394. function Objects:clear()
  395. for i,body in ipairs(self.bodies) do body:destroy() end
  396. for i,joint in ipairs(self.joints) do joint:destroy() end
  397. self.bodies = {}
  398. self.joints = {}
  399. self.contacts = {}
  400. self.touchMap = {}
  401. end
  402.  
  403. function Objects:drawTouchVector()
  404. pushStyle()
  405. strokeWidth(5)
  406. stroke(128,0,128)
  407. local gain = 2.0
  408. local damp = 0.5
  409. for k,v in pairs(self.touchMap) do
  410. local worldAnchor = v.body:getWorldPoint(v.anchor)
  411. local touchPoint = v.tp
  412. local diff = touchPoint - worldAnchor
  413. local vel = v.body:getLinearVelocityFromWorldPoint(worldAnchor)
  414. v.body:applyForce((1/1) * diff * gain - vel * damp, worldAnchor)
  415. line(touchPoint.x, touchPoint.y, worldAnchor.x, worldAnchor.y)
  416. end
  417. popStyle()
  418. end
  419.  
  420. function Objects:drawJoints()
  421. pushStyle()
  422. stroke(0,255,0,255)
  423. strokeWidth(5)
  424. for k,joint in pairs(self.joints) do
  425. local a = joint.anchorA
  426. local b = joint.anchorB
  427. line(a.x,a.y,b.x,b.y)
  428. end
  429. popStyle()
  430. end
  431.  
  432. function Objects:drawObjects()
  433. local defaultColor = color(255, 255, 255, 255)
  434. for i,body in ipairs(self.bodies) do
  435. pushMatrix()
  436. pushStyle()
  437.  
  438. if body.info == nil then
  439. body.info = {}
  440. end
  441.  
  442. local lineWidth = body.info.lineWidth
  443. if lineWidth and lineWidth > 0 then
  444. stroke(body.info.lineColor or defaultColor)
  445. strokeWidth(lineWidth)
  446. else
  447. noStroke()
  448. lineWidth = 0
  449. end
  450.  
  451. if body.info.fillColor then
  452. fill(body.info.fillColor)
  453. else
  454. noFill()
  455. end
  456.  
  457. translate(body.x, body.y)
  458. rotate(body.angle)
  459.  
  460. if body.shapeType == POLYGON then
  461. local points = body.points
  462. if body.info.isRect == true then
  463. local x1 = points[1][1]
  464. local y1 = points[1][2]
  465. local x2 = points[3][1]
  466. local y2 = points[3][2]
  467. rectMode(CORNERS)
  468. rect(x1, y1, x2, y2)
  469. else
  470. for j = 1,#points do
  471. a = points[j]
  472. b = points[(j % #points)+1]
  473. line(a.x, a.y, b.x, b.y)
  474. end
  475. end
  476. elseif body.shapeType == CHAIN or body.shapeType == EDGE then
  477. local points = body.points
  478. for j = 1,#points-1 do
  479. a = points[j]
  480. b = points[j+1]
  481. line(a.x, a.y, b.x, b.y)
  482. end
  483. elseif body.shapeType == CIRCLE then
  484. ellipse(0,0,body.radius*2)
  485. if lineWidth > 0 then
  486. pushMatrix()
  487. pushStyle()
  488. strokeWidth(lineWidth * 2)
  489. for r = 0, 2 do
  490. rotate(120)
  491. line(0, 0, body.radius - 3, 0)
  492. end
  493. popStyle()
  494. popMatrix()
  495. end
  496. end
  497.  
  498. popStyle()
  499. popMatrix()
  500. end
  501. end
  502.  
  503. function Objects:drawContacts()
  504. pushStyle()
  505. stroke(255, 0, 0, 255)
  506. fill(255, 0, 0, 255)
  507. for k,v in pairs(self.contacts) do
  508. for m,n in ipairs(v.points) do
  509. ellipse(n.x, n.y, 10, 10)
  510. end
  511. end
  512. popStyle()
  513. end
  514.  
  515. function Objects:draw()
  516. self:drawTouchVector()
  517. self:drawJoints()
  518. self:drawObjects()
  519. self:drawContacts()
  520. end
  521.  
  522. function Objects:touched(touch)
  523. local touchPoint = vec2(touch.x , touch.y)
  524. if touch.state == BEGAN then
  525. for i,body in ipairs(self.bodies) do
  526. if body:testPoint(touchPoint) then
  527. local anchor = body:getLocalPoint(touchPoint)
  528. self.touchMap[touch.id] = {tp = touchPoint, body = body, anchor = anchor}
  529. return true
  530. end
  531. end
  532. elseif touch.state == MOVING and self.touchMap[touch.id] then
  533. self.touchMap[touch.id].tp = touchPoint
  534. return true
  535. elseif touch.state == ENDED and self.touchMap[touch.id] then
  536. self.touchMap[touch.id] = nil
  537. return true;
  538. end
  539. return false
  540. end
  541.  
  542. function Objects:collide(contact)
  543. if contact.state == BEGAN then
  544. self.contacts[contact.id] = contact
  545. sound(SOUND_HIT, 2643)
  546. elseif contact.state == MOVING then
  547. self.contacts[contact.id] = contact
  548. elseif contact.state == ENDED then
  549. self.contacts[contact.id] = nil
  550. end
  551. end
RAW Paste Data