繁体   English   中英

Three.js-每x秒生成一个对象并向前移动每个对象(沿着Z)

[英]Three.js - Spawn an object every x seconds and move each object forward (along Z)

我正在使用Three.js制作无尽的亚军风格游戏。 游戏场景和构想的基本设置是一条漫长的道路,汽车驶向您,您必须避开它们。 我仍处于制作此游戏的初期阶段,所以我的第一个问题是我需要英雄角色(躲避汽车的英雄)看起来像他在前进,同时使汽车看起来像他们正在(更快)向英雄角色发展。

我的想法是创建路标对象(路中间的白线),并使其以一定的速度移向处于(0,0)的英雄角色。

我已经成功创建了一个路带对象,并将其放置在路的最后面( RoadStrip.mesh.position.z = -5000; )。 这是我的代码:

var objectRoadStrip = function() {
    this.mesh = new THREE.Object3D();
    this.mesh.name = "roadStrip";

    geomRoadStrip = new THREE.BoxGeometry(20, 11, 300);
    matRoadStrip = new THREE.MeshPhongMaterial({color: Colors.white});

    RoadStrip = new THREE.Mesh(geomRoadStrip, matRoadStrip);
    RoadStrip.name = 'roadStripName';
    this.mesh.add(RoadStrip);
}

function createRoadStrip() {

    new objectRoadStrip();
    RoadStrip.position.y = -72.5;
    RoadStrip.position.z = -5000;

    scene.add(RoadStrip);

}

render()函数中,该函数循环遍历每帧,并在最后一次调用以确保相机和场景更新每帧时,每次render() ,我都能成功地将该条带沿z轴向前移动10 render()称为。 我还添加了一些代码,以便当RoadStrip触摸(0,0)时将其从场景中删除。 请参阅以下内容:

