我有一个比编程问题更多的数学问题,对不起,如果我不在正确的部分。在我的2D游戏中,我们可以将相机移动到可以发出声音的物体的地图上,当屏幕中心靠近此物体时,此音量(由0到1的浮点定义)必须增加。例如,当对象位于屏幕中心时,音量为1,当我们离开时,音量必须减小。每个对象都有自己的范围值。 (例如1000像素)。
我不知道如何编写可以计算它的方法。 这是我的一些代码(这不是正确的计算):
private function setVolumeWithDistance():Void
{
sound.volume = getDistanceFromScreenCenter() / range;
// So the volume is a 0 to 1 float, the range is the scope in pixels and
// and the getDistanceFromScreenCenter() is the distance in pixels
}
我已经有了计算物体距中心屏幕的距离的方法:
public function getDistanceFromScreenCenter():Float
{
return Math.sqrt(Math.pow((Cameraman.getInstance().getFocusPosition().x - position.x), 2) +
Math.pow((Cameraman.getInstance().getFocusPosition().y - position.y), 2));
答案 0 :(得分:1)
简单的声学可以提供帮助。
Here是来自点源的声强公式。它遵循距离规则的反平方。将其构建到您的代码中。
您需要考虑全局和屏幕坐标之间的映射。您必须将屏幕上的像素位置映射到物理坐标并返回。
您的距离代码存在缺陷。没有人应该使用pow()
来对数字进行平方。你很容易出现舍入错误。
此代码结合距离计算,正确完成,并尝试解决逆平方强度计算。注意:对于零距离,反平方是奇异的。
package physics;
/**
* Simple model for an acoustic point source
* Created by Michael
* Creation date 1/16/2016.
* @link https://stackoverflow.com/questions/34827629/calculate-sound-value-with-distance/34828300?noredirect=1#comment57399595_34828300
*/
public class AcousticPointSource {
// Units matter here....
private static final double DEFAULT_REFERENCE_INTENSITY = 0.01;
private static final double DEFAULT_REFERENCE_DISTANCE = 1.0;
// Units matter here...
private double referenceDistance;
private double referenceIntensity;
public static void main(String[] args) {
int numPoints = 20;
double x = 0.0;
double dx = 0.05;
AcousticPointSource source = new AcousticPointSource();
for (int i = 0; i < numPoints; ++i) {
x += dx;
Point p = new Point(x);
System.out.println(String.format("point %s intensity %-10.6f", p, source.intensity(p)));
}
}
public AcousticPointSource() {
this(DEFAULT_REFERENCE_DISTANCE, DEFAULT_REFERENCE_INTENSITY);
}
public AcousticPointSource(double referenceDistance, double referenceIntensity) {
if (referenceDistance <= 0.0) throw new IllegalArgumentException("distance must be positive");
if (referenceIntensity <= 0.0) throw new IllegalArgumentException("intensity must be positive");
this.referenceDistance = referenceDistance;
this.referenceIntensity = referenceIntensity;
}
public double distance2D(Point p1) {
return distance2D(p1, Point.ZERO);
}
public double distance2D(Point p1, Point p2) {
double distance = 0.0;
if ((p1 != null) && (p2 != null)) {
double dx = Math.abs(p1.x - p2.x);
double dy = Math.abs(p1.y - p2.y);
double ratio;
if (dx > dy) {
ratio = dy/dx;
distance = dx;
} else {
ratio = dx/dy;
distance = dy;
}
distance *= Math.sqrt(1.0 + ratio*ratio);
if (Double.isNaN(distance)) {
distance = 0.0;
}
}
return distance;
}
public double intensity(Point p) {
double intensity = 0.0;
if (p != null) {
double distance = distance2D(p);
if (distance != 0.0) {
double ratio = this.referenceDistance/distance;
intensity = this.referenceIntensity*ratio*ratio;
}
}
return intensity;
}
}
class Point {
public static final Point ZERO = new Point(0.0, 0.0, 0.0);
public final double x;
public final double y;
public final double z;
public Point(double x) {
this(x, 0.0, 0.0);
}
public Point(double x, double y) {
this(x, y, 0.0);
}
public Point(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public String toString() {
return String.format("(%-10.4f,%-10.4f,%-10.4f)", x, y, z);
}
}