我试图在给定角度和初始速度的情况下为射弹的轨迹(以炮弹的形式)制作动画。我已经以一条线的形式建造了“大炮”,并且我的目标是以盒子的形式瞄准,我知道它是基本的,但我只想暂时让炮弹动作。目前,我正在弄乱硬编码的角度和速度,但最终想输入角度和速度,并在输入后进行大炮射击。目标与发射点平行,所以我知道大炮的x值将是(initialVelocity)cos(角度)(时间),而y将是(initialVelocity)sin(角度)(时间) - (g * t ^ 2)/ 2,其中g是长度或距离。目前我所拥有的是一个在屏幕上线性移动的炮弹,它甚至没有在正确的位置开始。
我不是要求为我编写代码,我只想知道如何让大炮从正确的位置移动,并知道我哪里完全错了。如果我教会如何正确操作着色器,我相信我可以让它达到目标。
着色器:
<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 :(得分: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
。