Created
October 26, 2015 06:24
-
-
Save dermotbalson/0dff8777b2571e77e08f to your computer and use it in GitHub Desktop.
Tank 5d shooting seems to work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Shot | |
--shot | |
ShotList={} | |
function AddShot(p,d,s) | |
table.insert(ShotList,{start=p,pos=p,dir=d,speed=s}) | |
end | |
function DrawShots(Tanks) | |
for i,s in pairs(ShotList) do | |
local m=LookAtMatrix(s.pos,s.pos+s.dir) | |
pushMatrix() | |
modelMatrix(m) | |
Tank.Shot:draw() | |
popMatrix() | |
local newPos=s.pos+s.dir*(s.speed*DeltaTime) | |
print("shot dir",s.dir) | |
for _,t in pairs(Tanks) do | |
if t.pos:dist(newPos)<Tank.shotRadius or s.dir:dot(t.pos-newPos)<0 then | |
ShotList[i]=nil | |
print("hit") | |
print("t.angle",t.angle) | |
local objPos,m=RotateVector((s.pos-t.pos),-t.angle,0) | |
local objDir=m*s.dir | |
print("objPos",objPos) | |
print("objDir",objDir) | |
local min,h,nam=PenetrationTest(objPos,objDir) | |
h=h+t.pos | |
print("dist",min) | |
print("point",h) | |
print("part",nam) | |
else | |
s.pos=newPos | |
end | |
end | |
end | |
end | |
--# Effects | |
--Effects | |
function MakeExplosion(s) | |
local sin,cos,rand,pi2=math.sin,math.cos,math.random,math.pi*2 | |
local ss=s*1.5 | |
local img=image(ss,ss) | |
pushMatrix() | |
setContext(img) | |
translate(ss/2,ss/2) | |
for i=1,1000 do | |
local f=i/2000 | |
local m=0.4-0.2*f | |
local a,d,r=rand()*pi2,rand()*s*.5,rand()*s*m | |
local col=150+100*f | |
fill(color(col,col,col,50)) | |
rotate(a) | |
ellipse(d*sin(a),d*cos(a),r) | |
end | |
setContext() | |
popMatrix() | |
local m=mesh() | |
local x1,y1,z,x2,y2=-s/2,-s/2,0,s/2,s/2 | |
m.vertices={vec3(x1,y1,z),vec3(x2,y1,z),vec3(x2,y2,z),vec3(x2,y2,z),vec3(x1,y2,z),vec3(x1,y1,z)} | |
m.texture=img | |
m.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)} | |
m:setColors(color(255)) | |
m.shader=shader(TransparentFadeShader.v,TransparentFadeShader.f) | |
m.shader.a=1 | |
return m,img | |
end | |
function MakeShell() | |
return CreateBlock(0.15,0.15,20,color(255,255,0,100),vec3(0,0,-5)) | |
end | |
--# Shaders | |
--Shaders | |
TankFogShader={ | |
v=[[ | |
uniform mat4 modelViewProjection; | |
uniform mat4 mModel; | |
uniform vec4 directColor; | |
uniform vec4 directDirection; | |
uniform vec4 ambientColor; | |
uniform float offset; | |
attribute vec4 position; | |
attribute vec3 normal; | |
attribute vec2 texCoord; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
varying highp vec4 vPosition; | |
void main() | |
{ | |
gl_Position = modelViewProjection * position; | |
vTexCoord = vec2(texCoord.x+offset,texCoord.y); | |
vec4 norm = normalize(mModel * vec4( normal, 0.0 )); | |
float diffuse = max( 0.0, dot( norm, directDirection )); | |
vPosition = mModel*position; | |
vColor = diffuse * directColor + ambientColor; | |
} | |
]], | |
f=[[ | |
precision highp float; | |
uniform lowp sampler2D texture; | |
uniform float offset2; | |
uniform vec4 mistColor; | |
uniform float fog; | |
uniform vec3 camPos; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
varying highp vec4 vPosition; | |
void main() | |
{ | |
vec4 col = texture2D(texture, vec2(mod(vTexCoord.x+offset2,1.0),mod(vTexCoord.y,1.0)))*vColor; | |
float f = clamp(distance(vPosition.xyz,camPos)/fog,0.0,1.0); | |
col = mix( col, mistColor, f); | |
col.a=1.0; | |
gl_FragColor=col; | |
} | |
]]} | |
TankShader={ | |
v=[[ | |
uniform mat4 modelViewProjection; | |
uniform mat4 mModel; | |
uniform vec4 directColor; | |
uniform vec4 directDirection; | |
uniform vec4 ambientColor; | |
uniform float offset; | |
attribute vec4 position; | |
attribute vec3 normal; | |
attribute vec2 texCoord; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
varying highp vec4 vPosition; | |
void main() | |
{ | |
gl_Position = modelViewProjection * position; | |
vTexCoord = vec2(texCoord.x+offset,texCoord.y); | |
vec4 norm = normalize(mModel * vec4( normal, 0.0 )); | |
float diffuse = max( 0.0, dot( norm, directDirection )); | |
vPosition = mModel*position; | |
vColor = diffuse * directColor + ambientColor; | |
} | |
]], | |
f=[[ | |
precision highp float; | |
uniform lowp sampler2D texture; | |
uniform float offset2; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
varying highp vec4 vPosition; | |
void main() | |
{ | |
vec4 col = texture2D(texture, vec2(mod(vTexCoord.x+offset2,1.0),mod(vTexCoord.y,1.0)))*vColor; | |
col.a=1.0; | |
gl_FragColor=col; | |
} | |
]]} | |
TreeShader={ | |
v=[[ | |
uniform mat4 modelViewProjection; | |
attribute vec4 position; | |
attribute vec2 texCoord; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
gl_Position = modelViewProjection * position; | |
vTexCoord = texCoord; | |
} | |
]], | |
f=[[ | |
precision highp float; | |
uniform lowp sampler2D texture; | |
uniform vec4 mistColor; | |
uniform float visibility; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
vec4 col = texture2D(texture,vTexCoord); | |
if (col.a<0.05) discard; | |
else { | |
col=mix(mistColor,col,visibility); | |
gl_FragColor=col; | |
} | |
} | |
]]} | |
LightingShader={ | |
v=[[ | |
uniform mat4 modelViewProjection; | |
uniform mat4 mModel; | |
uniform vec4 directColor; | |
uniform vec4 directDirection; | |
uniform vec4 ambientColor; | |
uniform float fog; | |
uniform vec4 mistColor; | |
uniform vec3 camPos; | |
attribute vec4 position; | |
attribute vec4 color; | |
attribute vec3 normal; | |
varying lowp vec4 vColor; | |
void main() | |
{ | |
gl_Position = modelViewProjection * position; | |
vec4 norm = normalize(mModel * vec4( normal, 0.0 )); | |
float diffuse = max( 0.0, dot( norm, directDirection )); | |
vec4 p=mModel*position; | |
float f = clamp(distance(p.xyz,camPos)/fog,0.0,1.0); | |
vColor = mix(color * ( diffuse * directColor + ambientColor ),mistColor,f); | |
vColor.a=1.0; | |
} | |
]], | |
f=[[ | |
precision highp float; | |
varying lowp vec4 vColor; | |
void main() | |
{ | |
gl_FragColor=vColor; | |
} | |
]]} | |
--Tile | |
TileShader = { | |
v = [[ | |
uniform mat4 modelViewProjection; | |
uniform mat4 mModel; | |
attribute vec4 position; | |
attribute vec2 texCoord; | |
varying highp vec2 vTexCoord; | |
varying highp vec4 vPosition; | |
void main() | |
{ | |
vTexCoord = texCoord; | |
vPosition=mModel*position; | |
gl_Position = modelViewProjection * position; | |
} | |
]], | |
f = [[ | |
precision highp float; | |
uniform lowp sampler2D texture; | |
uniform float fog; | |
uniform vec4 mistColor; | |
uniform vec3 camPos; | |
varying highp vec2 vTexCoord; | |
varying highp vec4 vPosition; | |
void main() | |
{ | |
lowp vec4 col = texture2D(texture, vec2(mod(vTexCoord.x,1.0),mod(vTexCoord.y,1.0))); | |
float f = clamp(distance(vPosition.xyz,camPos)/fog,0.0,1.0); | |
gl_FragColor = mix(col,mistColor,f); | |
} | |
]]} | |
--# Terrain2 | |
--Terrain2 | |
local atan,rand,min,max,cos=math.atan,math.random,math.min,math.max,math.cos | |
local rad=math.pi/180 | |
local Terrain={} | |
function MakeTerrain() | |
local w,d,pic,f=1000,1000,"Dropbox:3D-grass2x",.02 | |
LoadImages() | |
local floor=mesh() | |
local img=readImage(pic) | |
floor.texture=img | |
local wn,dn=w/img.width/f,d/img.height/f | |
floor.vertices={vec3(0,0,0),vec3(w,0,0),vec3(w,0,-d),vec3(w,0,-d),vec3(0,0,-d),vec3(0,0,0)} | |
floor.texCoords={vec2(0,0),vec2(wn,0),vec2(wn,dn),vec2(wn,dn),vec2(0,dn),vec2(0,0)} | |
floor=SetLighting(floor,TileShader) | |
local trees={} | |
for i=1,400 do | |
table.insert(trees,AddBillboard(0,0,w,-d,treeImages,0.15)) | |
end | |
Terrain={floor=floor,trees=trees} | |
end | |
function LoadImages() | |
treeImages={readImage("Dropbox:3D-tree"),readImage("Dropbox:3D-tree3"),readImage("Dropbox:3D-tree7"), | |
readImage("Dropbox:3D-tree8")} | |
end | |
function AddBillboard(x1,z1,x2,z2,imgList,f) | |
local i=rand(1,#imgList) | |
local h=0.5+rand() | |
local w=imgList[i].width*h*f --width | |
local pos=vec3(rand(x1,x2),imgList[i].height*f/4*h,rand(min(z1,z2),max(z1,z2))) | |
local m=mesh() | |
m:addRect(0,0,w,imgList[i].height*h*f) | |
m.texture=imgList[i] | |
m.shader=shader(TreeShader.v,TreeShader.f) | |
m.shader.mistColor=backgroundColor | |
return {m=m,pos=pos,r=w/2} | |
end | |
function DrawTerrain() | |
Terrain.floor.shader.camPos=camPos | |
Terrain.floor:draw() | |
DrawBillboards(Terrain.trees,camPos) | |
end | |
function LookAt(source,target) | |
local z=(source-target):normalize() | |
local x=(vec3(0,1,0):cross(z)):normalize() | |
local y=(z:cross(x)):normalize() | |
return matrix(x.x,x.y,x.z,0, y.x,y.y,y.z,0, z.x,z.y,z.z,0, source.x,source.y,source.z,1) | |
end | |
function GetScreenRect(t1,t2,s) --t1 is camera, t2 is target, s is vec3 size of object | |
--get direction and distance | |
local v=(t2.pos-t1.pos) | |
local d=v:len()-u/2 --position of t2 is assumed to be its centre, so adjust by 1\2 depth | |
v=v/d | |
--get drawing rectangle | |
local w = u*WIDTH*projectionMatrix()[1]/d/2 | |
local h = s.y*HEIGHT*projectionMatrix()[6]/d/2 | |
--draw our tank | |
local m = modelMatrix()*viewMatrix()*projectionMatrix() | |
--m = m:translate(0,0,-d) | |
local X,Y=(m[13]/m[16]+1)*WIDTH/2, (m[14]/m[16]+1)*HEIGHT/2 | |
return X-w/2,Y-h/2,w,h | |
end | |
function DrawBillboards(billboards) | |
local PM1=projectionMatrix()[1] | |
--local lookPos=camPos+(camLook-camPos):normalize()*5000 | |
for _,b in pairs(billboards) do | |
b.pov=IsVisible(b.pos,camPos,camLook,b.r) | |
b.visibility=max(0,1-b.pos:dist(camPos)/fogRange) | |
end | |
--calc distance to camera and sort from furthest to nearest, every two seconds | |
if ElapsedTime>(lastSort or -9) +2 then | |
--for _,b in pairs(billboards) do b.visibility=max(0,1-b.pos:dist(camPos)/fogRange) end | |
table.sort(billboards,function(a,b) return a.visibility<b.visibility end) | |
lastSort=ElapsedTime | |
end | |
for i=1,#billboards do | |
local b=billboards[i] | |
if b.pov and b.visibility>0 then | |
pushMatrix() | |
--move to the centre of our image | |
local p=b.pos | |
translate(p:unpack()) | |
--calculate difference in x and z | |
local dx,dz=p.x-camPos.x,-p.z+camPos.z | |
--calculate angle we need to turn | |
local ang=atan(dx/-dz)/rad | |
--turn and draw | |
rotate(ang,0,1,0) --print(i,-ang) | |
b.m.shader.visibility=b.visibility | |
b.m:draw() | |
popMatrix() | |
end | |
end | |
end | |
function IsVisible(pos,camPos,camLook,radius) | |
look=camPos+(camLook-camPos)*5000 | |
local xDist=(pos-camPos):dist(math.max(math.min((pos-camPos):dot(look-camPos)/ | |
(look-camPos):lenSqr(),1),0)*(look-camPos)) | |
return xDist-radius<camPos:dist(pos)/projectionMatrix()[1] | |
end | |
--# Utility | |
--Utility | |
function CreateBlock(w,h,d,col,pos,tex,ms) --width,height,depth,colour,position,texture | |
pos=pos or vec3(0,0,0) | |
local x,X,y,Y,z,Z=pos.x-w/2,pos.x+w/2,pos.y-h/2,pos.y+h/2,pos.z-d/2,pos.z+d/2 | |
local v={vec3(x,y,Z),vec3(X,y,Z),vec3(X,Y,Z),vec3(x,Y,Z),vec3(x,y,z),vec3(X,y,z),vec3(X,Y,z),vec3(x,Y,z)} | |
local vert={v[1],v[2],v[3],v[1],v[3],v[4],v[2],v[6],v[7],v[2],v[7],v[3],v[6],v[5],v[8],v[6],v[8],v[7], | |
v[5],v[1],v[4],v[5],v[4],v[8],v[4],v[3],v[7],v[4],v[7],v[8],v[5],v[6],v[2],v[5],v[2],v[1]} | |
local texCoords | |
if tex then | |
local t={vec2(0,0),vec2(1,0),vec2(0,1),vec2(1,1)} | |
texCoords={t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3], | |
t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3]} | |
end | |
local n={vec3(0,0,1),vec3(1,0,0),vec3(0,0,-1),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0)} | |
local norm={} | |
for i=1,6 do for j=1,6 do norm[#norm+1]=n[i] end end | |
if not ms then ms=mesh() end | |
if ms.size==0 then | |
ms.vertices=vert | |
ms.normals=norm | |
if tex then ms.texture,ms.texCoords=tex,texCoords end | |
else | |
for i=1,#vert do | |
table.insert(ms.vertices,vert[i]) | |
table.insert(ms.normals,norm[i]) | |
if tex then table.insert(ms.texCoords,texCoords[i]) end | |
end | |
end | |
ms:setColors(col or color(255)) | |
return ms | |
end | |
function AddBlock(w,h,d,col,pos,rot,texture,vertices,texCoords,normals,colors) --width,height,depth,colour,position,texture | |
local x,X,y,Y,z,Z=-w/2,w/2,-h/2,h/2,-d/2,d/2 | |
local v={vec3(x,y,Z),vec3(X,y,Z),vec3(X,Y,Z),vec3(x,Y,Z),vec3(x,y,z),vec3(X,y,z),vec3(X,Y,z),vec3(x,Y,z)} | |
local vert={v[1],v[2],v[3],v[1],v[3],v[4],v[2],v[6],v[7],v[2],v[7],v[3],v[6],v[5],v[8],v[6],v[8],v[7], | |
v[5],v[1],v[4],v[5],v[4],v[8],v[4],v[3],v[7],v[4],v[7],v[8],v[5],v[6],v[2],v[5],v[2],v[1]} | |
if rot then | |
m=modelMatrix() | |
m=m:translate(pos:unpack()) | |
m=m:rotate(rot.x,1,0,0) m=m:rotate(r.y,0,1,0) m=m:rotate(r.z,0,0,1) | |
for i=1,#vert do vertices[#vertices+1]=m*vert[i] end | |
else | |
for i=1,#vert do vertices[#vertices+1]=pos+vert[i] end | |
end | |
local tex | |
if texture then | |
local t={vec2(0,0),vec2(1,0),vec2(0,1),vec2(1,1)} | |
tex={t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3], | |
t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3]} | |
for i=1,#tex do texCoords[#texCoords+1]=tex[i] end | |
end | |
local n={vec3(0,0,1),vec3(1,0,0),vec3(0,0,-1),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0)} | |
for i=1,6 do | |
for j=1,6 do | |
normals[#normals+1]=n[i] | |
colors[#colors+1]=col | |
end | |
end | |
return vertices,texCoords,normals,colors | |
end | |
--o is start of line, d is normalised line direction | |
--v0, v1, v2 are triangle vertices | |
function LineIntersectsTriangle(o,d,v1,v2,v3,n) | |
if d:dot(n)>0 then return end | |
local e1,e2=v2-v1,v3-v1 | |
local p=d:cross(e2) | |
local det=e1:dot(p) | |
if math.abs(det)<0.001 then return end | |
local inv_det=1/det | |
local t=o-v1 | |
local u=t:dot(p)*inv_det | |
if u<0 or u>1 then return end | |
local q=t:cross(e1) | |
local v=d:dot(q)*inv_det | |
if v<0 or u+v>1 then return end | |
local a=e2:dot(q)*inv_det | |
if a>0 then return a,o+d*a end | |
end | |
function LookAtMatrix(source,target,up) | |
local Z=(source-target):normalize() | |
up=up or vec3(0,1,0) | |
local X=(up:cross(Z)):normalize() | |
local Y=(Z:cross(X)):normalize() | |
return matrix(X.x,X.y,X.z,0,Y.x,Y.y,Y.z,0,Z.x,Z.y,Z.z,0,source.x,source.y,source.z,1) | |
end | |
function RotateVector(v,y,z) | |
local m=matrix(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1) | |
if y then m=m:rotate(y,0,1,0) end | |
if z then m=m:rotate(z,0,0,1) end | |
return m*v,m | |
end | |
--# Model | |
--Model | |
Tank=class() | |
Tank.turretMaxAngle=40 | |
Tank.barrelMaxAngles=vec2(-3,20) | |
Tank.maxSpeed=vec2(5,16) --pixels/sec | |
Tank.maxSpeedChange=0.1 | |
Tank.reloadTime=15 | |
Tank.width=19 | |
Tank.count=0 | |
Tank.shotRadius=12 | |
Tank.colors={color(158, 171, 48, 255),color(74, 81, 45, 255)} | |
function Tank:init(player) | |
if not Tank.model then | |
Tank.LoadTextures() | |
Tank.CreateModel() | |
end | |
self.trackOffset=0 | |
self.turretAngle=0 | |
self.gunAngle=0 | |
self.startOfBarrel=vec3(-3.8,5.75,0) | |
self.endOfBarrel=vec3(-10,0,0) --position of end of barrel relative to its base | |
self.muzzleSpeed=2000 --px/s | |
self.health=100 | |
self.speed=0.25 | |
self.angle=-90 | |
self.rad=math.rad(self.angle) | |
self.pos=vec3(0,0,0) | |
self.offset2=math.random() | |
self.wobble=math.random() | |
self.lastShot=-99 | |
Tank.count=Tank.count+1 | |
self.id=Tank.count | |
self.player=player | |
end | |
function Tank:draw(camPos,camLook) | |
self.trackOffset=self.trackOffset-self.speed/200 | |
self.pos=self.pos+vec3(-math.cos(self.rad),0,math.sin(self.rad))*self.speed *DeltaTime | |
if not self.player and not IsVisible(self.pos,camPos,camLook,Tank.width/2) then return end | |
local m=Tank.model | |
m.track.shader.offset=self.trackOffset | |
pushMatrix() | |
translate(self.pos:unpack()) | |
rotate(self.angle,0,1,0) | |
--if not self.player then self:Wobble(self.speed) end | |
m.wheels.shader.mModel=modelMatrix() | |
m.wheels.shader.camPos=camPos | |
m.wheels:draw() | |
m.track.shader.mModel=modelMatrix() | |
m.track.shader.camPos=camPos | |
m.track:draw() | |
m.body.shader.mModel=modelMatrix() | |
m.body.shader.camPos=camPos | |
m.body.shader.offset2=self.offset2 | |
m.body:draw() | |
rotate(self.turretAngle,0,1,0) | |
m.turret.shader.mModel=modelMatrix() | |
m.turret.shader.camPos=camPos | |
m.turret.shader.offset2=self.offset2 | |
m.turret:draw() | |
translate(self.startOfBarrel:unpack()) | |
rotate(-self.gunAngle,0,0,1) | |
m.barrel.shader.mModel=modelMatrix() | |
m.barrel.shader.camPos=camPos | |
m.barrel.shader.offset2=self.offset2 | |
m.barrel:draw() | |
--calculate position and angle of end of barrel | |
local mm=modelMatrix() | |
local a=vec3(mm[13],mm[14],mm[15]) | |
mm=mm:translate(self.endOfBarrel:unpack()) | |
self.muzzlePos=vec3(mm[13],mm[14],mm[15]) | |
self.muzzleAngle=(self.muzzlePos-a):normalize() | |
popMatrix() | |
end | |
function Tank:update(a1,s,a2,a3) | |
self:rotate(-a1/4) | |
local ss | |
if s<0 then ss=s*Tank.maxSpeed[1] else ss=s*Tank.maxSpeed[2] end | |
self.speed=self.speed+math.max(-Tank.maxSpeedChange,math.min(Tank.maxSpeedChange,ss-self.speed)) | |
self.turretAngle=math.max(-Tank.turretMaxAngle,math.min(Tank.turretMaxAngle,self.turretAngle-a2/2)) | |
self.gunAngle=math.max(Tank.barrelMaxAngles[1],math.min(Tank.barrelMaxAngles[2],self.gunAngle+a3/5)) | |
end | |
function Tank:rotate(a) | |
self.angle=self.angle+a | |
self.rad=math.rad(self.angle) | |
end | |
function Tank:rotateTurret(a) | |
self.turretAngle=self.turretAngle+a | |
end | |
function Tank:rotateBarrel(a) | |
self.barrelAngle=self.barrelAngle+a | |
end | |
function Tank:SetAim() | |
local m=matrix(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1) | |
m=m:translate(self.pos:unpack()) | |
m=m:rotate(self.angle,0,1,0) | |
m=m:rotate(self.turretAngle,0,1,0) | |
m=m:translate(self.startOfBarrel:unpack()) | |
local b1=vec3(m[13],m[14],m[15]) | |
m=m:rotate(-self.gunAngle,0,0,1) | |
--calculate position and angle of end of barrel | |
m=m:translate(self.endOfBarrel:unpack()) | |
local b2=vec3(m[13],m[14],m[15]) | |
local a=(b2-b1):normalize() | |
self.muzzlePos,self.muzzleAngle=b2,a | |
return b1,b2,a | |
end | |
function Tank:Shoot() | |
if not self:ready() then return end | |
AddShot(self.muzzlePos,self.muzzleAngle,self.muzzleSpeed) | |
self.lastShot=ElapsedTime | |
end | |
function Tank:ready() | |
return ElapsedTime>self.lastShot+Tank.reloadTime | |
end | |
function Tank:Wobble(speed) | |
local f,e=math.abs(.2*speed/60),ElapsedTime+self.wobble | |
local a,b=e*f,e*math.pi*f | |
rotate(10*noise(a,b),1,0,0) | |
rotate(3*noise(b,a),0,0,1) | |
end | |
function Tank.LoadTextures() | |
Tank.Shot=MakeShell() | |
Tank.texBody=readImage("Dropbox:Tank_Body") | |
if not Tank.texBody then | |
local w,h,f=400,400,5 | |
local img1=image(w,h) | |
for i=1,w do | |
for j=1,h do | |
local m=(noise(i/w*f,j/h*f)+1)/2 | |
img1:set(i,j,Tank.colors[1]:mix(Tank.colors[2],m)) | |
end | |
end | |
saveImage("Dropbox:Tank_Body",img1) | |
Tank.texBody=img1 | |
end | |
--Track------- | |
Tank.texTrack=readImage("Dropbox:Tank_Track") | |
if not Tank.texTrack then | |
local img=image(50,5) | |
setContext(img) | |
pushStyle() | |
noSmooth() | |
background(123, 122, 122, 255) | |
stroke(25) | |
strokeWidth(0.5) | |
for i=1,img.width do | |
line(i,0,i,5) | |
end | |
popStyle() | |
setContext() | |
saveImage("Dropbox:Tank_Track",img) | |
Tank.texTrack=img | |
end | |
--Wheel------- | |
Tank.texWheel=readImage("Dropbox:Tank_Wheel") | |
if not Tank.texWheel then | |
img=image(100,10) | |
local col=Tank.colors[1]*2/3+Tank.colors[2]/3 col.a=255 | |
print(col) | |
setContext(img) | |
background(0) | |
pushStyle() | |
noSmooth() | |
fill(col) | |
stroke(Tank.colors[2]) | |
strokeWidth(2) | |
for i=1,4 do | |
ellipse(i*26-11,10,20) | |
end | |
fill(Tank.colors[2]) | |
for i=1,4 do | |
ellipse(i*26-11,10,4) | |
end | |
fill(col) | |
for i=1,3 do | |
ellipse(2+i*26,9,20) | |
end | |
fill(Tank.colors[2]) | |
for i=1,4 do | |
ellipse(2+i*26,9,4) | |
end | |
popStyle() | |
setContext() | |
saveImage("Dropbox:Tank_Wheel",img) | |
Tank.texWheel=img | |
end | |
end | |
function Tank.CreateModel() | |
local x1,x2,x3,y1,y2,y3,z1,z2,z3,z4,f1,f2 | |
--body of tank | |
local body=mesh() | |
local v,t,c={},{},{} | |
x1,x2,y,z1,z2=-8.25,8.25,4.5,3.5,-3.5 --deck | |
v[#v+1]=vec3(x1,y,z1) v[#v+1]=vec3(x2,y,z1) v[#v+1]=vec3(x2,y,z2) | |
v[#v+1]=vec3(x2,y,z2) v[#v+1]=vec3(x1,y,z2) v[#v+1]=vec3(x1,y,z1) | |
x,y1,y2,z1,z2=8.25,2,4.5,3.5,-3.5 --back | |
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2) | |
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1) | |
x1,x2,y1,y2,z1,z2,z3,z4=-11,-8.25,3,4.5,-4.5,4.5,-3.5,3.5 --front #2 angle | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z4) | |
v[#v+1]=vec3(x2,y2,z4) v[#v+1]=vec3(x2,y2,z3) v[#v+1]=vec3(x1,y1,z1) | |
x1,x2,y1,y2,y3,z1,z2=-8.25,8.25,2,2,3.5,4.5,-4.5 --sides | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z1) | |
v[#v+1]=vec3(x2,y3,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x1,y1,z1) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y3,z2) | |
v[#v+1]=vec3(x1,y3,z2) v[#v+1]=vec3(x2,y3,z2) v[#v+1]=vec3(x2,y2,z2) | |
x1,x2,y1,y2,z1,z2=-8.25,8.25,3.5,4.5,4.5,3.5 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y2,z2) v[#v+1]=vec3(x1,y1,z1) | |
x1,x2,y1,y2,z1,z2=8.25,-8.25,3.5,4.5,-4.5,-3.5 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y2,z2) v[#v+1]=vec3(x1,y1,z1) | |
x1,x2,y1,z1,z2=-10,7.25,1,-2.5,2.5 --underneath | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y1,z2) | |
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y1,z1) | |
x,y1,y2,z1,z2=-11,2,3,-4.5,4.5 --front bottom | |
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2) | |
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1) | |
x1,x2,y1,y2,z1,z2=-10,-11,1,2,-2.5,2.5 --front under slant | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
x1,x2,y1,y2,z1,z2=7.25,8.25,1,2,2.5,-2.5 --back under slant | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
x1,x2,x3,y1,y2,y3,z1,z2=-11,-8.25,-8.25,3,2,3.5,4.5,3.5 --fill the cracks | |
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x3,y3,z1) | |
z1=-4.5 | |
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x3,y3,z1) v[#v+1]=vec3(x2,y2,z1) | |
x1,x2,x3,y1,y2,y3,z1=-11,-11,-8.25,3,2,2,4.5 | |
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x3,y3,z1) | |
z1=-4.5 | |
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x3,y3,z1) v[#v+1]=vec3(x2,y2,z1) | |
x1,x2,y1,y2,y3,z1,z2=-11,-8.25,3,3.5,4.5,4.5,3.5 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z2) | |
v[#v+1]=vec3(x1,y1,-z1) v[#v+1]=vec3(x2,y3,-z2) v[#v+1]=vec3(x2,y2,-z1) | |
x1,y1,y2,z1,z2=8.25,5.5,6.5,3.5,-3.5 | |
x1,y1,y2,z1,z2=8.25,2,3.5,4.5,3.5 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y2,z2) | |
v[#v+1]=vec3(x1,y2,z2) v[#v+1]=vec3(x1,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
v[#v+1]=vec3(x1,y1,-z1) v[#v+1]=vec3(x1,y2,-z2) v[#v+1]=vec3(x1,y1,-z2) | |
v[#v+1]=vec3(x1,y2,-z2) v[#v+1]=vec3(x1,y1,-z1) v[#v+1]=vec3(x1,y2,-z1) | |
x1,y1,y2,z1,z2=8.25,3.5,4.5,4.5,3.5 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y2,z2) | |
z1,z2=-3.5,-4.5 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y2,z1) | |
body.vertices=v | |
body:setColors(color(90)) | |
body.texture=Tank.texBody | |
body.name="body" | |
local testBody={v} | |
--tracks | |
local track,v,t=mesh(),{},{} | |
local f=.05 | |
x1,x2,y1,y2,z1,z2,f1,f2=8.25,8.25,1,2,4.5,2.5,0,f*2 --back right vert | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1) | |
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0) | |
z1,z2=-2.5,-4.5 --back left vert | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1) | |
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0) | |
x1,x2,y1,y2,z1,z2,f1,f2=7.25,8.25,0,1,4.5,2.5,f*2,f*4 --back right slant | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1) | |
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0) | |
z1,z2=-2.5,-4.5 --back left slant | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1) | |
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0) | |
x1,x2,y1,y2,z1,z2,f1,f2=-9,-11,0,2,2.5,4.5,0,f*2 --front right slant | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f1,1) | |
t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f2,0) | |
z1,z2=-4.5,-2.5 --front left slant | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2) | |
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f1,1) | |
t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f2,0) | |
x1,x2,y1,y2,z1,z2,f1,f2=-9,7.25,0,0,4.5,2.5,4*f,20.25*f --bottom right track | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2) | |
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1) | |
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0) | |
z1,z2=-2.5,-4.5 --bottom left track | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2) | |
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1) | |
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1) | |
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0) | |
track.vertices=v | |
track.texCoords=t | |
track:setColors(color(40)) | |
track.texture=Tank.texTrack | |
track.name="track" | |
wheels,v,t=mesh(),{},{} | |
x1,x2,y1,y2,z1=-11,-9,2,0,4 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y1,z1) | |
x1,x2,y1,y2,z1=-9,7.25,2,0,4 | |
v[#v+1]=vec3(x1,y2,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y1,z1) | |
v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y2,z1) | |
x1,x2,y1,y2,y3,z1=7.25,8.25,0,1,2,4 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y3,z1) | |
v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z1) v[#v+1]=vec3(x1,y3,z1) | |
x1,x2,y1,y2,z1=-11,-9,2,0,-4 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z1) | |
x1,x2,y1,y2,z1=-9,7.25,2,0,-4 | |
v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y2,z1) v[#v+1]=vec3(x1,y1,z1) | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z1) | |
x1,x2,y1,y2,y3,z1=7.25,8.25,0,1,2,-4 | |
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x2,y2,z1) | |
v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x2,y3,z1) | |
for i=1,#v/2 do t[#t+1]=vec2((v[i].x+11)/19,v[i].y/2) end | |
for i=#v/2+1,#v do t[#t+1]=vec2(-(8.25-v[i].x)/19,v[i].y/2) end | |
wheels.vertices=v | |
wheels.texCoords=t | |
wheels:setColors(color(255,0,0)) | |
wheels.texture=Tank.texWheel | |
wheels.name="wheels" | |
local turret,v=mesh(),{} | |
local h,y,slope=2.5,4.5,0.5 | |
local p={vec3(-4,0,1.5),vec3(0,0,3.5),vec3(2,0,3),vec3(4,0,1),vec3(4,0,-1), | |
vec3(2,0,-3),vec3(0,0,-3.5),vec3(-4,0,-1.5)} | |
for i=1,#p do p[i].y=y+(p[i].x/8+0.5)*slope end | |
for i=1,#p do | |
local a,b=p[i],p[i+1] or p[1] | |
v[#v+1]=vec3(a.x,y,a.z) | |
v[#v+1]=vec3(b.x,y,b.z) | |
v[#v+1]=vec3(b.x,b.y+h,b.z) | |
v[#v+1]=vec3(b.x,b.y+h,b.z) | |
v[#v+1]=vec3(a.x,a.y+h,a.z) | |
v[#v+1]=vec3(a.x,y,a.z) | |
end | |
local norm={} | |
for i=1,#v do norm[i]=v[i]:normalize() end | |
--roof | |
for i=1,#p do | |
local a,b=p[i],p[i+1] or p[1] | |
v[#v+1]=vec3(a.x,a.y+h,a.z) | |
v[#v+1]=vec3(b.x,b.y+h,b.z) | |
v[#v+1]=vec3(0,y+h+slope/2,0) | |
for j=1,3 do norm[#norm+1]=vec3(0,1,0) end | |
end | |
turret.vertices=v | |
--turret.normals=norm | |
turret:setColors(color(90)) | |
turret.texture=Tank.texBody | |
turret.name="turret" | |
local testTurret={v} | |
barrel,p,v,norm=mesh(),{},{},{} | |
local x1,x2,r1,r2,y=-4,-7,0.75,0.4,7.75 | |
for i=1,8 do p[i]=vec3(0,math.cos(i*math.pi/4),math.sin(i*math.pi/4)) end | |
for i=1,8 do | |
local p1,p2=p[i],p[i+1] or p[1] | |
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1) | |
v[#v+1]=vec3(x2,y+p1.y*r2,p1.z*r2) | |
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2) | |
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2) | |
v[#v+1]=vec3(x1,y+p2.y*r1,p2.z*r1) | |
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1) | |
end | |
local x1,x2,r1,r2,y=-7,-17,0.4,0.3,7.75 | |
for i=1,8 do p[i]=vec3(0,math.cos(i*math.pi/4),math.sin(i*math.pi/4)) end | |
for i=1,8 do | |
local p1,p2=p[i],p[i+1] or p[1] | |
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1) | |
v[#v+1]=vec3(x2,y+p1.y*r2,p1.z*r2) | |
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2) | |
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2) | |
v[#v+1]=vec3(x1,y+p2.y*r1,p2.z*r1) | |
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1) | |
end | |
for i=1,#v do norm[i]=(v[i]-vec3(v[i].x,y,0)):normalize() end | |
for i=1,#v do v[i].x,v[i].y=v[i].x+4,v[i].y-7.75 end | |
barrel.vertices=v | |
barrel.normals=norm | |
barrel:setColors(color(90)) | |
barrel.texture=Tank.texBody | |
barrel.name="barrel" | |
---print("vertices=",body.size+track.size+turret.size+barrel.size+wheels.size) | |
local tank={body=body,track=track,turret=turret,barrel=barrel,wheels=wheels} | |
for _,m in pairs(tank) do | |
local norm={} | |
local nn=m:buffer("normal") | |
if nn[1]==nil then | |
local v=m:buffer("position") | |
for i=1,m.size,3 do | |
local v1,v2=v[i]-v[i+2],v[i+1]-v[i+2] | |
local n=(v1:cross(v2)):normalize() | |
norm[i],norm[i+1],norm[i+2]=n,n,n | |
end | |
m.normals=norm | |
end | |
if m.texture==Tank.texBody then | |
local t={} | |
local v=m:buffer("position") | |
for i=1,m.size do | |
t[i]=vec2(v[i].x/8+v[i].y/5,v[i].z/6+v[i].y/9)/2 | |
end | |
m.texCoords=t | |
end | |
m=SetLighting(m) | |
m.shader.offset2=0 | |
end | |
Tank.model=tank | |
local vert,norm={},{} | |
local v,n=body:buffer("position"),body:buffer("normal") | |
for i=1,body.size do vert[i]=v[i] norm[i]=n[i] end | |
local testBody={vert,norm} | |
local vert,norm={},{} | |
local v,n=turret:buffer("position"),turret:buffer("normal") | |
for i=1,turret.size do vert[i]=v[i] norm[i]=n[i] end | |
local testTurret={vert,norm} | |
--create bounding box for tracks for penetration testing | |
local b=CreateBlock(19,2,2) | |
local v=b:buffer("position") | |
local vert,norm={},{} | |
for i=1,b.size do vert[#vert+1]=v[i]+vec3(0,0,-3.5) norm[#norm+1]=vec3(0,0,-1) end | |
for i=1,b.size do vert[#vert+1]=v[i]+vec3(0,0, 3.5) norm[#norm+1]=vec3(0,0, 1) end | |
local testTrack={vert,norm} | |
Tank.Test={track=testTrack,turret=testTurret,body=testBody} | |
end | |
function PenetrationTest(pos,dir) | |
--print("Testing") | |
local min,h=99 | |
local v=Tank.Test.body | |
local name="body" | |
for i=1,#v[1],3 do | |
local d,p=LineIntersectsTriangle(pos,dir,v[1][i],v[1][i+1],v[1][i+2],v[2][i]) | |
--[ | |
print("------------------") | |
print(i) | |
print("x, n",v[2][i]) | |
print("v1",v[1][i]) | |
print("v2",v[1][i+1]) | |
print("v3",v[1][i+2]) | |
if dir:dot(v[2][i])<0 then | |
print("dot",dir:dot(v[2][i])) | |
print("dist",d,"point",p) | |
else | |
print("Skip") | |
end | |
--]] | |
if d and d<min then min,h,nam=d,p,name end | |
end | |
local v=Tank.Test.turret | |
local name="turret" | |
for i=1,#v[1],3 do | |
local d,p=LineIntersectsTriangle(pos,dir,v[1][i],v[1][i+1],v[1][i+2],v[2][i]) | |
if d and d<min then min,h,nam=d,p,name end | |
end | |
local v=Tank.Test.track | |
local name="track" | |
for i=1,#v[1],3 do | |
local d,p=LineIntersectsTriangle(pos,dir,v[1][i],v[1][i+1],v[1][i+2],v[2][i]) | |
if d and d<min then min,h,nam=d,p,name end | |
end | |
return min,h,nam | |
end | |
--# Controls | |
--joystick | |
JoyStick = class() | |
local tick=60 | |
--Note all the options you can set below. Pass them through in a named table | |
function JoyStick:init(t) | |
t = t or {} | |
self.radius = t.radius or 100 --size of joystick on screen | |
self.stick = t.stick or 30 --size of inner circle | |
self.centre = t.centre or self.radius * vec2(1,1) + vec2(5,5) | |
self.damp=vec2(0.2,0.2) | |
self.position = vec2(0,0) --initial position of inner circle | |
self.target = vec2(0,0) --current position of inner circle (used when we interpolate movement) | |
self.value = vec2(0,0) | |
self.delta = vec2(0,0) | |
self.mspeed = 30 | |
self.moving = 0 | |
end | |
function JoyStick:draw() | |
ortho() | |
viewMatrix(matrix()) | |
pushStyle() | |
fill(160, 182, 191, 1) | |
stroke(0,0,0,50) | |
strokeWidth(3) | |
ellipse(self.centre.x,self.centre.y,2*self.radius) | |
fill(78, 131, 153, 1) | |
ellipse(self.centre.x+self.position.x, self.centre.y+self.position.y, self.stick*2) | |
popStyle() | |
end | |
function JoyStick:touched(t) | |
if t.state == BEGAN then | |
local v = vec2(t.x,t.y) | |
if v:dist(self.centre)<self.radius-self.stick then | |
self.touch = t.id | |
--else return false | |
end | |
end | |
if t.id == self.touch then | |
if t.state~=ENDED then | |
local v = vec2(t.x,t.y) | |
if v:dist(self.centre)>self.radius-self.stick then | |
v = (v - self.centre):normalize()*(self.radius - self.stick) + self.centre | |
end --set x,y values for joy based on touch | |
self.target=v - self.centre | |
else --reset joystick to centre when touch ends | |
self.target=vec2(0,0) | |
self.touch = false | |
end | |
else return false | |
end | |
return true | |
end | |
function JoyStick:update() | |
local p = self.target - self.position | |
if p:len() < tick * self.mspeed then | |
self.position = self.target | |
if not self.touch then | |
if self.moving ~= 0 then | |
self.moving = self.moving - 1 | |
end | |
else | |
self.moving = 2 | |
end | |
else | |
self.position = self.position + p:normalize() * tick * self.mspeed | |
self.moving = 2 | |
end | |
local v=self.position/(self.radius - self.stick) | |
return self:Dampen(v) | |
end | |
function JoyStick:Dampen(v) | |
if not self.damp then return v end | |
if v.x>0 then v.x=math.max(0,(v.x-self.damp.x)/(1-self.damp.x)) | |
else v.x=math.min(0,(v.x+self.damp.x)/(1-self.damp.x)) end | |
if v.y>0 then v.y=math.max(0,(v.y-self.damp.y)/(1-self.damp.y)) | |
else v.y=math.min(0,(v.y+self.damp.y)/(1-self.damp.y)) end | |
return v | |
end | |
function JoyStick:isMoving() | |
return self.moving | |
end | |
function JoyStick:isTouched() | |
return self.touch | |
end | |
--# Main | |
-- Tiger4 | |
displayMode(FULLSCREEN) | |
function setup() | |
backup("WoT","ver 103","Shooting seems to work v1") | |
Settings() | |
end | |
function Settings() | |
backgroundColor=color(255) | |
fogRange=5000 | |
FOV=45 | |
player=Tank(true) | |
player.pos=vec3(500,0.5,-50) | |
player.turretAngle=0 | |
player:rotate(0) | |
player.gunAngle=0--math.random(0,5) | |
player.viewAngle=180 | |
T={} | |
for j=1,1 do | |
T[j]=Tank() | |
T[j].pos=vec3(500,0.5,-150) | |
T[j]:rotate(90) | |
T[j].turretAngle=math.random(-35,35) | |
T[j].gunAngle=math.random(0,5) | |
T[j].turretAngleChange=0.25 | |
T[j].gunAngleChange=0.1 | |
T[j].speed=0 | |
end | |
camAngle=math.pi/2 | |
speed=0 | |
maxSpeed=1 | |
FPS=60 | |
MakeTerrain() | |
joy=JoyStick() | |
joyAiming=JoyStick{centre=vec2(310,105)} | |
firePos,fireRadius=vec2(WIDTH-100,105),100 | |
end | |
function draw() | |
background(backgroundColor) | |
FPS=FPS*0.9+0.1/DeltaTime | |
perspective(FOV) | |
local d=joy:update() | |
local aim=joyAiming:update() | |
player:update(d.x, d.y, aim.x, aim.y) | |
if joy:isTouched() or joyAiming:isTouched() then player.viewAngle=-90+player.angle+player.turretAngle end | |
SetCamera() | |
for _,t in pairs(T) do | |
t:update(0,0,0,0) | |
t:draw(camPos,camLook) | |
end | |
player:draw(camPos,camLook) | |
DrawShots(T) | |
DrawTerrain(camPos) | |
joy:draw() | |
joyAiming:draw() | |
ortho() | |
viewMatrix(matrix()) | |
pushStyle() | |
if player:ready() then fill(109, 150, 205, 100) else fill(255,0,0,100) end | |
ellipse(firePos.x,firePos.y,fireRadius) | |
fill(0) | |
fontSize(18) | |
text("FPS: "..math.floor(FPS),50,HEIGHT-25) | |
text("Speed: "..math.floor(player.speed),50,HEIGHT-50) | |
fill(255,255,0,100) | |
if drawTouch then ellipse(drawTouch.x,drawTouch.y,25) drawTouch=nil end | |
if aiming then | |
stroke(0) | |
strokeWidth(2) | |
line(WIDTH/2,0,WIDTH/2,HEIGHT) | |
line(0,HEIGHT/2,WIDTH,HEIGHT/2) | |
noFill() | |
ellipse(WIDTH/2,HEIGHT/2,200) | |
end | |
popStyle() | |
end | |
function SetCamera() | |
if aiming then | |
local b1,b2=player:SetAim() | |
local d=(b2-b1):normalize() | |
camPos=b2+d*2.3 | |
camLook=camPos+d | |
else | |
camPos=player.pos+RotateVector(vec3(0,20,-20),player.viewAngle,0) | |
camLook=player.pos+vec3(0,15,0) | |
end | |
camera(camPos.x,camPos.y,camPos.z,camLook.x,camLook.y,camLook.z) | |
end | |
function SetLighting(m,s) | |
s=s or TankShader | |
m.shader=shader(s.v,s.f) | |
m.shader.directDirection=vec4(-2,2,1,0):normalize() | |
m.shader.ambientColor=color(255)*0.5 | |
m.shader.directColor=color(255)*0.5 | |
m.shader.fog=fogRange | |
m.shader.mistColor=backgroundColor | |
m.shader.offset=0 | |
m.shader.mModel=modelMatrix() | |
return m | |
end | |
function touched(t) | |
drawTouch=vec2(t.x,t.y) | |
if joy:touched(t) or joyAiming:touched(t) or FireButtonTouched(t) then return | |
elseif t.state==MOVING then | |
player.viewAngle=player.viewAngle+2*t.deltaX/WIDTH*FOV | |
end | |
aiming=nil | |
end | |
function FireButtonTouched(t) | |
if t.state==ENDED and vec2(t.x,t.y):dist(firePos)<fireRadius then | |
if not aiming then | |
aiming=true | |
else | |
player:Shoot() | |
aiming=nil | |
end | |
end | |
return true | |
end | |
--# Test8 | |
--[[ | |
displayMode(NORMAL) | |
-- Tiger3 | |
displayMode(STANDARD) | |
function setup() | |
backgroundColor=color(255) | |
fogRange=5000 | |
FOV=45 | |
camPos=vec3(0,5,30) | |
camLook=camPos+vec3(0,0,-1) | |
ax,ay=0,0 | |
T={} | |
for j=1,1 do | |
T[j]=Tank() | |
T[j].pos=vec3(0,0.5,0) | |
T[j].turretAngle=0 | |
T[j]:rotate(180) | |
T[j].turretAngle=0--math.random(-35,35) | |
T[j].gunAngle=0--math.random(0,5) | |
T[j].turretAngleChange=0.25 | |
T[j].gunAngleChange=0.1 | |
end | |
T[1]:PenetrationTest(camPos,(camLook-camPos):normalize()) | |
end | |
function draw() | |
background(0) | |
perspective() | |
camera(camPos.x,camPos.y,camPos.z,camLook.x,camLook.y,camLook.z) | |
T[1]:draw(camPos,camLook) | |
end | |
function SetLighting(m,s) | |
s=s or TankShader | |
m.shader=shader(s.v,s.f) | |
m.shader.directDirection=vec4(-2,2,1,0):normalize() | |
m.shader.ambientColor=color(255)*0.5 | |
m.shader.directColor=color(255)*0.5 | |
m.shader.fog=fogRange | |
m.shader.mistColor=backgroundColor | |
m.shader.offset=0 | |
m.shader.mModel=modelMatrix() | |
return m | |
end | |
function touched(t) | |
if t.state~=ENDED then | |
ay,ax=ay+t.deltaX,ax+t.deltaY | |
elseif t.state==ENDED and vec2(WIDTH/2,HEIGHT/2):dist(vec2(t.x,t.y))<200 then | |
m=matrix(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1) | |
m=m:rotate(-ax,1,0,0) | |
m=m:rotate(-ay,0,1,0) | |
d=m*vec3(0,0,-1) | |
p=d*10 | |
T[1]:PenetrationTest(d,p) | |
end | |
end | |
function touched(t) | |
if t.state~=ENDED then | |
T[1]:PenetrationTest(vec3(0,0,10),vec3(0,0,-1)) | |
end | |
end | |
--]] | |
--# Backup | |
--backup | |
function backup(projectName,ver,comments,load) | |
local backupName=projectName..": "..ver..".txt" -- name of the backup file | |
local dds="/Documents/Dropbox.assetpack/" | |
local path = os.getenv("HOME").."/Documents/" | |
local file = os.getenv("HOME")..dds..backupName | |
local t=io.open(file,"r") | |
if t then | |
if load then | |
local txt=t:read('*a') | |
saveProjectTab("Recovered",txt) | |
end | |
io.close() | |
return | |
end | |
local wFd = io.open(file,"w") | |
local tabList=listProjectTabs() | |
data="--"..comments.."\n\n" | |
local txt | |
if #tabList>0 then | |
for _,tab in pairs(tabList) do | |
data=data..string.format("\n--# %s\n",tab) | |
local tt=readProjectTab(tab) | |
data=data..tt | |
if tab=="Versions" then txt=tt end | |
end | |
wFd:write(data) | |
end | |
wFd:close() | |
print(ver.." backup made") | |
--update version history | |
if not txt then txt="--[[VERSION HISTORY\n\n--]]" end | |
local i=txt:find("--]]") | |
txt=txt:sub(1,i-1)..""..ver.." ("..os.date("%c")..") - "..comments.."\n--]]" | |
saveProjectTab("Versions",txt) | |
end | |
--# Versions | |
--[[VERSION HISTORY | |
ver 101c (Sun Oct 25 17:18:22 2015) - Full controls working ver2 | |
ver 102 (Mon Oct 26 07:37:20 2015) - Aiming v1 | |
ver 102b (Mon Oct 26 08:15:19 2015) - Aiming v3 | |
ver 102c (Mon Oct 26 08:35:48 2015) - Aiming blue/red v4 | |
ver 103 (Mon Oct 26 14:23:31 2015) - Shooting seems to work v1 | |
--]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment