SC CODE: // Copyright 2024. Civilware. All rights reserved.
// TELA Decentralized Web Document (TELA-DOC-1)
Function InitializePrivate() Uint64
10 IF init() == 0 THEN GOTO 30
20 RETURN 1
30 STORE("nameHdr", "index.html")
31 STORE("descrHdr", "Index file")
32 STORE("iconURLHdr", "")
33 STORE("dURL", "index.html")
34 STORE("docType", "TELA-HTML-1")
35 STORE("subDir", "")
36 STORE("fileCheckC", "d3db15f64b5134140e0b71476ed1b77ae80723007bcbae2cae3e4b8957f97aa")
37 STORE("fileCheckS", "28ca09bf52105c1a394a10e61f8ce1f53bce370d9916df68867702b277ac7c08")
100 RETURN 0
End Function
Function init() Uint64
10 IF EXISTS("owner") == 0 THEN GOTO 30
20 RETURN 1
30 STORE("owner", address())
50 STORE("docVersion", "1.0.0")
60 STORE("hash", HEX(TXID()))
70 STORE("likes", 0)
80 STORE("dislikes", 0)
100 RETURN 0
End Function
Function address() String
10 DIM s as String
20 LET s = SIGNER()
30 IF IS_ADDRESS_VALID(s) THEN GOTO 50
40 RETURN "anon"
50 RETURN ADDRESS_STRING(s)
End Function
Function Rate(r Uint64) Uint64
10 DIM addr as String
15 LET addr = address()
16 IF r < 100 && EXISTS(addr) == 0 && addr != "anon" THEN GOTO 30
20 RETURN 1
30 STORE(addr, ""+r+"_"+BLOCK_HEIGHT())
40 IF r < 50 THEN GOTO 70
50 STORE("likes", LOAD("likes")+1)
60 RETURN 0
70 STORE("dislikes", LOAD("dislikes")+1)
100 RETURN 0
End Function
/*<!DOCTYPE html>
<html>
<head>
<!--
Full Tank 3D - Open Source under the MIT License
See LICENSE for details. -->
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100%;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
#ui {
position: absolute;
left: 0;
top: 0;
z-index: 10;
pointer-events: none;
background: transparent;
}
</style>
</head>
<body>
<canvas id="gl"></canvas>
<canvas id="ui"></canvas>
<script src="data1.js"></script>
<script src="data2.js"></script>
<script src="data3.js"></script>
<script src="data4.js"></script>
<script>initAudio(),window.addEventListener("resize",resizeCanvas);const canvas=document.getElementById("gl"),gl=canvas.getContext("webgl");let aspect=0;const uicanvas=document.getElementById("ui"),ctx=uicanvas.getContext("2d"),mapScaler=5;let minimapSize,MAP_W,MAP_H,mapScaleX,mapScaleZ,mapOffsetX,mapOffsetZ;function updateProjection(){aspect=canvas.width/canvas.height,camera.projectionMatrix=camera.getProjectionMatrix(aspect)}function resizeCanvas(){canvas.width=window.innerWidth,canvas.height=window.innerHeight,uicanvas.width=window.innerWidth,uicanvas.height=window.innerHeight,camera&&updateProjection(),gl.viewport(0,0,canvas.width,canvas.height),resizeMap()}const camera=new Camera;resizeCanvas(),gl.viewport(0,0,canvas.width,canvas.height);let vertexShaderSource="\nprecision mediump float;\n\nuniform bool uSkipShading;\n\nattribute vec2 uv;//treads & textures\n\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec3 color;\n\nuniform mat4 uModel;\nuniform mat4 uView;\nuniform mat4 uProj;\n\nvarying vec2 vUV;//treads\n\nvarying vec3 vNormal;\nvarying vec3 vColor;\n\n\nvoid main() {\t\n\tvNormal = normal;\n\tvColor = color;\n\tvUV = uv;\n\tgl_Position = uProj * uView * uModel * vec4(position, 1.0);\n}\n\n",fragmentShaderSource="\nprecision mediump float;\n\nvarying vec3 vNormal;\nvarying vec3 vColor;\nuniform bool uUseHeightTint;\n\n//Regular textures\nuniform bool uUseTexture;\nuniform sampler2D uTexture;\n\n//treads\nuniform bool uUseTreadTexture;\nuniform float uTreadOffset;\nuniform sampler2D uTreadTex;\nvarying vec2 vUV;\nuniform bool uSkipShading;\nvoid main() {\n\nvec3 N = normalize(vNormal);\nvec3 base = vColor;\n\n// If shading is skipped, we still want textures\nif (!uSkipShading) {\n\n\tvec3 lightDir = normalize(vec3(1.0, 1.0, 1.0));\n\tfloat diffuse = max(dot(N, lightDir), 0.0);\n\n\tfloat steep = 1.0 - N.y;\n\tvec3 slopeColor = mix(vColor, vColor * 0.3, steep);\n\n\tfloat heightTint = clamp((vColor.g - 0.3) * 2.0, 0.0, 1.0);\n\tvec3 heightColor = mix(vec3(0.1, 0.4, 0.1), vec3(0.6, 0.6, 0.6), heightTint);\n\n\tbase = slopeColor;\n\n\tif (uUseHeightTint) {\n\t\tbase = mix(slopeColor, heightColor, 0.5);\n\t}\n}\n\n// TEXTURE ALWAYS OVERRIDES COLOR, EVEN IF SHADING IS SKIPPED\nbool hasValidUV = (vUV.x >= 0.0 && vUV.y >= 0.0);\n\nif (uUseTexture && hasValidUV) {\n\tvec4 tex = texture2D(uTexture, vUV);\n\n\tif (tex.a < 0.1) {\n\t\t// treat transparent pixels as hull color\n\t\tbase = vColor;\n\t} else {\n\t\tbase = tex.rgb;\n\t}\n}\n\n\nif (uUseTreadTexture) {\n\tvec2 uv2 = vec2(vUV.x, vUV.y + uTreadOffset);\n\tbase = texture2D(uTreadTex, uv2).rgb;\n}\n\n// If shading is skipped, output raw texture\nif (uSkipShading) {\n\tgl_FragColor = vec4(base, 1.0);\n\treturn;\n}\n\n// Otherwise apply lighting\nfloat ambient = 0.25;\nfloat diffuse = max(dot(N, normalize(vec3(1.0))), 0.0);\nfloat highlight = pow(diffuse, 8.0) * 0.2;\n\nvec3 litColor = base * (ambient + diffuse) + highlight;\ngl_FragColor = vec4(litColor, 1.0);\n\n}\n";function compile(e,t,r){const a=e.createShader(t);return e.shaderSource(a,r),e.compileShader(a),e.getShaderParameter(a,e.COMPILE_STATUS)||console.error("Shader compile error:",e.getShaderInfoLog(a)),a}const vs=compile(gl,gl.VERTEX_SHADER,vertexShaderSource),fs=compile(gl,gl.FRAGMENT_SHADER,fragmentShaderSource),program=gl.createProgram();gl.attachShader(program,vs),gl.attachShader(program,fs),gl.linkProgram(program),gl.getProgramParameter(program,gl.LINK_STATUS)||console.error("Program link error:",gl.getProgramInfoLog(program)),gl.useProgram(program);const uProj=gl.getUniformLocation(program,"uProj"),uModel=gl.getUniformLocation(program,"uModel"),uView=gl.getUniformLocation(program,"uView"),uUseHeightTint=gl.getUniformLocation(program,"uUseHeightTint"),uUseTexture=gl.getUniformLocation(program,"uUseTexture"),uTexture=gl.getUniformLocation(program,"uTexture"),uTreadOffset=gl.getUniformLocation(program,"uTreadOffset"),uUseTreadTexture=gl.getUniformLocation(program,"uUseTreadTexture"),uTreadTex=gl.getUniformLocation(program,"uTreadTex"),uSkipShading=gl.getUniformLocation(program,"uSkipShading");gl.enable(gl.DEPTH_TEST);const posLoc=gl.getAttribLocation(program,"position");gl.enableVertexAttribArray(posLoc);const normLoc=gl.getAttribLocation(program,"normal");gl.enableVertexAttribArray(normLoc);const colorLoc=gl.getAttribLocation(program,"color");gl.enableVertexAttribArray(colorLoc);const uvLoc=gl.getAttribLocation(program,"uv");gl.enableVertexAttribArray(uvLoc);class Material{constructor(e=null){this.texture=e}}class Mesh{constructor(e,t,r,a,n=null,o=e.TRIANGLES){this.vertexCount=t.length/3,this.mode=o,this.material=new Material,this.posBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.posBuf),e.bufferData(e.ARRAY_BUFFER,t,e.STATIC_DRAW),this.normBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.normBuf),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),this.colorBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.colorBuf),e.bufferData(e.ARRAY_BUFFER,a,e.STATIC_DRAW),n?(this.uvBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.uvBuf),e.bufferData(e.ARRAY_BUFFER,n,e.STATIC_DRAW)):this.uvBuf=null}draw(e,t,r,a,n){e.bindBuffer(e.ARRAY_BUFFER,this.posBuf),e.vertexAttribPointer(t,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.normBuf),e.vertexAttribPointer(r,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorBuf),e.vertexAttribPointer(a,3,e.FLOAT,!1,0,0),this.uvBuf&&-1!==n?(e.bindBuffer(e.ARRAY_BUFFER,this.uvBuf),e.vertexAttribPointer(n,2,e.FLOAT,!1,0,0)):e.disableVertexAttribArray(n),e.drawArrays(this.mode,0,this.vertexCount),-1!==n&&e.enableVertexAttribArray(n)}}function drawObject(e,t,r,a){const n=e.transform.getMatrix(t);if(gl.uniformMatrix4fv(uModel,!1,n),gl.uniformMatrix4fv(uView,!1,r),gl.uniformMatrix4fv(uProj,!1,a),gl.uniform1i(uUseHeightTint,!!e.profile),gl.uniform1i(uSkipShading,e.skipShading?1:0),e.isTread){let t=treadTexture,r=e.treadOffset;e.isShortTread&&(t=treadTextureHalf,r*=2),gl.uniform1i(uUseTreadTexture,!0),gl.uniform1f(uTreadOffset,r),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,t),gl.uniform1i(uTreadTex,0)}else gl.uniform1i(uUseTreadTexture,!1);if(e.mesh.material&&e.mesh.material.texture?(gl.uniform1i(uUseTexture,!0),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,e.mesh.material.texture),gl.uniform1i(uTexture,1)):gl.uniform1i(uUseTexture,!1),e.mesh.draw(gl,posLoc,normLoc,colorLoc,uvLoc),e.children&&e.children.length)for(const t of e.children)drawObject(t,n,r,a)}function render(){gl.clearColor(.45,.65,.95,1),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);const e=camera.getProjectionMatrix(canvas.width/canvas.height),t=camera.getViewMatrix();for(const r of scene)drawObject(r,null,t,e)}function createProceduralTread(e){const t=64,r=new Uint8Array(16384);for(let e=0;e<t;e++){const a=e%8<4?120:60;for(let n=0;n<t;n++){const o=4*(e*t+n);r[o]=a,r[o+1]=a,r[o+2]=a,r[o+3]=255}}const a=e.createTexture();return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,t,0,e.RGBA,e.UNSIGNED_BYTE,r),e.generateMipmap(e.TEXTURE_2D),a}function createProceduralTreadHalf(e){const t=64,r=new Uint8Array(16384);for(let e=0;e<t;e++){const a=e%16<8?120:60;for(let n=0;n<t;n++){const o=4*(e*t+n);r[o]=a,r[o+1]=a,r[o+2]=a,r[o+3]=255}}const a=e.createTexture();return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,t,0,e.RGBA,e.UNSIGNED_BYTE,r),e.generateMipmap(e.TEXTURE_2D),a}const treadTexture=createProceduralTread(gl),treadTextureHalf=createProceduralTreadHalf(gl);function createWindshieldAtlas(e){const t=64,r=new Uint8Array(16384);for(let e=0;e<16;e++)for(let a=0;a<16;a++){const n=4*((0+e)*t+(48+a));if(e<9.6){r[n+3]=0;continue}if(e<9.92){r[n]=100,r[n+1]=60,r[n+2]=0,r[n+3]=255;continue}if(e<10.4){r[n]=20,r[n+1]=40,r[n+2]=60,r[n+3]=255;continue}const o=e/16,i=20+20*o,u=40+40*o,l=60+60*o;r[n]=i,r[n+1]=u,r[n+2]=l,r[n+3]=255}const a=e.createTexture();return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,t,0,e.RGBA,e.UNSIGNED_BYTE,r),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),a}const windshield=createWindshieldAtlas(gl);function curve(e){return Math.abs(e)<.2?0:Math.sign(e)*Math.pow(Math.abs(e),1.5)}function updateInput(e){const t=game.player;switch(input.toggleCamera&&("barrel"===camera.mode?(resetCameraForLookAt(t),camera.mode="lookAt"):"lookAt"===camera.mode?camera.mode="topdown":camera.mode="barrel"),t.profile.steeringModel){case"tank":updateTankSteering(t,input.turn,e);break;case"car":updateCarSteering(t,input.turn,e);break;case"drift":updateDriftSteering(t,input.turn,e)}updateMovement(t,input.up,input.down,e);const r=curve(input.turretTurn),a=curve(input.turretPitch);t.turret.yaw+=r*e*(2*camera.zoom),t.turret.pitch+=a*e*(1.5*camera.zoom),t.turret.pitch=Math.max(-.2,Math.min(t.turret.pitch,.6)),input.primaryFire&&t.primaryFireCooldown<=0&&(shootTurret(t),t.primaryFireCooldown=t.primaryFireRate),input.secondaryFire&&t.secondaryFireCooldown<=0&&(shootMachineGun(t),t.secondaryFireCooldown=t.secondaryFireRate),input.dropMine&&t.mineCooldown<=0&&(dropMine(t),t.mineCooldown=t.mineFireRate),t.primaryFireCooldown-=e,t.secondaryFireCooldown-=e,t.mineCooldown-=e}let t=0,scene=[],debugObjects=[],worldObjects=[],projectiles=[];const STATE={TITLE:0,MENU:1,PLAYING:2,PAUSED:3,LEVELCOMPLETE:4,WIN:5};let game={},currentLevel=1;function resetGame(){t=0,game.bases=[],game.enemies=[],game.particles=[],scene=[],debugObjects=[],worldObjects=[],projectiles=[]}function newLevel(e){switch(e){case 1:createLevel1();break;case 2:createLevel2();break;case 3:createLevel3();break;case 4:createLevel4()}}function updateEnemies(e){for(let t of game.enemies)updateEnemy(t,e);for(const e of game.enemies)updateVehicle(e)}function updateStatus(e){if(game.player.health<=0&&game.player.dead)return resetGame(),newLevel(currentLevel),void(game.player.dead=!1);0===Object.keys(game.bases).length&&0===game.enemies.length&&(game.state=STATE.LEVELCOMPLETE)}function update(e){gatherInput(),ctx.clearRect(0,0,uicanvas.width,uicanvas.height),game.state!==STATE.PLAYING||away||(t+=e,updateStatus(e),updateInput(e),updateVehicle(game.player,e),updateCollisions(),updateEnemies(e),updateProjectiles(e),updateParticles(e),updateCamera(),render())}game.bases=[],game.enemies=[],game.particles=[],newLevel(1),game.state=STATE.TITLE;let last=performance.now();function loop(e){const t=e-last;away=t>200;last=e,update(t/1e3),renderHUD(e),requestAnimationFrame(loop)}requestAnimationFrame(loop);
</script>
</body>
</html>*/ |
| SC Arguments: [Name:SC_ACTION Type:uint64 Value:'1' Name:SC_CODE Type:string Value:'// Copyright 2024. Civilware. All rights reserved.
// TELA Decentralized Web Document (TELA-DOC-1)
Function InitializePrivate() Uint64
10 IF init() == 0 THEN GOTO 30
20 RETURN 1
30 STORE("nameHdr", "index.html")
31 STORE("descrHdr", "Index file")
32 STORE("iconURLHdr", "")
33 STORE("dURL", "index.html")
34 STORE("docType", "TELA-HTML-1")
35 STORE("subDir", "")
36 STORE("fileCheckC", "d3db15f64b5134140e0b71476ed1b77ae80723007bcbae2cae3e4b8957f97aa")
37 STORE("fileCheckS", "28ca09bf52105c1a394a10e61f8ce1f53bce370d9916df68867702b277ac7c08")
100 RETURN 0
End Function
Function init() Uint64
10 IF EXISTS("owner") == 0 THEN GOTO 30
20 RETURN 1
30 STORE("owner", address())
50 STORE("docVersion", "1.0.0")
60 STORE("hash", HEX(TXID()))
70 STORE("likes", 0)
80 STORE("dislikes", 0)
100 RETURN 0
End Function
Function address() String
10 DIM s as String
20 LET s = SIGNER()
30 IF IS_ADDRESS_VALID(s) THEN GOTO 50
40 RETURN "anon"
50 RETURN ADDRESS_STRING(s)
End Function
Function Rate(r Uint64) Uint64
10 DIM addr as String
15 LET addr = address()
16 IF r < 100 && EXISTS(addr) == 0 && addr != "anon" THEN GOTO 30
20 RETURN 1
30 STORE(addr, ""+r+"_"+BLOCK_HEIGHT())
40 IF r < 50 THEN GOTO 70
50 STORE("likes", LOAD("likes")+1)
60 RETURN 0
70 STORE("dislikes", LOAD("dislikes")+1)
100 RETURN 0
End Function
/*<!DOCTYPE html>
<html>
<head>
<!--
Full Tank 3D - Open Source under the MIT License
See LICENSE for details. -->
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100%;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
#ui {
position: absolute;
left: 0;
top: 0;
z-index: 10;
pointer-events: none;
background: transparent;
}
</style>
</head>
<body>
<canvas id="gl"></canvas>
<canvas id="ui"></canvas>
<script src="data1.js"></script>
<script src="data2.js"></script>
<script src="data3.js"></script>
<script src="data4.js"></script>
<script>initAudio(),window.addEventListener("resize",resizeCanvas);const canvas=document.getElementById("gl"),gl=canvas.getContext("webgl");let aspect=0;const uicanvas=document.getElementById("ui"),ctx=uicanvas.getContext("2d"),mapScaler=5;let minimapSize,MAP_W,MAP_H,mapScaleX,mapScaleZ,mapOffsetX,mapOffsetZ;function updateProjection(){aspect=canvas.width/canvas.height,camera.projectionMatrix=camera.getProjectionMatrix(aspect)}function resizeCanvas(){canvas.width=window.innerWidth,canvas.height=window.innerHeight,uicanvas.width=window.innerWidth,uicanvas.height=window.innerHeight,camera&&updateProjection(),gl.viewport(0,0,canvas.width,canvas.height),resizeMap()}const camera=new Camera;resizeCanvas(),gl.viewport(0,0,canvas.width,canvas.height);let vertexShaderSource="\nprecision mediump float;\n\nuniform bool uSkipShading;\n\nattribute vec2 uv;//treads & textures\n\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec3 color;\n\nuniform mat4 uModel;\nuniform mat4 uView;\nuniform mat4 uProj;\n\nvarying vec2 vUV;//treads\n\nvarying vec3 vNormal;\nvarying vec3 vColor;\n\n\nvoid main() {\t\n\tvNormal = normal;\n\tvColor = color;\n\tvUV = uv;\n\tgl_Position = uProj * uView * uModel * vec4(position, 1.0);\n}\n\n",fragmentShaderSource="\nprecision mediump float;\n\nvarying vec3 vNormal;\nvarying vec3 vColor;\nuniform bool uUseHeightTint;\n\n//Regular textures\nuniform bool uUseTexture;\nuniform sampler2D uTexture;\n\n//treads\nuniform bool uUseTreadTexture;\nuniform float uTreadOffset;\nuniform sampler2D uTreadTex;\nvarying vec2 vUV;\nuniform bool uSkipShading;\nvoid main() {\n\nvec3 N = normalize(vNormal);\nvec3 base = vColor;\n\n// If shading is skipped, we still want textures\nif (!uSkipShading) {\n\n\tvec3 lightDir = normalize(vec3(1.0, 1.0, 1.0));\n\tfloat diffuse = max(dot(N, lightDir), 0.0);\n\n\tfloat steep = 1.0 - N.y;\n\tvec3 slopeColor = mix(vColor, vColor * 0.3, steep);\n\n\tfloat heightTint = clamp((vColor.g - 0.3) * 2.0, 0.0, 1.0);\n\tvec3 heightColor = mix(vec3(0.1, 0.4, 0.1), vec3(0.6, 0.6, 0.6), heightTint);\n\n\tbase = slopeColor;\n\n\tif (uUseHeightTint) {\n\t\tbase = mix(slopeColor, heightColor, 0.5);\n\t}\n}\n\n// TEXTURE ALWAYS OVERRIDES COLOR, EVEN IF SHADING IS SKIPPED\nbool hasValidUV = (vUV.x >= 0.0 && vUV.y >= 0.0);\n\nif (uUseTexture && hasValidUV) {\n\tvec4 tex = texture2D(uTexture, vUV);\n\n\tif (tex.a < 0.1) {\n\t\t// treat transparent pixels as hull color\n\t\tbase = vColor;\n\t} else {\n\t\tbase = tex.rgb;\n\t}\n}\n\n\nif (uUseTreadTexture) {\n\tvec2 uv2 = vec2(vUV.x, vUV.y + uTreadOffset);\n\tbase = texture2D(uTreadTex, uv2).rgb;\n}\n\n// If shading is skipped, output raw texture\nif (uSkipShading) {\n\tgl_FragColor = vec4(base, 1.0);\n\treturn;\n}\n\n// Otherwise apply lighting\nfloat ambient = 0.25;\nfloat diffuse = max(dot(N, normalize(vec3(1.0))), 0.0);\nfloat highlight = pow(diffuse, 8.0) * 0.2;\n\nvec3 litColor = base * (ambient + diffuse) + highlight;\ngl_FragColor = vec4(litColor, 1.0);\n\n}\n";function compile(e,t,r){const a=e.createShader(t);return e.shaderSource(a,r),e.compileShader(a),e.getShaderParameter(a,e.COMPILE_STATUS)||console.error("Shader compile error:",e.getShaderInfoLog(a)),a}const vs=compile(gl,gl.VERTEX_SHADER,vertexShaderSource),fs=compile(gl,gl.FRAGMENT_SHADER,fragmentShaderSource),program=gl.createProgram();gl.attachShader(program,vs),gl.attachShader(program,fs),gl.linkProgram(program),gl.getProgramParameter(program,gl.LINK_STATUS)||console.error("Program link error:",gl.getProgramInfoLog(program)),gl.useProgram(program);const uProj=gl.getUniformLocation(program,"uProj"),uModel=gl.getUniformLocation(program,"uModel"),uView=gl.getUniformLocation(program,"uView"),uUseHeightTint=gl.getUniformLocation(program,"uUseHeightTint"),uUseTexture=gl.getUniformLocation(program,"uUseTexture"),uTexture=gl.getUniformLocation(program,"uTexture"),uTreadOffset=gl.getUniformLocation(program,"uTreadOffset"),uUseTreadTexture=gl.getUniformLocation(program,"uUseTreadTexture"),uTreadTex=gl.getUniformLocation(program,"uTreadTex"),uSkipShading=gl.getUniformLocation(program,"uSkipShading");gl.enable(gl.DEPTH_TEST);const posLoc=gl.getAttribLocation(program,"position");gl.enableVertexAttribArray(posLoc);const normLoc=gl.getAttribLocation(program,"normal");gl.enableVertexAttribArray(normLoc);const colorLoc=gl.getAttribLocation(program,"color");gl.enableVertexAttribArray(colorLoc);const uvLoc=gl.getAttribLocation(program,"uv");gl.enableVertexAttribArray(uvLoc);class Material{constructor(e=null){this.texture=e}}class Mesh{constructor(e,t,r,a,n=null,o=e.TRIANGLES){this.vertexCount=t.length/3,this.mode=o,this.material=new Material,this.posBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.posBuf),e.bufferData(e.ARRAY_BUFFER,t,e.STATIC_DRAW),this.normBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.normBuf),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW),this.colorBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.colorBuf),e.bufferData(e.ARRAY_BUFFER,a,e.STATIC_DRAW),n?(this.uvBuf=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.uvBuf),e.bufferData(e.ARRAY_BUFFER,n,e.STATIC_DRAW)):this.uvBuf=null}draw(e,t,r,a,n){e.bindBuffer(e.ARRAY_BUFFER,this.posBuf),e.vertexAttribPointer(t,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.normBuf),e.vertexAttribPointer(r,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.colorBuf),e.vertexAttribPointer(a,3,e.FLOAT,!1,0,0),this.uvBuf&&-1!==n?(e.bindBuffer(e.ARRAY_BUFFER,this.uvBuf),e.vertexAttribPointer(n,2,e.FLOAT,!1,0,0)):e.disableVertexAttribArray(n),e.drawArrays(this.mode,0,this.vertexCount),-1!==n&&e.enableVertexAttribArray(n)}}function drawObject(e,t,r,a){const n=e.transform.getMatrix(t);if(gl.uniformMatrix4fv(uModel,!1,n),gl.uniformMatrix4fv(uView,!1,r),gl.uniformMatrix4fv(uProj,!1,a),gl.uniform1i(uUseHeightTint,!!e.profile),gl.uniform1i(uSkipShading,e.skipShading?1:0),e.isTread){let t=treadTexture,r=e.treadOffset;e.isShortTread&&(t=treadTextureHalf,r*=2),gl.uniform1i(uUseTreadTexture,!0),gl.uniform1f(uTreadOffset,r),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,t),gl.uniform1i(uTreadTex,0)}else gl.uniform1i(uUseTreadTexture,!1);if(e.mesh.material&&e.mesh.material.texture?(gl.uniform1i(uUseTexture,!0),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,e.mesh.material.texture),gl.uniform1i(uTexture,1)):gl.uniform1i(uUseTexture,!1),e.mesh.draw(gl,posLoc,normLoc,colorLoc,uvLoc),e.children&&e.children.length)for(const t of e.children)drawObject(t,n,r,a)}function render(){gl.clearColor(.45,.65,.95,1),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);const e=camera.getProjectionMatrix(canvas.width/canvas.height),t=camera.getViewMatrix();for(const r of scene)drawObject(r,null,t,e)}function createProceduralTread(e){const t=64,r=new Uint8Array(16384);for(let e=0;e<t;e++){const a=e%8<4?120:60;for(let n=0;n<t;n++){const o=4*(e*t+n);r[o]=a,r[o+1]=a,r[o+2]=a,r[o+3]=255}}const a=e.createTexture();return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,t,0,e.RGBA,e.UNSIGNED_BYTE,r),e.generateMipmap(e.TEXTURE_2D),a}function createProceduralTreadHalf(e){const t=64,r=new Uint8Array(16384);for(let e=0;e<t;e++){const a=e%16<8?120:60;for(let n=0;n<t;n++){const o=4*(e*t+n);r[o]=a,r[o+1]=a,r[o+2]=a,r[o+3]=255}}const a=e.createTexture();return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,t,0,e.RGBA,e.UNSIGNED_BYTE,r),e.generateMipmap(e.TEXTURE_2D),a}const treadTexture=createProceduralTread(gl),treadTextureHalf=createProceduralTreadHalf(gl);function createWindshieldAtlas(e){const t=64,r=new Uint8Array(16384);for(let e=0;e<16;e++)for(let a=0;a<16;a++){const n=4*((0+e)*t+(48+a));if(e<9.6){r[n+3]=0;continue}if(e<9.92){r[n]=100,r[n+1]=60,r[n+2]=0,r[n+3]=255;continue}if(e<10.4){r[n]=20,r[n+1]=40,r[n+2]=60,r[n+3]=255;continue}const o=e/16,i=20+20*o,u=40+40*o,l=60+60*o;r[n]=i,r[n+1]=u,r[n+2]=l,r[n+3]=255}const a=e.createTexture();return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,t,0,e.RGBA,e.UNSIGNED_BYTE,r),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),a}const windshield=createWindshieldAtlas(gl);function curve(e){return Math.abs(e)<.2?0:Math.sign(e)*Math.pow(Math.abs(e),1.5)}function updateInput(e){const t=game.player;switch(input.toggleCamera&&("barrel"===camera.mode?(resetCameraForLookAt(t),camera.mode="lookAt"):"lookAt"===camera.mode?camera.mode="topdown":camera.mode="barrel"),t.profile.steeringModel){case"tank":updateTankSteering(t,input.turn,e);break;case"car":updateCarSteering(t,input.turn,e);break;case"drift":updateDriftSteering(t,input.turn,e)}updateMovement(t,input.up,input.down,e);const r=curve(input.turretTurn),a=curve(input.turretPitch);t.turret.yaw+=r*e*(2*camera.zoom),t.turret.pitch+=a*e*(1.5*camera.zoom),t.turret.pitch=Math.max(-.2,Math.min(t.turret.pitch,.6)),input.primaryFire&&t.primaryFireCooldown<=0&&(shootTurret(t),t.primaryFireCooldown=t.primaryFireRate),input.secondaryFire&&t.secondaryFireCooldown<=0&&(shootMachineGun(t),t.secondaryFireCooldown=t.secondaryFireRate),input.dropMine&&t.mineCooldown<=0&&(dropMine(t),t.mineCooldown=t.mineFireRate),t.primaryFireCooldown-=e,t.secondaryFireCooldown-=e,t.mineCooldown-=e}let t=0,scene=[],debugObjects=[],worldObjects=[],projectiles=[];const STATE={TITLE:0,MENU:1,PLAYING:2,PAUSED:3,LEVELCOMPLETE:4,WIN:5};let game={},currentLevel=1;function resetGame(){t=0,game.bases=[],game.enemies=[],game.particles=[],scene=[],debugObjects=[],worldObjects=[],projectiles=[]}function newLevel(e){switch(e){case 1:createLevel1();break;case 2:createLevel2();break;case 3:createLevel3();break;case 4:createLevel4()}}function updateEnemies(e){for(let t of game.enemies)updateEnemy(t,e);for(const e of game.enemies)updateVehicle(e)}function updateStatus(e){if(game.player.health<=0&&game.player.dead)return resetGame(),newLevel(currentLevel),void(game.player.dead=!1);0===Object.keys(game.bases).length&&0===game.enemies.length&&(game.state=STATE.LEVELCOMPLETE)}function update(e){gatherInput(),ctx.clearRect(0,0,uicanvas.width,uicanvas.height),game.state!==STATE.PLAYING||away||(t+=e,updateStatus(e),updateInput(e),updateVehicle(game.player,e),updateCollisions(),updateEnemies(e),updateProjectiles(e),updateParticles(e),updateCamera(),render())}game.bases=[],game.enemies=[],game.particles=[],newLevel(1),game.state=STATE.TITLE;let last=performance.now();function loop(e){const t=e-last;away=t>200;last=e,update(t/1e3),renderHUD(e),requestAnimationFrame(loop)}requestAnimationFrame(loop);
</script>
</body>
</html>*/'] |