Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Main
- supportedOrientations(PORTRAIT)
- debug = false
- headsize = 100
- headweight = 5
- bodywidth = 160
- bodyheight = 55
- bodyweight = 0
- armlength = 100
- armwidth = 35
- armweight = 0
- handsize = 50
- handweight = 0
- hitforce = 10
- playerWon = 0
- maxhealth = 5000.0
- health = { maxhealth, maxhealth }
- function setup()
- objects = Objects()
- lineCapMode(PROJECT)
- if debug ~= true then displayMode(FULLSCREEN) end
- physics.gravity(0, 0)
- physics.iterations(1, 8)
- createBounds()
- colors = { color(30, 73, 32, 255), color(32, 31, 111, 255) }
- lh1, rh1, lb1, rb1, head1 = createBoxer(WIDTH/2, 150, 1, colors[1])
- lh2, rh2, lb2, rb2, head2 = createBoxer(WIDTH/2, HEIGHT - 150, -1, colors[2])
- head1.info.collectDamage = vec2(10, 1)
- lb1.info.collectDamage = vec2(1, 1)
- rb1.info.collectDamage = vec2(1, 1)
- lh1.info.inflictDamage = vec2(1, 1)
- rh1.info.inflictDamage = vec2(1, 1)
- head2.info.collectDamage = vec2(10, 2)
- lb2.info.collectDamage = vec2(1, 2)
- rb2.info.collectDamage = vec2(1, 2)
- lh2.info.inflictDamage = vec2(1, 2)
- rh2.info.inflictDamage = vec2(1, 2)
- end
- function draw()
- pushMatrix()
- background(0, 0, 0, 255)
- objects:draw()
- drawJoysticks()
- drawHealth()
- applyCorrections(200)
- popMatrix()
- end
- function touched(touch)
- --objects:touched(touch)
- if playerWon == 0 then
- controlBoxers(touch)
- end
- end
- function applyCorrections(correction)
- if playerWon ~= 2 then
- local v1 = vec2(0,1):rotate(math.rad(head1.angle))
- local v2 = vec2(head2.x - head1.x, head2.y - head1.y)
- local w = math.deg(v1:angleBetween(v2))
- w = w*w*w/10000
- head1:applyTorque(w * correction)
- end
- if playerWon ~= 1 then
- local v1 = vec2(0,-1):rotate(math.rad(head2.angle))
- local v2 = vec2(head1.x - head2.x, head1.y - head2.y)
- local w = math.deg(v1:angleBetween(v2))
- w = w*w*w/10000
- head2:applyTorque(w * correction)
- end
- end
- function controlBoxers(touch)
- local player = 1 + math.floor(touch.y / (HEIGHT/2))
- local lh, rh = lh1, rh1
- if player == 2 then
- lh, rh = rh2, lh2
- end
- local side = 1 + math.floor(touch.x / (WIDTH/2))
- local hand = lh
- if side == 2 then hand = rh end
- local px = (WIDTH / 4) * (1 + (side - 1) * 2)
- local py = (HEIGHT / 4) * (1 + (player - 1) * 2)
- local vx = (touch.x - px) * hitforce
- local vy = (touch.y - py) * hitforce
- hand:applyForce(vec2(vx, vy))
- end
- function drawJoysticks()
- pushStyle()
- stroke(255,255,255,32)
- strokeWidth(5)
- noFill()
- local d = WIDTH/4
- ellipse(WIDTH/4, HEIGHT/4, d)
- ellipse(WIDTH*3/4, HEIGHT/4, d)
- ellipse(WIDTH/4, HEIGHT*3/4, d)
- ellipse(WIDTH*3/4, HEIGHT*3/4, d)
- popStyle()
- end
- function drawHealth()
- pushStyle()
- strokeWidth(0)
- fill(colors[1])
- rect(0, 0, health[1] * WIDTH / maxhealth, 30)
- fill(colors[2])
- rect(0, HEIGHT - 30, health[2] * WIDTH / maxhealth, 30)
- popStyle()
- end
- function collide(contact)
- --objects:collide(contact)
- if contact.state == BEGAN then
- local b1 = contact.bodyA
- local b2 = contact.bodyB
- local dInfo = b1.info.inflictDamage or b2.info.inflictDamage
- if dInfo ~= nil then
- local damage, from = dInfo[1], dInfo[2]
- local collect = b1.info.collectDamage or b2.info.collectDamage
- if collect ~= nil then
- local force = contact.normalImpulse
- local injure = collect[1] * damage * force
- local player = collect[2]
- if player ~= from then
- if collect[1] > 1 then
- sound(SOUND_HIT, 2663)
- else
- sound(SOUND_HIT, 2664)
- end
- health[player] = health[player] - injure
- if health[player] < 0 then
- playerWon = 3 - player
- local dead = color(40, 40, 40, 255)
- if player == 1 then
- head1.info.fillColor = dead
- head1.mass = 10000
- else
- head2.info.fillColor = dead
- head2.mass = 10000
- end
- end
- end
- end
- end
- end
- end
- function createBounds()
- local r
- r = createBox(WIDTH/2, 15, WIDTH, 30)
- r.type = STATIC
- r = createBox(WIDTH/2, HEIGHT - 15, WIDTH, 30)
- r.type = STATIC
- r = createBox(-15, HEIGHT/2, 30, HEIGHT)
- r.type = STATIC
- r = createBox(WIDTH + 15, HEIGHT/2, 30, HEIGHT)
- r.type = STATIC
- end
- function createBoxer(x, y, d, c)
- -- arms
- local diff = bodywidth/2 + (bodyheight - armwidth) / 2
- local lUpperArm = createBox(x-d*diff, y+d*armlength/2, armwidth, armlength)
- lUpperArm.mass = armweight
- lUpperArm.info.fillColor = c
- local rUpperArm = createBox(x+d*diff, y+d*armlength/2, armwidth, armlength)
- rUpperArm.mass = armweight
- rUpperArm.info.fillColor = c
- local lElbow = createCircle(x-d*diff, y+d*armlength, armwidth/2)
- lElbow.mass = armweight
- lElbow.info.fillColor = c
- local rElbow = createCircle(x+d*diff, y+d*armlength, armwidth/2)
- rElbow.mass = armweight
- rElbow.info.fillColor = c
- weldParts(lUpperArm, lElbow)
- weldParts(rUpperArm, rElbow)
- local lLowerArm = createBox(x-d*diff, y+d*armlength*3/2, armwidth, armlength)
- lLowerArm.mass = armweight
- lLowerArm.info.fillColor = c
- local rLowerArm = createBox(x+d*diff, y+d*armlength*3/2, armwidth, armlength)
- rLowerArm.mass = armweight
- rLowerArm.info.fillColor = c
- connectParts(lUpperArm, lLowerArm, lElbow.position, -10, 90)
- connectParts(rUpperArm, rLowerArm, rElbow.position, -90, 10)
- -- hands
- local lHand = createCircle(x-d*diff, y+d*armlength*2, handsize/2)
- lHand.mass = handweight
- lHand.info.fillColor = color(160, 25, 25, 255)
- local rHand = createCircle(x+d*diff, y+d*armlength*2, handsize/2)
- rHand.mass = armweight
- rHand.info.fillColor = color(160, 25, 25, 255)
- weldParts(lLowerArm, lHand)
- weldParts(rLowerArm, rHand)
- -- torso
- local lBody = createBox(x-d*bodywidth/4, y, bodywidth/2, bodyheight)
- lBody.mass = bodyweight
- lBody.info.fillColor = c
- local rBody = createBox(x+d*bodywidth/4, y, bodywidth/2, bodyheight)
- rBody.mass = bodyweight
- rBody.info.fillColor = c
- local lShoulder = createCircle(x-d*bodywidth/2, y, bodyheight/2)
- lShoulder.mass = bodyweight
- lShoulder.info.fillColor = c
- local rShoulder = createCircle(x+d*bodywidth/2, y, bodyheight/2)
- rShoulder.mass = bodyweight
- rShoulder.info.fillColor = c
- weldParts(lBody, lShoulder)
- weldParts(rBody, rShoulder)
- local lUpperJoint = connectParts(lBody, lUpperArm, lShoulder.position, -90, 90)
- local rUpperJoint = connectParts(rBody, rUpperArm, rShoulder.position, -90, 90)
- -- head
- local head = createCircle(x, y, headsize/2)
- head.mass = headweight
- head.info.fillColor = color(255, 255, 255, 255)
- weldParts(lBody, head)
- weldParts(rBody, head)
- return lHand, rHand, lBody, rBody, head
- end
- -- object creation routines ----------------------------------
- function createCircle(x,y,r)
- local circle = physics.body(CIRCLE, r)
- circle.interpolate = false
- circle.x = x
- circle.y = y
- circle.info = {}
- circle.sleepingAllowed = false
- circle.interpolate = true
- objects:addBody(circle)
- return circle
- end
- function createBox(x,y,w,h)
- 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))
- box.x = x
- box.y = y
- box.info = {}
- box.info.isRect = true
- box.sleepingAllowed = false
- box.interpolate = true
- objects:addBody(box)
- return box
- end
- function createPoly(points, x, y)
- local poly = physics.body(POLYGON, unpack(points))
- poly.interpolate = false
- poly.x = x
- poly.y = y
- poly.info = {}
- poly.sleepingAllowed = false
- poly.interpolate = true
- objects:addBody(poly)
- return poly
- end
- function createLine(x1, y1, x2, y2)
- local edge = physics.body(EDGE, vec2(x1, y1), vec2(x2, y2))
- edge.interpolate = false
- edge.type = EDGE
- edge.info = {}
- edge.sleepingAllowed = false
- edge.interpolate = true
- objects:addBody(edge)
- return edge
- end
- function createRandPoly(x,y)
- local count = math.random(3,10)
- local r = math.random(25,75)
- local a = 0
- local d = 2 * math.pi / count
- local points = {}
- for i = 1,count do
- local r1 = math.random(-10,10)
- local r2 = math.random(-10,10)
- local v = vec2(r,0):rotate(a) + vec2(r1, r2)
- a = a + d
- table.insert(points, v)
- end
- createPoly(points, x, y)
- end
- function weldParts(part1, part2, where)
- local joint = connectParts(part1, part2, where)
- restrictAngle(joint, 0, 0)
- return joint
- end
- function connectParts(part1, part2, where, minAngle, maxAngle)
- where = where or part2.position
- local joint = physics.joint(REVOLUTE, part1, part2, where)
- objects:addJoint(joint)
- if minAngle and maxAngle then
- restrictAngle(joint, minAngle, maxAngle)
- end
- return joint
- end
- function restrictAngle(joint, minAngle, maxAngle)
- joint.enableLimit = true
- joint.upperLimit = -minAngle
- joint.lowerLimit = -maxAngle
- end
- --# Objects
- Objects = class()
- function Objects:init()
- self.bodies = {}
- self.joints = {}
- self.touchMap = {}
- self.contacts = {}
- end
- function Objects:addBody(body)
- table.insert(self.bodies, body)
- end
- function Objects:removeBody(body)
- for i,b in ipairs(self.bodies) do
- if b == body then
- table.remove(self.bodies, i)
- return
- end
- end
- end
- function Objects:addJoint(joint)
- table.insert(self.joints, joint)
- end
- function Objects:removeJoint(joint)
- for i,j in ipairs(self.joints) do
- if j == joint then
- table.remove(self.joints, i)
- return
- end
- end
- end
- function Objects:clear()
- for i,body in ipairs(self.bodies) do body:destroy() end
- for i,joint in ipairs(self.joints) do joint:destroy() end
- self.bodies = {}
- self.joints = {}
- self.contacts = {}
- self.touchMap = {}
- end
- function Objects:drawTouchVector()
- pushStyle()
- strokeWidth(5)
- stroke(128,0,128)
- local gain = 2.0
- local damp = 0.5
- for k,v in pairs(self.touchMap) do
- local worldAnchor = v.body:getWorldPoint(v.anchor)
- local touchPoint = v.tp
- local diff = touchPoint - worldAnchor
- local vel = v.body:getLinearVelocityFromWorldPoint(worldAnchor)
- v.body:applyForce((1/1) * diff * gain - vel * damp, worldAnchor)
- line(touchPoint.x, touchPoint.y, worldAnchor.x, worldAnchor.y)
- end
- popStyle()
- end
- function Objects:drawJoints()
- pushStyle()
- stroke(0,255,0,255)
- strokeWidth(5)
- for k,joint in pairs(self.joints) do
- local a = joint.anchorA
- local b = joint.anchorB
- line(a.x,a.y,b.x,b.y)
- end
- popStyle()
- end
- function Objects:drawObjects()
- local defaultColor = color(255, 255, 255, 255)
- for i,body in ipairs(self.bodies) do
- pushMatrix()
- pushStyle()
- if body.info == nil then
- body.info = {}
- end
- local lineWidth = body.info.lineWidth
- if lineWidth and lineWidth > 0 then
- stroke(body.info.lineColor or defaultColor)
- strokeWidth(lineWidth)
- else
- noStroke()
- lineWidth = 0
- end
- if body.info.fillColor then
- fill(body.info.fillColor)
- else
- noFill()
- end
- translate(body.x, body.y)
- rotate(body.angle)
- if body.shapeType == POLYGON then
- local points = body.points
- if body.info.isRect == true then
- local x1 = points[1][1]
- local y1 = points[1][2]
- local x2 = points[3][1]
- local y2 = points[3][2]
- rectMode(CORNERS)
- rect(x1, y1, x2, y2)
- else
- for j = 1,#points do
- a = points[j]
- b = points[(j % #points)+1]
- line(a.x, a.y, b.x, b.y)
- end
- end
- elseif body.shapeType == CHAIN or body.shapeType == EDGE then
- local points = body.points
- for j = 1,#points-1 do
- a = points[j]
- b = points[j+1]
- line(a.x, a.y, b.x, b.y)
- end
- elseif body.shapeType == CIRCLE then
- ellipse(0,0,body.radius*2)
- if lineWidth > 0 then
- pushMatrix()
- pushStyle()
- strokeWidth(lineWidth * 2)
- for r = 0, 2 do
- rotate(120)
- line(0, 0, body.radius - 3, 0)
- end
- popStyle()
- popMatrix()
- end
- end
- popStyle()
- popMatrix()
- end
- end
- function Objects:drawContacts()
- pushStyle()
- stroke(255, 0, 0, 255)
- fill(255, 0, 0, 255)
- for k,v in pairs(self.contacts) do
- for m,n in ipairs(v.points) do
- ellipse(n.x, n.y, 10, 10)
- end
- end
- popStyle()
- end
- function Objects:draw()
- self:drawTouchVector()
- self:drawJoints()
- self:drawObjects()
- self:drawContacts()
- end
- function Objects:touched(touch)
- local touchPoint = vec2(touch.x , touch.y)
- if touch.state == BEGAN then
- for i,body in ipairs(self.bodies) do
- if body:testPoint(touchPoint) then
- local anchor = body:getLocalPoint(touchPoint)
- self.touchMap[touch.id] = {tp = touchPoint, body = body, anchor = anchor}
- return true
- end
- end
- elseif touch.state == MOVING and self.touchMap[touch.id] then
- self.touchMap[touch.id].tp = touchPoint
- return true
- elseif touch.state == ENDED and self.touchMap[touch.id] then
- self.touchMap[touch.id] = nil
- return true;
- end
- return false
- end
- function Objects:collide(contact)
- if contact.state == BEGAN then
- self.contacts[contact.id] = contact
- sound(SOUND_HIT, 2643)
- elseif contact.state == MOVING then
- self.contacts[contact.id] = contact
- elseif contact.state == ENDED then
- self.contacts[contact.id] = nil
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement