2015-11-05 80 views
0

我試圖給出一個角度和初始速度的彈丸彈道(形式爲炮彈球)的動畫。我已經以線條形式構建了「大炮」,並且我以箱子的形式瞄準了目標,我知道這個目標是基本的,但我現在只想讓彈丸動作向下。目前,我正在使用硬編碼的角度和速度,但最終還是希望輸入角度和速度,並在輸入後進行大炮拍攝。目標是平行於發射點,所以我知道大炮的x值將是(初始速度)cos(角度)(時間),並且y將是(initialVelocity)sin(角度)(時間) - (g * t^2)/ 2,其中g是長度或距離。目前我所擁有的是一個在屏幕上線性移動的炮彈球,它甚至不在正確的位置開始。在2D WebGL中進行動畫製作

我並不是要求爲我寫的代碼,我只想從如何讓大炮從正確的位置移動,並知道我完全錯誤的地方開始。如果我教會如何正確操作着色器,我相信我可以讓它達到目標。

着色器:

<script id="vertex-shader" type="x-shader/x-vertex"> 

precision mediump float; 

attribute vec4 vPosition; 
attribute vec4 vColor; 
varying vec4 fColor; 
uniform float time; 

void main() 
{ 
/*old code from manipulating clock hands*/ 
/* fColor = vColor; 
    float length = sqrt(vPosition.x*vPosition.x + vPosition.y * vPosition.y); 
    gl_Position.x = length*cos(theta); 
    gl_Position.y = length*sin(theta); 
    gl_Position.z = 0.0; 
    gl_Position.w = 1.0; */ 
    fColor = vColor; 
    gl_Position = vPosition; 
} 
</script> 

<script id="background-vertex-shader" type="x-shader/x-vertex"> 

precision mediump float; 

attribute vec4 vPosition; 
attribute vec4 vColor; 
varying vec4 fColor; 

void main() 
{ 
    fColor = vColor; 
    gl_Position = vPosition; 
} 
</script> 

<script id="fragment-shader" type="x-shader/x-fragment"> 

precision mediump float; 
varying vec4 fColor; 

void main() 
{ 
    gl_FragColor = fColor; 
} 
</script> 

的WebGL代碼:

var gl; 
var points = []; 
var colors = []; 
var cannonpoints = []; 
var circlepoints; 

var squarepoints; 

var baseColors = [ 
vec3(1.0,0.0,0.0), 
vec3(0.0,1.0,0.0), 
vec3(0.0,0.0,1.0), 
vec3(1.0,1.0,1.0), 
vec3(0.0,0.0,0.0) 
]; 

var program; 
var backgroundprogram; 

var Time; 
var thetaLoc; 

var angle; 
var initialVel; 
var vx; 
var vy; 



var ballX = -0.5; 
var ballY = -0.5; 
window.onload = function init(){ 
var canvas = document.getElementById("gl-canvas"); 

gl = WebGLUtils.setupWebGL(canvas); 
if(!gl) { 
    alert("webGL isn't available"); 
} 

// configuring WebGL 
gl.viewport(0,0, 
      canvas.width,canvas.height); 
gl.clearColor(0.0,0.0,1.0,1.0); // set background color to black. 

// load the shaders and initialize 
// the attrbibute buffers. 

    program = initShaders(gl, "vertex-shader", "fragment-shader"); 
backgroundprogram = initShaders(gl, "background-vertex-shader", "fragment- shader"); 

    document.getElementById("shoot").onclick = function() { 
    velocity = document.getElementById("velocity").value; 
     angle = document.getElementById("angle").value; 
     console.log("angle="+angle); 
     vx = (Math.cos(angle*(Math.PI/180))*velocity); 
     console.log("vx="+vx); 
     vy = (Math.sin(angle*(Math.PI/180))*velocity); 
     console.log("vy="+vy); 

    } 



Time = 0.0; 
    thetaLoc = gl.getUniformLocation(program,"time"); 

    initBackground(); 
    /****************** 
    initBall(Time,1); 
    *******************/ 
    initBall(Time); 
    //render(); 
    setInterval(render, 100); 
}; 

function render(){ 
    gl.clear(gl.COLOR_BUFFER_BIT); 

    /* draw the circle */ 
    gl.drawArrays(gl.TRIANGLE_FAN,0,circlepoints); 
    /* draw the square(s) */ 
    gl.drawArrays(gl.TRIANGLES,circlepoints,squarepoints); 
    //draw the cannon 
    gl.drawArrays(gl.LINES,circlepoints+squarepoints,2); 
    //draw the cannon ball 
    //starting index is the amount of points already drawn 
     //amount of points for circle + amount of points for square + amount of points for line 
    var start = circlepoints + squarepoints + 2; 
    Time += 0.01; 
    initBall(Time); //,1); 
    gl.uniform1f(thetaLoc,Time); 
    //amount of points to draw is length of points array minus the start index 
    gl.drawArrays(gl.TRIANGLE_FAN,start,points.length-start); 
} 

function initBall(Time) { //,r){ 
    gl.useProgram(program); 

    /******************************************************* 
    filled_circle(vec2(r*Math.cos(Time),r*Math.sin(Time)),0.05,4);*/ 
    vx= (Math.cos(60*(Math.PI/180))*1); 
    vy= (Math.sin(60*(Math.PI/180))*1); 

    filled_circle(vec2(-0.8+(vx*Time),-0.3+(vy*Time)),0.05,4); 

    // Load the data into the GPU 
    var bufferId = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER,     bufferId); 
    gl.bufferData(gl.ARRAY_BUFFER, 
       flatten(points), 
       gl.STATIC_DRAW); 

    // Associate our shader variables with 
    // the data buffer. 
    var vPosition = gl.getAttribLocation(program,"vPosition"); 
    gl.vertexAttribPointer(vPosition,2,gl.FLOAT,false,0,0); 
    gl.enableVertexAttribArray(vPosition); 

    // load color data to the gpu 
    var cBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, 
       cBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, 
       flatten(colors), 
       gl.STATIC_DRAW); 

    var vColor = gl.getAttribLocation(
       program, "vColor"); 
    gl.vertexAttribPointer(vColor,3, 
       gl.FLOAT, false, 0, 0); 
    gl.enableVertexAttribArray(vColor); 

} 
+0

這不是一個真正的WebGL問題。 WebGL只是一個光柵化/繪圖庫。在Javascript中,你可以計算一個位置,方向,然後繪製。您可以使用HTML元素或SVG或Canvas 2D或WebGL進行繪製。執行動畫的代碼不會改變。 – gman

回答

0

我認爲這樣做是給你彈的起始位置,速度和加速度的最簡單的方法。那麼彈丸的位置隨時都是位置+速度*時間+加速度*時間*時間。拋射體的角度只是拋射體當前速度的角度。

如果你想最終添加其他東西,如碰撞,那麼它可能是一個好主意,使彈道追蹤其當前的速度和加速度;並且在每個幀上,位置和速度根據每幀之間的經過時間而改變。像這樣:

Projectile.prototype.update = function(dt){ 
    this.velocity += this.acceleration * dt; 
    this.position += this.velocity * dt; 
    this.angle = getAngle(this.velocity); 
}; 

而且每一幀,調用projectile.update(dt)其中dt = currentFrameTime - lastFrameTime