0

所以我制作了自己的 FPS、图形和枪支以及所有这些很酷的东西;当我们开火时,子弹应该在十字准线内随机移动,定义如下:

    float randomX=(float)Math.random()*(0.08f*guns[currentWeapon].currAcc)-(0.04f*guns[currentWeapon].currAcc);
    float randomY=(float)Math.random()*(0.08f*guns[currentWeapon].currAcc)-(0.04f*guns[currentWeapon].currAcc);

    bulletList.add(new Bullet(new float[]{playerXpos, playerYpos, playerZpos}, new float[]{playerXrot+randomX, playerYrot+randomY}, (float) 0.5));

我们计算 X 和 Y 的随机性(假设你的十字准线大小 (guns[currentWeapon].currAcc) 为 10,那么子弹可以向任何一侧移动 0.4 并且它会保留在十字准线内。计算完之后,我们发送玩家位置作为子弹的起始位置,以及它打算采取的方向(具有额外随机性的玩家方向),最后是速度(不是重要的 atm,tho)。

现在,每一帧,子弹都必须移动,所以对于每个子弹,我们调用:

position[0] -= (float)Math.sin(direction[1]*piover180) * (float)Math.cos(direction[0]*piover180) * speed;
position[2] -= (float)Math.cos(direction[1]*piover180) * (float)Math.cos(direction[0]*piover180) * speed;

position[1] += (float)Math.sin(direction[0]*piover180) * speed;

因此,对于 X 和 Z 位置,子弹根据玩家在 Y 和 X 轴上的旋转移动(假设您水平观察 Z,X 为 0 度,Y 为 0;X 将移动 0*1*speed 和 Z将移动 1*1* 速度)。

对于 Y 位置,子弹根据 X 轴上的旋转移动(在 -90 和 90 之间变化),这意味着如果玩家水平看,它会保持在相同的高度,如果玩家垂直看,它会完全向上移动。

现在,问题如下:如果我水平拍摄,一切都很好。子弹散布在十字准线周围,如https://dl.dropbox.com/u/16387578/horiz.jpg所示

问题是,如果我开始向上看,子弹开始集中在中心周围,并使这条垂直线越靠近我看的天空。 https://dl.dropbox.com/u/16387578/verti.jpg 第一张图片在 X 轴上大约 40º,第二张稍微高一点,最后一张是我垂直看的时候。

我在这里做错了什么?我自己设计了这个解决方案,我很确定我在某个地方搞砸了,但我想不通:/

4

2 回答 2

0

基本上垂直偏移计算 (float)Math.cos(direction[0]*piover180) 搞砸了 X 和 Z 的运动,因为它们都会被减少到 0。子弹会形成一条垂直线,因为它们会旋转X 轴具有随机性。我的解决方案是在垂直偏移计算之后添加随机性,因此在您触发它们后它们仍然会左右上下移动。

我还必须添加一个额外的随机值,否则你只会画一条对角线或一个十字。

    float randomX=(float)Math.random()*(0.08f*guns[currentWeapon].currAcc)-(0.04f*guns[currentWeapon].currAcc);
    float randomY=(float)Math.random()*(0.08f*guns[currentWeapon].currAcc)-(0.04f*guns[currentWeapon].currAcc);
    float randomZ=(float)Math.random()*(0.08f*guns[currentWeapon].currAcc)-(0.04f*guns[currentWeapon].currAcc);

    bulletList.add(new Bullet(new float[]{playerXpos, playerYpos, playerZpos}, new float[]{playerXrot, playerYrot}, new float[]{randomX,randomY, randomZ},(float) 0.5));

和移动代码...

    vector[0]= -((float)Math.sin(dir[1]*piover180) * (float)Math.cos(dir[0]*piover180)+(float)Math.sin(random[1]*piover180)) * speed;
    vector[1]= ((float)Math.sin(dir[0]*piover180)+(float)Math.sin(random[0]*piover180)) * speed;
    vector[2]= -((float)Math.cos(dir[1]*piover180) * (float)Math.cos(dir[0]*piover180)+(float)Math.sin(random[2]*piover180)) * speed;
于 2013-02-18T20:14:15.283 回答
0

您不需要进行任何复杂的数学运算,您的问题是,当您围绕 y 轴旋转子弹以进行枪支传播时,如果您直接向上看(也就是说,通过 y 轴,子弹正在旋转绕着它前进的路径,这意味着没有任何旋转(想象一下将手臂向前伸向墙壁并转圈和将手臂伸向天空并转圈之间的区别。请注意,您的手没有当指向天空(y轴)时根本不动,所以你会得到那些“对角线”子弹传播。

诀窍是在按玩家注视的方向旋转之前进行子弹散布,因为这样您就知道当您旋转散布时,矢量保证垂直于 x 轴和 y 轴。

  this.vel = new THREE.Vector3(0,0,-1);
  var angle = Math.random() * Math.PI * 2;
  var mag = Math.random() * this.gun.accuracy;
  this.spread = new THREE.Vector2(Math.cos(angle) * mag,Math.sin(angle) * mag);
  this.vel.applyAxisAngle(new THREE.Vector3(0,1,0),this.spread.y / 100); //rotate first when angle gaurenteed to be perpendicular to x and y axes
  this.vel.applyAxisAngle(new THREE.Vector3(1,0,0),this.spread.x / 100); 
  this.vel.applyAxisAngle(new THREE.Vector3(1,0,0),player.looking.x); //then add player looking direction
  this.vel.applyAxisAngle(new THREE.Vector3(0,1,0),player.looking.y);
  this.offset = this.vel.clone()

我不使用 java,但我希望你能通过这个 javascript 了解我在做什么。我通过spread.y 和spread.x 沿负z 方向(相机的默认方向)旋转一个矢量,然后我通过玩家面对的角度的俯仰和偏航旋转。

于 2018-06-16T17:52:01.870 回答