简体   繁体   English

Three.js 使用 2D 纹理\\精灵做动画(planeGeometry)

[英]Three.js Using 2D texture\sprite for animation (planeGeometry)

I'm quite new in html5 and three.js.我对 html5 和three.js 很陌生。 I've been experimenting a bit with it, and basically what I want done is to have a Mesh (I'm using planeGeometry, as the tutorial I followed used it).我一直在尝试使用它,基本上我想要做的是有一个网格(我正在使用planeGeometry,因为我遵循的教程使用了它)。 The Mesh shows different Textures, which can change later on.网格显示不同的纹理,稍后可以更改。

Here's what my code looks like:这是我的代码的样子:

angelTexture = THREE.ImageUtils.loadTexture("images/textures/chars/angel/angel.png");
angelTexture.offset.x = -0.75;
angelTexture.offset.y = -0.75;

angelMesh = new THREE.Mesh( new THREE.PlaneGeometry(79, 53, 79, 53), new THREE.MeshBasicMaterial( { map: angelTexture, wireframe: false } ));

angelMesh.position.x = 0;
angelMesh.position.y = 0;
scene.add(angelMesh);

The problem is that whenever I offset, the Mesh seems big enough to show all the other Sprites (I'm using the texture as a 2D Sprite that I offset to animate it).问题是,每当我偏移时,网格似乎足够大以显示所有其他精灵(我将纹理用作我偏移的 2D 精灵以对其进行动画处理)。 The result is quite disastrous and I am still figuring out how to control how big the Mesh is so that it shows only one snapshot of the Sprite.结果是灾难性的,我仍在想办法控制网格有多大,以便它只显示精灵的一个快照。 All my attempts seem only to resize the Mesh as well as the underlying Texture and still shows all the Sprites.我所有的尝试似乎只是调整网格以及底层纹理的大小,并且仍然显示所有精灵。

Can someone point me in the right direction?有人可以指出我正确的方向吗? Thanks in advance.提前致谢。

... ...

My friend came up with a solution... I missed the repeat property.我的朋友想出了一个解决方案......我错过了重复属性。

angelTexture = THREE.ImageUtils.loadTexture("images/textures/chars/angel/angel.png");
angelTexture.offset.x = -0.75; 
angelTexture.offset.y = -0.75;

angelTexture.repeat.x = 0.25;
angelTexture.repeat.y = 0.25;   
scene.add(angelMesh);

Hope this helps others having the same problem.希望这可以帮助其他有同样问题的人。

I had the same question a while ago, and so I have written up a complete example of animating using a spritesheet as the texture for a PlaneGeometry, and then updating the texture at regular intervals -- check out the example at不久前我有同样的问题,所以我写了一个完整的示例,使用 spritesheet 作为 PlaneGeometry 的纹理进行动画处理,然后定期更新纹理 - 查看示例

http://stemkoski.github.io/Three.js/Texture-Animation.html http://stemkoski.github.io/Three.js/Texture-Animation.html

and view the commented source code for additional explanation.并查看注释的源代码以获取更多解释。

I've noted in my comment to Lee Stemkoski that spritesheets that have more than one row do not work the same when using the newer THREE.TextureLoader() .我在对 Lee Stemkoski 的评论中指出,当使用较新的THREE.TextureLoader()时,具有多于一行的精灵表的工作方式不同。

I am using the following 4x4 sprite image in my tests.我在测试中使用了以下 4x4 精灵图像。

图像显示为每个预期图块突出显示的象限

With no modification to Lee Stemkoski's TextureAnimator function, assuming you have a full 16 tile spritesheet.不修改 Lee Stemkoski 的TextureAnimator函数,假设您有一个完整的 16 块 spritesheet。

var texture = new THREE.TextureLoader().load('grid-sprite.jpg');
var annie = new TextureAnimator(texture, 4, 4, 16, 150);

The animated texture runs backwards.动画纹理向后运行。 Codepen Demo 代码笔演示

在此处输入图片说明

So I made my own which I call 🎉🎉🎉 THREE.SpriteSheetTexture 🎉🎉🎉所以我自己做了一个我称之为 🎉🎉🎉 THREE.SpriteSheetTexture 🎉🎉🎉

THREE.SpriteSheetTexture = function(imageURL, framesX, framesY, frameDelay, _endFrame) {

    var timer, frameWidth, frameHeight,
            x = 0, y = 0, count = 0, startFrame = 0, 
            endFrame = _endFrame || framesX * framesY,
            CORSProxy = 'https://cors-anywhere.herokuapp.com/',
            canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            canvasTexture = new THREE.CanvasTexture(canvas),
            img = new Image();

    img.crossOrigin = "Anonymous"
    img.onload = function(){
        canvas.width = frameWidth = img.width / framesX;
        canvas.height = frameHeight = img.height / framesY;
        timer = setInterval(nextFrame, frameDelay);
    }
    img.src = CORSProxy + imageURL;

    function nextFrame() {
        count++;

        if(count >= endFrame ) {
            count = 0;
        };

        x = (count % framesX) * frameWidth;
        y = ((count / framesX)|0) * frameHeight;

        ctx.clearRect(0, 0, frameWidth, frameHeight);
        ctx.drawImage(img, x, y, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);

        canvasTexture.needsUpdate = true;
    }

    return canvasTexture;
}

And what you need to know about it imageURL is the URL of your spritesheet framesX is how many frames fit along the x axis (left and right) framesY is how many frames fit along the y axis (up and down) delay is how long it the texture waits to change to the next frame _endFrame is optional - How many frames are there (in case it doesnt use a full row)您需要了解的信息imageURL是您的 spritesheet 的 URL 帧framesX是沿 x 轴(左和右)适合的帧数framesY是沿 y 轴(向上和向下)适合的帧数delay是多长时间纹理等待更改为下一帧_endFrame是可选的 - 有多少帧(以防它不使用整行)

That all looks something like this这一切看起来像这样

texture = new THREE.SpriteSheetTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/68819/grid-sprite.jpg', 4, 4, 100, 16);
var material = new THREE.MeshBasicMaterial({ 
    map: texture
});
geometry = new THREE.BoxGeometry( 200, 200, 200 );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

And there was much rejoicing!!!有很多的欣喜!!! Codepen Demo Here Codepen 演示在这里

@Cmndo to make frames flow moves in the right order you just need to update this: @Cmndo 使帧以正确的顺序移动,您只需要更新它:

texture.offset.y = currentRow / this.tilesVertical;

to this:对此:

texture.offset.y = this.tilesVertical - (currentRow / this.tilesVertical);

In this example: https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Texture-Animation.html在这个例子中: https : //github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Texture-Animation.html

To make frames move in the right direction use:要使框架朝正确的方向移动,请使用:

texture.offset.y = (1 - currentRow / _tilesVertical) - (1 / _tilesVertical);

instead of代替

texture.offset.y = currentRow / this.tilesVertical;

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

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