36.飞行音乐

36.Flight Music

As well as being useful for working with triangles, the sine function can also be used for generating sounds. If you take an ever increasing number and pass it to the sine function, you get back this graph:

正弦函数不仅对处理三角形非常实用,它也可以被用于生成声音。倘若你将一个不断增加的数字序列作为参数传递给正弦函数,你将得到如下图像:

If you treat this as a sound wave, then you get a dull tone that we recognise as an electronic beep, since it’s used so often by electronic devices. Here’s an example of a sine wave on youtube.

如果你将其视为一个声音波形的话,你将得到一个沉闷的音调,就像我们熟知的电子蜂鸣声一样,因为它经常被电子设备所使用。这儿是youtube网站的一个正弦波示例

We saw in our last post that for our monkeys-throwing-bananas game, we can work out how long the banana will be in flight for. We can use this information to construct a sound that’s exactly as long as the time the banana will spend in the air:

我们在上一篇关于猴子扔香蕉游戏的帖子中了解到,我们可以计算出香蕉将要飞行多长时间。我们可以利用这个信息来创建一个声音,它的长度完全等同于香蕉在空中飞行的时间:

double lengthInSecs = timePerFrame  * (impactTime - 5);
short[] soundWave = new short[(int)(lengthInSecs * 44000.0)];

The sound will play at 44000 samples per second, so we need to multiply the number of seconds by 44000 to get the number of samples. The length of the sound in seconds will be the time it takes to execute one frame in Greenfoot, multiplied by the number of frames before impact (“impactTime”, above — which we saw how to calculate last post). I subtract 5 frames off the total, to make sure that the sound is finished before we need to play the impact sound.

声音在每秒钟将会播放个44000样本,于是我们需要用44000乘以秒数来获取样本的数量。在greenfoot的每一帧中,声音的长度(以秒为单位)将会作为时间值去乘以碰撞之前经过的帧的数量(就是“impactTime”,我们在上一篇帖子中知道了如何去计算)。我在总数上减去了5帧,以便确保飞行声音在我们需要播放碰撞声音前结束。

Just playing a simple sine wave for the sound of the flight is dull and incongruous. We can greatly improve the suitability of the sound if we vary the frequency of the sine wave during the flight. If we change the frequency in proportion to the height of the banana, we get a sound that starts low, increases in pitch as the banana reaches the apex of its flight, then decreases again as it comes back down. This creates a more familiar flight sound (such as you hear in cartoons). The gist is something like this — the sine wave gets more frequent (the peaks get closer together, horizontally), the higher the projectile is in the air:

仅仅播放一个简单的正弦波作为飞行的声音是单调的不和谐的。如果我们在飞行过程中改变正弦波的频率,则可以几大地改善声音的适应性。如果我们按照香蕉高度的比例来改变声波频率,我们将得到这样一个声音:开始时较低,然后逐渐升高音调直到香蕉飞行高度达到顶峰,接下来随着香蕉下落而重新降低音调。这将创建一个更加熟悉的飞行声音(正如我们在动画片中听到的)。大意是这样的—抛射物在空中越高,声音正弦波则越紧密(在水平方向波峰变得更加靠近了):



What this means is that instead of using a steadily-increasing number to feed to the sine wave function, you increase the number faster when the banana is higher. Here’s some code that does just that, using the height calculation from our previous post:

这意味着你不能使用一个稳定增长的数字作为参数传递给正弦函数,而是当香蕉变得高一些时要让数字增加得快一些。这里有一些代码实现这个功能,使用到了前一篇帖子中的高度计算代码

        double a = 0;
        for (int i = 0; i < soundWave.length; i++)
        {
            // t is the frame number:
            double t = (double)i / (timePerFrame * 44000.0);

            a += 0.25 + (t * vy - 0.5 * g * t * (t - 1)) / 3200.0;
            
            soundWave[i] = (short)(8000 * Math.sin(a));
        }

There are three constants in this code that I fiddled with until they sounded right (literally!). The 0.25 and the 3200 on the middle line of the loop adjust the amount that the height of the projectile affects the frequency of the sine wave. The 8000 in the last line is simply the volume of the sound (the height of the sine wave).

这段代码中有三个常量,我不断的调整它们的值,直到它们听起来比较正确。循环代码中间一行的0.25和3200用来调节抛射物高度影响正弦波频率的量。最后一行的8000只是声音的音量(即正弦波的高)。

You can play with the finished game (including a couple of simple AI players) over on the Greenfoot site. Don’t forget to listen to the flight sounds!

你可以到greenfoot官网玩以一下完成后的游戏(包括了一些简单的AI玩家)。不要忘了听一下飞行音乐哦!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium.js是一个强大的JavaScript库,用于创建三维地球和地图。它广泛应用于地理信息系统(GIS)和虚拟地球等领域。在Cesium中,飞行功能允许用户在三维地球或地图上飞行,以查看更广阔的视野或更详细的地形。 要使用Cesium的飞行功能,您需要执行以下步骤: 1. 初始化Cesium环境:首先,您需要创建一个Cesium场景(Scene)对象,该对象将包含您的地图和飞行器。 ```javascript var scene = new Cesium.Scene({ scene3DOnly: true, // 仅显示3D场景 minimumPixelSize: new Cesium.Cartesian2(800, 600) // 设置最小像素大小 }); ``` 2. 创建飞行器(FlightVehicle):您需要创建一个飞行器对象,该对象将控制您的飞行行为。Cesium提供了一个名为FlightVehicle的类,它代表一个可以飞行的物体。 ```javascript var vehicle = new Cesium.FlightVehicle(); ``` 3. 设置飞行器的位置和速度:您可以使用飞行器的setPosition和setVelocity方法来设置飞行器的位置和速度。这些方法接受经纬度、高度和速度作为参数。 ```javascript vehicle.setPosition(new Cesium.Cartesian3(longitude, latitude, altitude)); vehicle.setVelocity(new Cesium.Cartesian3(velocityX, velocityY, velocityZ)); ``` 4. 添加飞行器到场景中:最后,您需要将飞行器添加到场景中,以便它可以被渲染和飞行。 ```javascript scene.entities.add(vehicle); ``` 一旦您完成了这些步骤,您就可以使用Cesium的API来控制飞行器的飞行了。例如,您可以使用setHeading方法来设置飞行器的朝向,使用flyTo方法来导航到新的位置。 请注意,飞行功能可能会受到地图数据和设备性能的影响。在处理复杂的地图或高分辨率数据时,您可能需要调整场景的配置或优化代码以获得更好的性能。 此外,Cesium还提供了许多其他功能和API,可以帮助您创建更高级的地理信息系统应用。您可以查阅Cesium的文档以获取更多详细信息和示例代码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值