You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带方向速度的抛射体添加重力效果?

Fixing Gravity for Angled Bullet Trajectories

Alright, let's break down what's going wrong here and fix your bullet's gravity behavior properly. Your core issue is that your initial update logic doesn't correctly separate the bullet's velocity into world-space components—you’re forcing the bullet to always move along its initial launch angle, which cancels out the effect gravity should have on its trajectory.

Why Your Previous Attempts Failed

Let’s unpack the problems with your two tries:

  • First Attempt: You added gravity to vel.y, but then immediately calculated y-displacement using Math.sin(this.angle * Math.PI/4) * this.vel.y. This means the gravity-induced change to vel.y never actually affects the bullet’s movement—you’re still tying y-motion strictly to the initial angle, hence the weird curved path.
  • Second Attempt: Multiplying gravity by Math.sin(this.angle * Math.PI/4) makes gravity act along the bullet’s launch direction instead of straight down. When this.angle is 0, that sine value becomes 0, so gravity does nothing—this is why you saw anomalies at that angle. Gravity should always pull along the world’s y-axis, not the bullet’s initial angle.

The Standard Solution for Projectile Motion

The correct way to handle this follows real-world physics principles:

  1. Decompose initial velocity into x/y components once when the bullet spawns.
  2. Update the y-velocity each frame by adding gravity (since gravity acts vertically).
  3. Update position directly using current velocity—no need to re-use the initial angle every frame.

Step 1: Initialize Bullet Velocity Correctly

When creating the bullet, calculate its initial vel.x and vel.y from the launch angle and speed:

// When spawning the bullet:
const initialSpeed = this.vel; // Assume this was your original speed magnitude
this.vel.x = Math.cos(this.angle * Math.PI/4) * initialSpeed;
this.vel.y = Math.sin(this.angle * Math.PI/4) * initialSpeed;

(Note: Adjust the Math.PI/4 scaling if your angle uses a different unit conversion.)

Step 2: Update Position and Velocity Each Frame

In your bullet’s update function, use the current velocity components directly, then apply gravity to the y-axis:

// In the bullet's update loop:
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
this.vel.y += GRAVITY; 
// Tip: Use a negative GRAVITY value if your y-axis increases downward (common in game engines), positive if y increases upward

This will give you a natural parabolic trajectory: the x-velocity stays constant (no air resistance), while the y-velocity is continuously pulled by gravity, making the bullet arc downward as expected.

Optional: Extending the Behavior

If you want to add extra physics touches, you can build on this foundation:

  • Air Resistance: Multiply vel.x and vel.y by a drag factor each frame (e.g., this.vel.x *= 0.99; this.vel.y *= 0.99;) to slow the bullet over time.
  • Terminal Velocity: Cap the magnitude of vel.y to a maximum value so the bullet doesn’t accelerate indefinitely.

内容的提问来源于stack exchange,提问作者Kake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:13:18