Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Main
- -- APlayer
- -- Use this function to perform your initial setup
- function setup()
- displayMode(FULLSCREEN)
- ply = Player(WIDTH/2,HEIGHT/2,vec2(120,120),180)
- dt=1 -- or 60/(1/DeltaTime), experimental
- tchs = {}
- pts = {}
- pts[0] = vec2()
- --level generator
- for i=1,1000 do
- table.insert(pts,pts[i-1]+vec2(math.random(10,20),math.sin(i/10)*10+
- noise(i/2,i*2)*(5+i/100)))
- end
- lvm = TMesh(pts,10)
- parameter.integer("SurfaceTexType",1,10,1,function()
- if SurfaceTexType == 1 then
- lvm.m.texture = readImage("Cargo Bot:Register Slot")
- end
- if SurfaceTexType == 2 then
- lvm.m.texture = readImage("Cargo Bot:Game Area Floor")
- end
- if SurfaceTexType == 3 then
- lvm.m.texture = readImage("Planet Cute:Brown Block")
- end
- if SurfaceTexType == 4 then
- lvm.m.texture = readImage("Planet Cute:Dirt Block")
- end
- if SurfaceTexType == 5 then
- lvm.m.texture = readImage("Planet Cute:Grass Block")
- end
- if SurfaceTexType == 6 then
- lvm.m.texture = readImage("Planet Cute:Stone Block")
- end
- if SurfaceTexType == 7 then
- lvm.m.texture = readImage("Planet Cute:Wall Block")
- end
- if SurfaceTexType == 8 then
- lvm.m.texture = readImage("Planet Cute:Water Block")
- end
- if SurfaceTexType == 9 then
- lvm.m.texture = readImage("Planet Cute:Wood Block")
- end
- if SurfaceTexType == 10 then
- lvm.m.texture = readImage("Platformer Art:Water")
- end
- end)
- parameter.integer("GroundTexType",1,2,1,function()
- if GroundTexType == 1 then
- lvm.t.texture = readImage("Cargo Bot:Starry Background")
- end
- if GroundTexType == 2 then
- lvm.t.texture = readImage("Tyrian Remastered:Panel Opening 2")
- end
- end)
- bvm = mesh()
- bvm.texture = readImage("Space Art:UFO")
- balls={}
- for i=1,50 do
- balls[i]={}
- balls[i].body = physics.body(CIRCLE,math.random(5,10))
- balls[i].body.position = ply:getPos()+vec2(math.random(-50,50),500+math.random(0,500))
- balls[i].r = bvm:addRect(10,10,10,10)
- end
- physics.continuous = true
- physics.iterations(10,8)
- floor = physics.body(CHAIN,false,unpack(pts))
- floor.info = "level"
- floor.categories = {0,2}
- scr = vec2(WIDTH/2,HEIGHT/2)
- end
- function treadImage(str)
- local tbl = {}
- tbl.img = readImage(str)
- tbl.str = str
- return tbl
- end
- function moveScreen()
- local ball = ply:getPos()-vec2(WIDTH/2,HEIGHT/3)
- spos = ball
- if scr.x~=ball.x and scr.y~=ball.y then
- scr = scr + ((vec2(WIDTH/2,HEIGHT/2)-ball)-scr)
- end
- local mt = vec2(WIDTH,HEIGHT*0.3)*0.5-vec2(WIDTH,HEIGHT*0.3)*0.5
- translate(-ball.x+mt.x,-ball.y+mt.y)
- end
- function touched(t)
- if t.state == BEGAN then
- local jpos,jsize = ply.joypos,ply.joysize
- local epos,esize = ply.epos,ply.esize
- if vec2(t.x,t.y):dist(jpos) < jsize/2 then
- table.insert(tchs,{t,ply,"ply"})
- elseif vec2(t.x,t.y):dist(epos) < esize/2 then
- table.insert(tchs,{t,ply,"jump"})
- else
- table.insert(tchs,{t,ply,"look"})
- end
- end
- for k,v in pairs(tchs) do
- if t.id == v[1].id then
- tchs[k][1] = t
- tchs[k][2]:touched(tchs[k])
- if v[1].state == ENDED then
- tchs[k] = nil
- end
- end
- end
- end
- function collide(c) ply:collide(c) end
- function sign(x)
- if x>0 then return 1 elseif x < 0 then return -1 else return 0 end
- end
- function angleOfPoint( pt )
- local x, y = pt.x, pt.y
- local radian = math.atan2(y,x)
- local angle = radian*180/math.pi
- if angle < 0 then angle = 360 + angle end
- return angle
- end
- -- This function gets called once every frame
- function draw()
- -- This sets a dark background color
- background(40, 40, 50)
- -- This sets the line thickness
- strokeWidth(5)
- -- Do your drawing here
- pushMatrix()
- moveScreen()
- lvm:draw()
- for k,v in pairs(balls) do
- bvm:setRect(v.r,v.body.x,v.body.y,v.body.radius*2,v.body.radius*2,math.rad(v.body.angle))
- end
- bvm:draw()
- ply:draw()
- popMatrix()
- ply:drawJoystick()
- end
- flipshadr = {vS = [[//
- // A basic vertex shader
- //
- //This is the current model * view * projection matrix
- // Codea sets it automatically
- uniform mat4 modelViewProjection;
- //This is the current mesh vertex position, color and tex coord
- // Set automatically
- attribute vec4 position;
- attribute vec4 color;
- attribute vec2 texCoord;
- //This is an output variable that will be passed to the fragment shader
- varying lowp vec4 vColor;
- varying highp vec2 vTexCoord;
- void main()
- {
- //Pass the mesh color to the fragment shader
- vColor = color;
- vTexCoord = texCoord;
- //Multiply the vertex position by our combined transform
- gl_Position = modelViewProjection * position;
- }
- ]],fS = [[
- //
- // A basic fragment shader
- //
- //Default precision qualifier
- precision highp float;
- //This represents the current texture on the mesh
- uniform lowp sampler2D texture;
- uniform highp vec2 flip;
- //The interpolated vertex color for this fragment
- varying lowp vec4 vColor;
- //The interpolated texture coordinate for this fragment
- varying highp vec2 vTexCoord;
- void main()
- {
- //Sample the texture at the interpolated coordinate
- lowp vec4 col = vec4(0,0,0,0);
- mediump vec2 tx = vTexCoord.st;
- if(flip.x==-1.0) tx.x = 1.0 - tx.x;
- if(flip.y==-1.0) tx.y = 1.0 - tx.y;
- col = texture2D( texture, tx)
- * vColor;
- //Set the output color to the texture color
- gl_FragColor = col;
- }
- ]]}
- --# Player
- Player = class()
- function Player:init(x,y,jpos,jsize)
- self.pos = vec2(x,y)
- self.vel = vec2(0,0)
- self.alive = true
- self.plyv = {vec2(-13,-11),vec2(-14,21),vec2(-8,27),
- vec2(-1,29),vec2(7,27),vec2(15,20),
- vec2(15,-9),vec2(10,-15),vec2(1,-18),
- vec2(-8,-16)}
- self.rca = nil
- self.rcb = nil
- self.ply = physics.body(POLYGON,unpack(self.plyv))
- self.ply.friction = 0.5
- self.ply.restitution = 0.4
- self.ply.position = vec2(x,y)
- self.ply.type = STATIC
- self.ply.linearVelocity = vec2(0,0)
- self.ply.categories = {4}
- self.ply.info = "ply"
- local verts = {vec2(-13,14),vec2(-16,4),vec2(-23,0),
- vec2(-17,0),vec2(-13,-17),vec2(-5,-22),
- vec2(10,-22),vec2(16,-15),vec2(19,0),
- vec2(24,0),vec2(20,4),vec2(15,14),
- vec2(5,19),vec2(-4,19)}
- self.head = physics.body(POLYGON,unpack(verts))
- self.head.friction = 0.5
- self.head.density = 1
- self.head.restitution = 0.4
- self.head.position = vec2(x,y+35)
- self.head.type = STATIC
- self.head.info = "head"
- self.head.categories = {4}
- self.head.linearVelocity = vec2()
- self.neck = physics.joint(REVOLUTE,self.ply,self.head,self.head.position+vec2(0,-30))
- self.neck.enableLimit = true
- self.neck.lowerLimit = -45
- self.neck.upperLimit = 45
- self.plym = mesh()
- self.plyr = self.plym:addRect(x,y,40,80,0)
- self.plym.shader = shader(flipshadr.vS,flipshadr.fS)
- self.plym.shader.flip = vec2(-1,1)
- self.plym.texture = readImage("Small World:Grass Patch")
- self.headm = mesh()
- self.headr = self.headm:addRect(x,y,60,60)
- self.headm.shader = shader(flipshadr.vS,flipshadr.fS)
- self.headm.shader.flip = vec2(-1,1)
- self.headm.texture = readImage("Small World:Grass Patch")
- self.joypos = jpos
- self.epos = vec2(WIDTH-jsize/2-25,jpos.y)
- self.esize = jsize
- self.joysize = jsize
- self.jactive = false
- self.joff = vec2()
- self.lookpos = vec2(x+600,y)
- self.speed = 450
- self.jump = nil
- self.dir = 1
- self.lp = false
- self.mdir = self.dir
- local verts = {vec2(-9,0),vec2(-9,-4),vec2(-5,-6),vec2(0,-6),vec2(5,-6),vec2(9,-5),vec2(10,-3),vec2(10,3),vec2(7,6),vec2(4,5),vec2(2,4),vec2(-2,5),vec2(-6,4)}
- for i=1,#verts do
- verts[i] = verts[i]*1.5
- end
- self.sj = nil
- self.lt = physics.body(POLYGON,unpack(verts))
- self.lt.position = vec2(x-10,y-50)
- self.lt.angularDamping = 0.1
- self.lt.friction = 1.5
- self.lt.type = STATIC
- self.lt.bullet = true
- self.lt.density = 1
- self.lt.categories = {3}
- self.lt.mask = {0,1}
- self.lt.info = "foot"
- self.rt = physics.body(POLYGON,unpack(verts))
- self.rt.position = vec2(x+10,y-50)
- self.rt.angularDamping = 0.1
- self.rt.friction = 1.5
- self.rt.bullet = true
- self.rt.type = STATIC
- self.rt.density = 1
- self.rt.categories = {3}
- self.rt.mask = {0,1}
- self.rt.info = "foot"
- self.lm = mesh()
- self.lm.texture = readImage("Small World:Grass Patch")
- self.lt.info = self.lm:addRect(self.lt.x,self.lt.y,10,30)
- self.rt.info = self.lm:addRect(self.rt.x,self.rt.y,10,30)
- self.lm.shader = shader(flipshadr.vS,flipshadr.fS)
- self.lm.shader.flip = vec2(-self.dir,1)
- self.lm:setColors(255,255,255,255)
- self.hm = mesh()
- self.hm.texture = readImage("Small World:Grass Patch")
- self.hm.shader = shader(flipshadr.vS,flipshadr.fS)
- self.hm.shader.flip = vec2(-1,self.dir)
- self.hr = self.hm:addRect(x+30,y,20,18)
- self.wt = -2
- self.dt = vec2(x,y)
- self.recoil = vec2()
- self.prevang = 0
- self.lookvel = vec2()
- self.tw = nil
- self.killed = false
- self.ktime = 0
- self.dtt = nil
- self.rv = 0
- self.tp = nil
- self.ftouch = false
- self:flipTex(true)
- self.tbox = nil
- self:setState(DYNAMIC)
- end
- function Player:isAlive()
- return self.alive
- end
- function Player:getState()
- if (self.ply.type+self.lt.type+self.rt.type+self.head.type)/4 == DYNAMIC then return DYNAMIC else return STATIC end
- end
- function Player:setState(state)
- self.ply.type = state self.lt.type = state self.rt.type = state self.head.type = state
- end
- function Player:getPos()
- return self.ply.position
- end
- function Player:setPos(x,y)
- local pos = vec2(x,y)
- self.ply.position = pos+vec2(0,30)
- self.head.position = self.ply.position+vec2(0,40)
- self.lt.position = self.ply.position+vec2(-10,-50)
- self.rt.position = self.ply.position+vec2(10,-50)
- end
- function Player:joyOffset()
- return self.joff
- end
- function Player:getVelocity()
- return self.ply.linearVelocity
- end
- function Player:flipTex(flip)
- if self.dir == nil then return end
- local dir = -self.dir
- if flip then dir = -dir end
- self.plym.shader.flip = vec2(-dir,1)
- self.headm.shader.flip = vec2(-dir,1)
- self.hm.shader.flip = vec2(-1,dir)
- self.lm.shader.flip = vec2(-dir,1)
- end
- function Player:stopActions()
- self.joff = vec2()
- self.jactive = false
- self.vel = vec2()
- self.jump = nil
- end
- function Player:walk(vel)
- local ply = self.ply
- self.vel = vec2(vel.x,ply.linearVelocity.y)
- if sign(self.vel.x) ~= 0 then
- if sign(self.vel.x)~=self.dir then
- self.lookpos = ply.position
- self.mdir = sign(self.vel.x)
- --self.dir = self.mdir
- end
- end
- --self.wt = self.wt+0.001*(dt*0.7+0.3)*self.vel.x*0.6
- --self.wt = self.wt+self.vel.x*0.0006
- end
- function Player:applyForce(force)
- self.ply:applyForce(force*self.ply.mass*dt)
- self.lt:applyForce(force*self.lt.mass*dt*0.5)
- self.rt:applyForce(force*self.rt.mass*dt*0.5)
- self.head:applyForce(force*self.head.mass*dt*0.05)
- end
- function Player:applyLinearImpulse(force)
- self.ply:applyLinearImpulse(((force-self.ply.linearVelocity/32)*self.ply.mass)/32)
- self.lt:applyLinearImpulse(((force-self.lt.linearVelocity/32)*self.lt.mass)/32)
- self.rt:applyLinearImpulse(((force-self.rt.linearVelocity/32)*self.rt.mass)/32)
- --self.head:applyLinearImpulse(force*self.head.mass)
- end
- function Player:setVelocity(vel)
- self.ply.linearVelocity = vel
- self.lt.linearVelocity = vel
- self.rt.linearVelocity = vel
- self.head.linearVelocity = vel
- end
- function Player:correctFeet()
- if self.lt.angle > 40 then
- self.lt.angle = 45
- elseif self.lt.angle < -45 then
- self.lt.angle = -45
- end
- if self.rt.angle > 45 then
- self.rt.angle = 45
- elseif self.rt.angle < -45 then
- self.rt.angle = -45
- end
- end
- function Player:destroy()
- self.rt:destroy()
- self.lt:destroy()
- self.ply:destroy()
- self.head:destroy()
- self.neck:destroy()
- end
- function Player:kill()
- if not self.alive or playing == "death" then return end
- self.ply.fixedRotation = false
- while self.ply.angle > 180 do
- self.ply.angle = self.ply.angle - 360
- end
- while self.ply.angle < -180 do
- self.ply.angle = self.ply.angle + 360
- end
- while self.lt.angle > 180 do
- self.lt.angle = self.lt.angle - 360
- end
- while self.lt.angle < -180 do
- self.lt.angle = self.lt.angle + 360
- end
- while self.rt.angle > 180 do
- self.rt.angle = self.rt.angle - 360
- end
- while self.rt.angle < -180 do
- self.rt.angle = self.rt.angle + 360
- end
- while self.head.angle > 180 do
- self.head.angle = self.head.angle - 360
- end
- while self.head.angle < -180 do
- self.head.angle = self.head.angle + 360
- end
- self:stopActions()
- self.alive = false
- self.killed = true
- self.lookvel = vec2()
- self.neck.lowerLimit = -80
- self.neck.upperLimit = 80
- self.head.density = 0.5
- self.head.angularVelocity = 0
- self:stopWalk()
- if self.tw then tween.stop(self.tw) self.tw = nil end
- self.tw = tween.delay(1.5,function() self:revive() end)
- end
- function Player:findLegs()
- local found = true
- local ply,lt,rt = self.ply,self.lt,self.rt
- if lt.position:dist(ply.position) > 40 then
- local rcl = physics.raycast(lt.position,lt.position+(ply.position-lt.position):normalize()*60-vec2(0,-10),0,1)
- if rcl and rcl.fraction<0.7 then
- lt:applyForce(rcl.normal*(1-rcl.fraction)*7.5+vec2(0,15)+vec2((lt.position-ply.position).x,0):normalize()*5)
- elseif not rcl or (rcl and rcl.fraction>0.7) then
- lt:applyForce(vec2((ply.position-lt.position).x,0):normalize()*30-vec2(lt.linearVelocity.x/10,0))
- if lt.y<ply.y-5 then
- lt:applyForce(vec2(0,15))
- end
- end
- found = false
- end
- if rt.position:dist(ply.position) > 40 then
- local rcr = physics.raycast(rt.position,rt.position+(ply.position-rt.position):normalize()*60-vec2(0,-10),0,1)
- if rcr and rcr.fraction<0.7 then
- rt:applyForce(rcr.normal*(1-rcr.fraction)*7.5+vec2(0,15)+vec2((rt.position-ply.position).x,0):normalize()*5)
- elseif not rcr or (rcr and rcr.fraction>0.7) then
- rt:applyForce(vec2((ply.position-rt.position).x,0):normalize()*30-vec2(rt.linearVelocity.x/10,0))
- if rt.y<ply.y-5 then
- rt:applyForce(vec2(0,15))
- end
- end
- found = false
- end
- if found then
- local rc = physics.raycast(ply.position,ply.position-vec2(0,50),0)
- if rc then
- ply.linearVelocity = vec2(0,20)
- self.head.linearVelocity = vec2(0,80)
- local ang = (0-ply.angle)
- while ang > 180 do
- ang = ang - 360
- end
- while ang < -180 do
- ang = ang + 360
- end
- --ply.angularVelocity = ply.angularVelocity+ang-ply.angularVelocity/10
- if rc.fraction<0.6 then
- found = false
- end
- else
- found = true
- end
- end
- local pla = ply.angle
- while pla > 180 do
- pla = pla - 360
- end
- while pla < -180 do
- pla = pla + 360
- end
- if found then
- if pla>-90 and pla<90 then
- found = true
- else
- found = false
- end
- end
- if ((self.lt.position+self.rt.position)/2-self.ply.position):len()>900 then
- playing = nil
- cod = "You died from not being able to find your legs."
- end
- if not found and not self.killed then
- tween.delay(0.03,function() self:findLegs() end)
- else
- self.alive = true
- for i=1,10 do
- tween.delay(0.02*i,function() self:setVelocity(vec2()) end)
- end
- self.killed = false
- ply.angle = pla
- end
- end
- function Player:revive()
- self.killed = false
- if self.tw then tween.stop(self.tw) self.tw = nil end
- if ((self.lt.position+self.rt.position)/2-self.ply.position):len()<900 then
- --self.alive = true
- --self:setPos(self.ply.x,self.ply.y+40)
- self:findLegs()
- self.neck.lowerLimit = -45
- self.neck.upperLimit = 45
- self.head.density = 0.5
- end
- end
- function Player:collide(c)
- if not c.bodyA then return end
- if c.bodyA.info and c.bodyA.info == "head" then
- if c.normalImpulse>4 then
- self:kill()
- end
- end
- end
- function Player:papplyForce(force)
- self.ply.linearVelocity = self.ply.linearVelocity*0.98 + force
- end
- function Player:raycast(pos,pos2,...)
- local rc = physics.raycastAll(pos,pos2,...)
- local cent = {nil,math.huge}
- if not rc then return nil end
- for k,v in pairs(rc) do
- if v.body.info ~= "foot" then
- if v.point:dist(pos)<cent[2] then
- cent = {v,v.point:dist(pos)}
- end
- end
- end
- return cent[1]
- end
- function Player:getViewAngle()
- return angleOfPoint(self.lookpos-self:getPos())
- end
- function Player:draw()
- local pl = self.ply
- local lt = self.lt
- local rt = self.rt
- local rtang = math.rad(self.rt.angle)
- local ltang = math.rad(self.lt.angle)
- local head = self.head
- local jump = self.jump
- local alive = self.alive
- local joff = self.joff
- local norm = vec2()
- local lv = 0
- local angadd = 0
- local sp = self:getPos()
- local pos = sp
- local dir = self.dir
- local tp = vec2(sp.x+(head.x-sp.x),sp.y)
- self.tp = tp
- local lp = self.lookpos
- local dtt = (lp-pos):normalize()*math.min(math.max(lp:dist(sp),1),40)
- if sign(lp.x-sp.x)~=self.dir then
- self.dir = sign(lp.x-sp.x)
- if not self.dir then
- self.dir = 1
- else
- self:flipTex(true)
- self.lm.shader.flip = vec2(-self.dir,1)
- end
- end
- if dtt ~= dtt then
- dtt = vec2(40,25)
- end
- if not self.ftouch and self.vel:len()>0 then
- --self:kill()
- self.ftouch = true
- end
- self.dtt = dtt
- pos = pos+dtt
- ellipse(lp.x,lp.y,20)
- local ptos = dtt
- local ang = math.rad(angleOfPoint(lp-sp))
- local ptang = ang
- local npos = vec2()
- local gpos = pos + self.recoil/10
- self.hm:setRect(self.hr,gpos.x-dtt.x*0.5,gpos.y-dtt.y*0.5,20,18,ang)
- local kneepos = pl.position+vec2(0,-60)+pl.linearVelocity/32
- if joff.y<-0.4 then
- -- kneepos = pl.position+vec2(0,-45)
- end
- local wt = self.wt
- local vel = self.vel
- local plvel = pl.linearVelocity
- --Foot gap distance
- local len = math.min(10+20*(math.abs(vel.x)/600+0.3),40)
- if joff.y<-0.4 then
- len = math.min(10+15*(math.abs(vel.x)/1000+0.4),30)
- end
- self.plym:setRect(self.plyr,sp.x,sp.y,30,40,math.rad(pl.angle))
- self.headm:setRect(self.headr,head.x,head.y,50,50,math.rad(head.angle))
- pushStyle()
- strokeWidth(5)
- --Toe and Heel raycast
- self.rcat = self:raycast(lt.position+vec2(1*dir,-5):rotate(math.rad(lt.angle)),
- lt.position+vec2(9*dir,-16):rotate(math.rad(lt.angle)),0)
- self.rcah = self:raycast(lt.position+vec2(-1*dir,-5):rotate(math.rad(lt.angle)),
- lt.position+vec2(-9*dir,-16):rotate(math.rad(lt.angle)),0)
- self.rcbt = self:raycast(rt.position+vec2(1*dir,-5):rotate(math.rad(rt.angle)),
- rt.position+vec2(9*dir,-16):rotate(math.rad(rt.angle)),0)
- self.rcbh = self:raycast(rt.position+vec2(-1*dir,-5):rotate(math.rad(rt.angle)),
- rt.position+vec2(-9*dir,-16):rotate(math.rad(rt.angle)),0)
- --Debug drawing for feet
- local p1,p2,p3,p4
- p1,p2 = lt.position+vec2(9*dir,-16):rotate(math.rad(lt.angle)),rt.position+vec2(9*dir,-16):rotate(math.rad(rt.angle))
- p3,p4 = lt.position+vec2(1*dir,-5):rotate(math.rad(lt.angle)),rt.position+vec2(1*dir,-5):rotate(math.rad(rt.angle))
- if self.rcat then
- p1 = self.rcat.point
- end
- line(p3.x,p3.y,p1.x,p1.y)
- if self.rcbt then
- p2 = self.rcbt.point
- end
- line(p4.x,p4.y,p2.x,p2.y)
- stroke(255,50,50)
- p1,p2 = lt.position+vec2(-9*dir,-16):rotate(math.rad(lt.angle)),rt.position+vec2(-9*dir,-16):rotate(math.rad(rt.angle))
- p3,p4 = lt.position+vec2(1*dir,-5):rotate(math.rad(lt.angle)),rt.position+vec2(-1*dir,-5):rotate(math.rad(rt.angle))
- if self.rcah then
- p1 = self.rcah.point
- end
- line(p3.x,p3.y,p1.x,p1.y)
- if self.rcbh then
- p2 = self.rcbh.point
- end
- line(p4.x,p4.y,p2.x,p2.y)
- popStyle()
- --End debug drawing
- local rc = self.rcat or self.rcah
- local rc2 = self.rcbt or self.rcbh
- if self.jump and rc and rc2 then
- rc = nil
- rc2 = nil
- self.lt:applyForce(vec2(0,-self.jump.y/5))
- self.rt:applyForce(vec2(0,-self.jump.y/5))
- --self:papplyForce(vec2(0,0))
- tween.delay(0.01,function()
- if self.jump then
- self:setVelocity(vec2((self.vel.x*3)+pl.linearVelocity.x/32,self.jump.y*5))
- self.lt:applyForce(vec2(0,self.jump.y/5))
- self.rt:applyForce(vec2(0,self.jump.y/5))
- end
- end)
- end
- local angg = 0
- local pla = pl.angle
- while pla > 180 do
- pla = pla - 360
- end
- while pla < -180 do
- pla = pla + 360
- end
- --Upright the body
- if alive then
- local ang = (angg-pla)
- while ang > 180 do
- ang = ang - 360
- end
- while ang < -180 do
- ang = ang + 360
- end
- pl.angularVelocity = (ang-pl.angularVelocity/10)*dt*2
- end
- local fpos = ((rt.position+lt.position)/2)+vec2(0,60)
- local ltpos,rtpos = lt.position,rt.position
- local rcd = self:raycast(pl.position+vec2(0,-30):rotate(math.rad(pl.angle)),pl.position+vec2(0,-120):rotate(math.rad(pl.angle)),0)
- if (rc or rc2) and alive and not jump then
- kneepos = pl.position+vec2(0,-60)
- self.hm:setRect(self.hr,gpos.x-dtt.x*0.5,gpos.y-dtt.y*0.5,20,18,math.rad(angleOfPoint(lp-sp)))
- self.prevang = ang
- self:papplyForce(vec2(self.recoil.x*5,self.recoil.y*2.5))
- local plv = vec2(pl.linearVelocity.x,pl.linearVelocity.y*2)
- if joff.y<-0.4 then
- else
- end
- if rcd then
- norm = rcd.normal
- end
- local pf = false
- if rc and rc2 then
- if rc.body == rc2.body then
- if rc.body.mass>3 and rc2.body.mass>3 then
- pf = true
- end
- end
- end
- local rca = rcd
- if pf and rca then
- pl:applyLinearImpulse(rca.body.linearVelocity*rca.body.mass*0.1*pl.mass/42)
- lt:applyLinearImpulse(rca.body.linearVelocity*rca.body.mass*0.1*lt.mass/36)
- rt:applyLinearImpulse(rca.body.linearVelocity*rca.body.mass*0.1*rt.mass/36)
- end
- if self.ktime>0.4 then self:kill() self:revive() end
- if norm:len() ~= norm:len() then norm = vec2(0,1) end
- local ang = (angleOfPoint(norm)-90)
- local gad = (ang/90)*-dir
- local gda = (ang/90)*dir
- gda = norm.x*dir
- local grad = 1+(ang/90)*-dir
- if rcd and rcd.body.type == DYNAMIC then
- ang = 0
- grad = 1
- gad = 0
- gda = 0
- norm.y = 1
- norm.x = 0
- end
- self:applyLinearImpulse(vec2(0,(-vel.x)*0.2*
- (grad)):rotate(math.rad(ang*0.9+90))/(1+math.abs(pl.x-(lt.x+rt.x)/2)*0.1))
- local move = 1
- if self.joff:len()>0 then move = 0 end
- local rcf,rcf2
- if rc then
- if self.rcat or self.rcah then
- rcf = true
- end
- end
- if rc2 then
- if self.rcbt or self.rcbh then
- rcf2 = true
- end
- end
- --If feet are not touching the ground, this needs tweaking
- if math.cos(self.wt-gda)>=0.01 then
- self.wt = wt + (math.sin(self.wt+math.pi/2-gda)*dir)*move*0.1
- end
- if math.cos(self.wt+math.pi-gda)>=0.01 then
- self.wt = wt + (math.sin(self.wt-math.pi/2-gda)*dir)*move*0.1
- end
- --Debug drawing
- pushStyle()
- pushMatrix()
- translate(pl.x,pl.y)
- strokeWidth(3)
- stroke(255)
- fill(255)
- text(math.ceil(gda*100)/100,0,100)
- line(100,100,100,200)
- line(90,100-math.min(math.cos(self.wt-math.rad(ang)),0)*100,110,100-math.min(math.cos(self.wt-math.rad(ang))*100,0))
- text(math.ceil(math.min(math.cos(self.wt-math.rad(ang)),0)*100)/100,70,100-math.min(math.cos(self.wt-math.rad(ang)),0)*100)
- line(150,100,150,200)
- line(140,100-math.min(math.cos(self.wt+math.pi-math.rad(ang)),0)*100,160,100-math.min(math.cos(self.wt+math.pi-math.rad(ang))*100,0))
- text(math.ceil(math.min(math.cos(self.wt+math.pi-math.rad(ang)),0)*100)/100,180,100-math.min(math.cos(self.wt+math.pi-math.rad(ang)),0)*100)
- popMatrix()
- popStyle()
- --End debug drawing
- --This makes the feet turn, wt = walking time, grad = floor gradient
- if self.joff.x~=0 and not self.jump then
- self.wt = self.wt + (self.vel.x*0.00055)*((grad-1)*0.5+1)
- end
- --Check if the joystick is being used
- if self.jactive then
- self:walk(self.joff*self.speed)
- end
- --A bit of grip, can be made stronger but this works well
- if rcd then
- pl:applyForce(pl.mass*((rcd.point-pl.position)))
- end
- --The footwork
- if not self.jump then
- if rc or not rc2 then
- local pros
- local pnorm
- fpos = nil
- --Check if the foot should be touching the floor, gda = ground angle from -1 to 1, 1 being 90
- if math.cos(self.wt)<=gda then
- if self.rcat then
- pros = self.rcat.point
- lt.angularVelocity = lt.angularVelocity+5*-dir-lt.angularVelocity/20
- if not self.rcah then
- lt:applyForce(lt.mass*((pros-lt.position)*4-lt.linearVelocity))
- end
- end
- if self.rcah then
- pros = self.rcah.point
- lt.angularVelocity = lt.angularVelocity+5*dir-lt.angularVelocity/20
- if not self.rcat then
- lt:applyForce(lt.mass*((pros-lt.position)*4-lt.linearVelocity))
- end
- end
- if self.rcat and self.rcah then
- pnorm = (self.rcat.normal+self.rcah.normal)/2
- pros = (self.rcat.point+self.rcah.point)/2+pnorm*0
- ltpos = pros
- lt:applyLinearImpulse(lt.mass*((pros-lt.position)*16-lt.linearVelocity)/32)
- lt.linearVelocity=lt.linearVelocity*0.1
- end
- else
- ltpos = (vec2(math.sin(self.wt)*(len+5),
- math.cos(self.wt)*math.max(len,0)):rotate(math.rad(ang))+kneepos)
- end
- --pros = ((pros+(lt.position+rt.position)/2+pl.position+vec2(0,120))/3)
- local pti = vec2(self.vel.x*0.035,0):rotate(math.rad(ang))
- pti.y = math.min(pti.y,0)
- pl:applyForce(pl.mass*(((lt.position+rt.position)/2+vec2(pti.x,60+pti.y)-pl.position)*32-
- pl.linearVelocity))
- rtpos = (vec2(math.sin(self.wt+math.pi)*(len+5),
- math.cos(self.wt+math.pi)*math.max(len,0)):rotate(math.rad(ang))+kneepos+pti)
- end
- if rc2 or not rc then
- local pros
- local pnorm
- fpos = nil
- if math.cos(self.wt+math.pi)<=gda then
- if self.rcbt then
- pros = self.rcbt.point
- rt.angularVelocity = rt.angularVelocity+5*-dir-rt.angularVelocity/20
- if not self.rcbh then
- rt:applyForce(rt.mass*((pros-rt.position)*4-rt.linearVelocity))
- end
- end
- if self.rcbh then
- pros = self.rcbh.point
- rt.angularVelocity = rt.angularVelocity+5*dir-rt.angularVelocity/20
- if not self.rcbt then
- rt:applyForce(rt.mass*((pros-rt.position)*4-rt.linearVelocity))
- end
- end
- if self.rcbt and self.rcbh then
- pnorm = (self.rcbt.normal+self.rcbh.normal)/2
- pros = (self.rcbt.point+self.rcbh.point)/2+pnorm*0
- rtpos = pros
- rt:applyLinearImpulse(rt.mass*((pros-rt.position)*16-rt.linearVelocity)/32)
- rt.linearVelocity=rt.linearVelocity*0.1
- end
- else
- rtpos = (vec2(math.sin(self.wt+math.pi)*(len+5),
- math.cos(self.wt+math.pi)*math.max(len,0)):rotate(math.rad(ang))+kneepos)
- end
- --pros = ((pros+(lt.position+rt.position)/2+pl.position+vec2(0,120))/3)
- local pti = vec2(self.vel.x*0.035,0):rotate(math.rad(ang))
- pti.y = math.min(pti.y,0)
- pl:applyForce(pl.mass*(((lt.position+rt.position)/2+vec2(pti.x,60+pti.y)-pl.position)*32-
- pl.linearVelocity))
- ltpos = (vec2(math.sin(self.wt)*(len+5),
- math.cos(self.wt)*math.max(len,0)):rotate(math.rad(ang))+kneepos+pti)
- end
- end
- local mng = ang--+math.sin(self.wt)*15+(15*dir)
- lt.angularVelocity = lt.mass*((mng-lt.angle)*32-lt.angularVelocity)
- rt.angularVelocity = rt.mass*((mng-rt.angle)*32-rt.angularVelocity)
- elseif alive then
- ltpos = (vec2(math.sin(self.wt)*len*0.5*dir,0)+kneepos)
- rtpos = (vec2(math.sin(self.wt+math.pi)*len*0.5*dir,0)+kneepos)
- self:papplyForce(self.recoil*0.55)
- --Gravity does not work so well so we need to give it a little push
- if pl.linearVelocity.y<=0 then
- pl.linearVelocity.y = pl.linearVelocity.y*1.1
- end
- if lt.linearVelocity.y<=0 then
- lt.linearVelocity.y = lt.linearVelocity.y*1.1
- end
- if rt.linearVelocity.y<=0 then
- rt.linearVelocity.y = rt.linearVelocity.y*1.1
- end
- self:applyForce(vec2(0,-20))
- --Simple foot correction
- local mng = 0
- lt.angularVelocity = lt.mass*((mng-lt.angle)*32-lt.angularVelocity)
- rt.angularVelocity = rt.mass*((mng-rt.angle)*32-rt.angularVelocity)
- if math.cos(self.wt)>0.1 and math.cos(self.wt+math.pi)>0.1 then
- self.wt = wt + 0.1*dir*move
- end
- self:walk(self.joff*self.speed*0.2)
- end
- if alive then
- local px = lp.x-(pl.x)
- if px == 0 then px = 1 end
- if math.abs(px)<200 then
- px = sign(px)*200
- end
- if head.angle > 60 then
- head.angle = 60
- end
- if head.angle < -60 then
- head.angle = -60
- end
- local angle = angleOfPoint(vec2(sign(px)*200,lp.y+50-pl.y))+90-100*sign(px)
- while angle > 180 do
- angle = angle - 360
- end
- while angle < -180 do
- angle = angle + 360
- end
- local ang = (angle-head.angle)
- --ply angle normalising
- while ang > 180 do
- ang = ang - 360
- end
- while ang < -180 do
- ang = ang + 360
- end
- head.angularVelocity = (ang*25-head.angularVelocity/10)
- while math.abs(head.angularVelocity)>300 do
- head.angularVelocity = head.angularVelocity*0.9
- end
- --text(math.ceil(ang),head.x,head.y+50)
- --text(math.ceil(head.angularVelocity),head.x,head.y+100)
- end
- --Apply the force luke!
- if alive then
- if fpos then
- pl:applyForce(pl.mass*((fpos-pl.position)*32-pl.linearVelocity/32))
- lt:applyForce(lt.mass*((ltpos-lt.position)*32-lt.linearVelocity))
- rt:applyForce(rt.mass*((rtpos-rt.position)*32-rt.linearVelocity))
- else
- pl:applyForce(pl.mass*(pl.linearVelocity/32))
- lt:applyLinearImpulse(lt.mass*((ltpos-lt.position)*32-lt.linearVelocity)/32)
- rt:applyLinearImpulse(rt.mass*((rtpos-rt.position)*32-rt.linearVelocity)/32)
- end
- end
- --Draw body
- self.lm:setRect(self.lt.info,lt.x,lt.y-2,27,17,ltang)
- self.lm:setRect(self.rt.info,rt.x,rt.y-2,27,17,rtang)
- self.lm:draw()
- self.plym:draw()
- self.headm:draw()
- self.hm:draw()
- if not self.lp then
- local lookpos = sp+vec2(self.mdir,0):normalize()*400
- local dis = self.lookpos:dist(lookpos)
- self:setLookPos(self.lookpos + (lookpos-self.lookpos):normalize()*math.min(dis*0.05*dt,30))
- end
- if alive then
- self:correctFeet()
- end
- if self.mdir~=self.dir then self.mdir = -self.dir end
- end
- function Player:drawJoystick()
- pushStyle()
- local joyp = self.joypos
- local jsize = self.joysize
- tint(255,200)
- sprite("Documents:flatdark",joyp.x,joyp.y,jsize,jsize)
- if self.jactive then
- tint(200,200)
- else
- tint(255,255)
- end
- sprite("Documents:flatjoy",joyp.x+self.joff.x*(jsize/2),
- joyp.y+self.joff.y*(jsize/2),jsize*0.6)
- popStyle()
- pushStyle()
- if self.jump then
- fill(100,40)
- stroke(50,100)
- strokeWidth(5)
- else
- fill(100,70)
- stroke(50,70)
- strokeWidth(3)
- end
- ellipse(self.epos.x,self.epos.y,self.esize)
- popStyle()
- end
- function Player:setLookPos(pos)
- self.lookpos = pos
- local dis = (pos-(vec2(self.ply.x,self.ply.y)))
- if math.abs(dis.x)<10 then
- self.lookpos.x = pos.x + dis:normalize().x*10
- end
- if math.abs(dis.x)>0 then
- self.dir = (vec2(dis.x,0):normalize().x)
- self.mdir = self.dir
- self:flipTex(true)
- --self.lm.shader.flip = vec2(-self.dir,1)
- end
- --end
- self.rv = 1
- end
- function Player:stopWalk()
- self.jactive,self.joff,self.vel = false,vec2(),vec2()
- end
- function Player:touched(touch)
- t = touch[1]
- local p = vec2(t.x,t.y)+vec2(WIDTH/2,HEIGHT/2)-scr
- local jpos,jsize = self.joypos,self.joysize
- local epos,esize = self.epos,self.esize
- if touch[3] == "ply" then
- if vec2(t.x,t.y):dist(jpos) < jsize/2 and t.state == BEGAN then
- self.jactive = true
- self.joff = (vec2(t.x,t.y)-jpos)/(jsize*0.5)
- end
- if self.jactive then
- self.joff = (vec2(t.x,t.y)-jpos)/(jsize*0.5)
- if self.joff:len() > 1 then
- self.joff = self.joff:normalize()
- end
- if t.state == ENDED or t.state == CANCELLED then
- self.jactive,self.joff,self.vel = false,vec2(),vec2()
- end
- end
- end
- if touch[3] == "look" then
- self:setLookPos(p)
- self.lp = true
- if t.state == ENDED then
- self.lp = false
- end
- end
- if touch[3] == "jump" and not self.tbox then
- if vec2(t.x,t.y):dist(epos) < esize/2 and t.state == BEGAN then
- self.jump = vec2(0,100)
- tween.delay(0.1,function() self.jump = nil end)
- end
- end
- end
- --# TMesh
- TMesh = class()
- function TMesh:init(points,width)
- self.points = points
- self.width = width+15
- self.m = mesh()
- self.p1,self.p2 = nil,nil
- self.t = mesh()
- self.mp = {}
- self.finished = true
- local p = points
- local mp = {}
- local mu = {p[1]-vec2(0,800)}
- local pl = #p
- --Create lower ground vertices from given points
- for i=1,pl do
- --if (i%2) == 0 or i == pl then
- mu[math.floor(i)+1] = p[i]+vec2(0,-self.width/3)
- --end
- end
- --Create surface layer two triangles each segment
- for i=2,pl do
- table.insert(mp,p[i-1]+vec2(0,-self.width/2))
- table.insert(mp,p[i]+vec2(0,-self.width/2))
- table.insert(mp,p[i-1]+vec2(0,25))
- table.insert(mp,p[i-1]+vec2(0,25))
- table.insert(mp,p[i]+vec2(0,-self.width/2))
- table.insert(mp,p[i]+vec2(0,25))
- end
- mu[#mu+1] = p[#p]-vec2(0,1500) --This makes sure the lower ground ends far below view
- self.p1 = mp
- self.p2 = triangulate(mu)
- end
- function TMesh:draw()
- self.t:draw()
- self.m:draw()
- if self.finished then
- self.m.texture = readImage("Cargo Bot:Register Slot") --Surface mesh
- self.t.texture = readImage("Cargo Bot:Starry Background")
- self.m.vertices = self.p1
- self.t.vertices = self.p2
- self.m:setColors(255,255,255,255)
- self.t:setColors(255,255,255,255)
- local tv = {}
- local gl = 0
- local p1 = self.p1
- local seglen = 70
- --This plots the texture coordinates for the surface, change seglen to change surface image length
- for i=1,#p1,6 do
- if p1[i+3] and p1[i+5] then
- local len = 0
- local lent = p1[i]:dist(p1[i+1])
- local lenb = p1[i+3]:dist(p1[i+5])
- if lenb>lent then len = lenb else len = lent end
- local texlen = len/seglen
- tv[i] = vec2(gl,0.1)
- tv[i+1] = vec2(gl+texlen,0.1)
- tv[i+2] = vec2(gl,1)
- tv[i+3] = vec2(gl,1)
- tv[i+4] = vec2(gl+texlen,0.1)
- tv[i+5] = vec2(gl+texlen,1)
- gl = gl + texlen
- end
- end
- self.m.texCoords = tv
- self.m.shader = shader(ttexshdr.vS,ttexshdr.fS)
- tv = {}
- for k,v in pairs(self.p2) do
- table.insert(tv,vec2(v.x/96,v.y/96))
- end
- self.t.texCoords = tv
- self.t.shader = shader(ttexshdr.vS,ttexshdr.fS)
- self.finished = nil
- end
- end
- ttexshdr = {}
- ttexshdr.vS =
- [[
- //This is the current model * view * projection matrix
- // Codea sets it automatically
- uniform mat4 modelViewProjection;
- //This is the current mesh vertex position, color and tex coord
- // Set automatically
- attribute vec4 position;
- attribute vec4 color;
- attribute vec2 texCoord;
- //This is an output variable that will be passed to the fragment shader
- varying lowp vec4 vColor;
- varying highp vec2 vTexCoord;
- void main()
- {
- //Pass the mesh color to the fragment shader
- vColor = color;
- vTexCoord = texCoord;
- //Multiply the vertex position by our combined transform
- gl_Position = modelViewProjection * position;
- }
- ]]
- ttexshdr.fS =
- [[
- //Default precision qualifier
- precision highp float;
- //This represents the current texture on the mesh
- uniform lowp sampler2D texture;
- //The interpolated vertex color for this fragment
- varying lowp vec4 vColor;
- //The interpolated texture coordinate for this fragment
- varying highp vec2 vTexCoord;
- void main()
- {
- //Sample the texture at the interpolated coordinate
- lowp vec4 col = texture2D( texture, vec2(mod(vTexCoord.x,1.0), mod(vTexCoord.y,1.0))) * vColor;
- //Set the output color to the texture color
- gl_FragColor = col;
- }
- ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement