用three.js写一个简单的3D射门游戏

5,010 阅读4分钟

这个小游戏很简单,一共由3个部分构成。1个平面(球场),1个球体(足球)还有一个立方体(球门)。

上个图给你们感受一下简陋的画风(掘金最高上传5M图片,原来图片都太大了压缩后很不清晰)

当按下空格键时,可以开始游戏。开始游戏后,视角会切换到球门正面,并且球门会开始左右移动。你所做的就是把足球踢进移动的球门中。J键是射门键,按下J键不松开,足球右侧会出现一个可以伸缩的黄色条状物... 这是模仿其他游戏里控制射门的力度,越长就代表力量越大。只按J是中路低平球射门,W+J是中路高球射门,A+J向左地平射门,A+W+J左高球射门,右侧D键同理。这里简述一下这个游戏是怎么运行的。

力量条控制

首先还是keydown事件监听按键。我们设一个变量strong代表力量大小,初始值为0。然后我们考虑一下,进度条不能无限变大,要设定一个最大值假设为15。 我们先来解决控制进度条伸缩也就是实现让strong从0到15再从15到0然后循环效果。 加一个long()方法和一个short()方法。当然方法里还有其他操作,先略过

        function long(){
            setTimeout(function(){
                strong += 1
            },100)
        }
         function short(){
            setTimeout(function(){
                strong -= 1
            },100)
        }

一开始我想,当按下J键首先执行long()方法,然后当strong大于等于15的时候,再执行short方法就OK了。类似这样

        switch(e.keyCode){
            case 74:
                if(strong>=15){
                    short()
                }
                else{
                    long()
                }
            break;
        } 

但是测试的时候发现不行,因为当strong等于15后,执行short(),strong变为14后又会继续执行long()了,实际上strong是先从0变成15,然后14 15 14 15循环。所以这里我增加了一个lock状态,初始值为false。

     switch(e.keyCode){
            case 74:
                if(strong>=15){
                    lock = true
                    short()
                }
                else{
                    lock ? short() : long()
                }
            break;
        } 

当strong大于等于15时,lock变为true, 在short方法里增加当strong为0时,修改lock值为false。

然后我们把strong的变化在页面上表现出来,把立方体Z轴设为strong/100动态改变立方体的高度就行了。

球门和足球的移动

球门的移动是固定速度的,通过改变球门的X,Y,Z轴的位置使球门移动,当球门Y轴位置大于某个值时,让它向右移动。当Y轴位置小于某个值时向左移动。足球的移动原理和球门是一样的,但是我增加了力量对足球速度的影响和足球的转动。足球转动很容易,通过改变rotation即可实现。力量对足球的影响我这里也只是做了一小部门,即力量越大足球飞行速度越快,飞行距离越远。添加一个setInterval方法,在这个方法里声明一个变量times,这个times是用来决定这个setInterval执行多少次的。

        let shootBall = setInterval(function(){
            time = time + 0.5
            if(time == strong){
                clearInterval(shootBall)
            }
            sphere.rotation.x += 1;
            sphere.position.x += strong/100;
        },100)

这里可以看出,力量越大,方法执行的次数也就越多,这样飞行距离就会变长。力量越大,每次足球移动的距离也会越大,所以速度就会越快。当然,力量对足球的影响不可能像我设计的这么简单,例如足球从加速到减速的过程就很复杂,我这里就直接忽视了。有兴趣的同学可以想一想怎么实现。

射门方式和碰撞检测

射门的方向和高度是通过组合按键控制的,组合按键也就是加keyStatus实现的,这个在我前一篇介绍中有就不说了。声明一个变量shootType,然后不同的射门方式都有自己独有的shootType,在keyup时间中监听射门键,当松开J键时,判断shootType来控制射门的方式。

碰撞检测呢是通过球门和足球X,Y,Z轴位置判断的。在足球飞行的过程中,如果检测到了碰撞则进球。

附上下载地址github.com/leslie233/3…