function render(){

    // moves RoadStrip towards (0,0). When it reaches z = -150, remove that strip from the scene

    if (RoadStrip.position.z <= -150) {
        RoadStrip.position.z += 10;
    } else {
        scene.remove(RoadStrip);
    }

    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

我还向init()函数中添加了以下代码,该函数在创建场景时创建RoadStrip ,并继续每10秒创建一次RoadStrip (大约每当RoadStrip达到(0,0)时)。

createRoadStrip();
setInterval( function() {
    createRoadStrip();
}, 10000);

这与我要达到的效果类似,但是请阅读下面的“问题”部分,在其中解释我的真正需求。

问题

我需要每隔x秒钟产生一个RoadStrip (这仍然待我确定,但是现在可以说3秒钟)。 每个RoadStrip需要独立移动到(0,0), z += 10 RoadStrip实例达到(0,0)时,应将其从场景中移除,但是无论其他RoadStrips在原始位置每3秒( z = -5000 ),都应继续生成。

我的尝试/解决方案构想

我已经做了大量的阅读工作,从其他人无休止的亚军游戏中寻找代码,并阅读了SO答案,但似乎没有任何效果。 以下是我尝试过的一些方法,或者一些我认为可行的方法,但我做得不好/对以下内容没有很好的理解:

  1. 想法:不用在setInterval内调用createRoadStrip()函数, RoadStrip每3秒将RoadStrip对象推到数组中,然后调用该数组并沿z轴将数组移动+= 10
  2. 可能的解决方案帮助:我尝试将setInterval更改为少于2秒而不是10秒。 这导致RoadStrip沿Z轴按预期方式移动了2秒钟,但是,当然,在2秒RoadStrip成了另一个RoadStrip ,因此第一个RoadStrip停止沿Z轴移动,而新的RoadStrip停止了移动(持续2秒钟)。以及此过程无限重复。 这非常接近我的需求,但是我需要每个RoadStrip继续移动,并在到达(0,0)时将其从场景中移出

感谢您抽出宝贵的时间阅读我的问题,期待您的解决方案!

类似风格游戏的示例: 第一第二

感谢@ prisoner849及其到线程的链接,我设法找到了解决问题的方法,因此,我在这里为将来遇到相同问题的任何人写一个答案!

我通读了该线程,并找到了该JSFiddle的链接,其中包括一个与我尝试实现的动画相似的成功动画,并且我强烈建议研究该JSFiddle的代码以完全理解如何创建无穷的跑步者效果。

这是有关如何执行此操作的详细说明:

不必无限创建对象并使它们向前动画直到到达终点然后消失(就像我最初认为的正确解决方案一样),您必须创建对象数组并对其进行动画处理。

这是我执行此操作的代码:

var roadStripArray = []

function objectRoadStrip() {

    for (var i = 0; i < 100; i++) {
        geomRoadStrip = new THREE.BoxGeometry(20, 11, 500);
        matRoadStrip = new THREE.MeshPhongMaterial({color: Colors.white});

        RoadStrip = new THREE.Mesh(geomRoadStrip, matRoadStrip);

        RoadStrip.position.set(0, -72.5, -150 - i * 1250);
        RoadStrip.receiveShadow = true;

        scene.add(RoadStrip);
        roadStripArray.push(RoadStrip);
    }

}

for循环的代码i < 100因为我的路很长,因此需要很多条带

这段代码:

RoadStrip.position.set(0, -72.5, 0 - i * 1250);

将每个条带的位置设置为彼此不同,数字1250是每个条带之间的距离

创建对象之后,必须在render()函数中为它们设置动画。 您必须将它们设置为沿Z轴移动,然后创建一条if语句,其中说:“如果任何条带到达终点(您希望其消失的位置),请将其位置重新设置为起点(即这对我来说是一条道路),这意味着您不断循环遍历对象数组,因此不会无限创建它们。

这是带状动画的代码:

// loop that runs every frame to render scene and camera
var clock = new THREE.Clock();
var time = 0;
var delta = 0;
var direction = new THREE.Vector3(0, 0, 1);
var speed = 2000; // units a second - 2 seconds

function render(){
    requestAnimationFrame(render);

    delta = clock.getDelta();
    time += delta;

    roadStripArray.forEach(function(RoadStrip){
        RoadStrip.position.addScaledVector(direction, speed * delta);
        if (RoadStrip.position.z >= 10000) {
            RoadStrip.position.z = -10000;
        } else {
        }
    });
    renderer.render(scene, camera);
}

移动每个小条的代码是:

RoadStrip.position.addScaledVector(direction, speed * delta);

您可以在此处阅读更多有关.addScaledVector的信息 ,但本质上,这是使该带动画化的代码。

然后, if语句检查地带是否触及10000 (即路的尽头),如果触及,则将地带的位置设置为-10000 然后,该条带将沿着Z轴移向终点。

我们将所有这些包装在forEach函数中,以遍历数组中的每个RoadStrip并以相同的方式对其进行动画处理。 我们需要分别对它们进行动画处理,以便我们可以检测其中之一何时到达路的尽头。

谢谢,希望对您有所帮助!

通常,这种情况最好用某种类似于粒子系统的方法来处理:您不会在场景中连续插入/删除对象,而是在初始化过程中创建了一组对象,比如说玩家只能看到10条道路条纹。一次,您的游戏逻辑总是移动这10条条纹,并根据需要更新位置,一旦一条条纹超出视野,则在开始时将其回收,依此类推。 我认为您不会找到能够完全满足您需求的固定解决方案,您需要提出最适合您游戏的更新逻辑。

我有自定义的粒子系统的例子存在 一旦粒子超出范围,当它需要发射新粒子时,该粒子便可供系统使用。 池中的粒子数始终是恒定的,用户可以在此处定义其目的仅仅是为了进行测试。 可以使用类似的方法来操纵您的无限条纹。 该代码的存储库位于https://github.com/leefsmp/Particle-System,但是您可以在那里找到许多其他粒子系统实现,这是我的特定需求。

希望能有所帮助。

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM