How to draw a tilemap in three.js?

Hey guys,

i want to draw a tilemap(bunch of sprites) in three.js ,
in javascript i just iterate over map array(sprites) and draw the index position of sprite

how can i archive same with Threejs ?

here is my code but not complete -> https://pastebin.com/qXBeEdj8

You basically transform texture coordinates by modifying Texture.repeat and Texture.offset. You just need to know some properties about your sprite sheet e.g. how many images it contains and the respective dimensions. Check out the following live demo to see this approach in action:

https://jsfiddle.net/f2Lommf5/16880/

2 Likes

how can i loop tilesets, if i have tile of 3x3 (3rows and 3 cols) i want to loop like in javascript from left top to bottom right ,your exemple i can only loop by x axis but not y

Try it with this implementation: https://jsfiddle.net/3uf8ba5w/

You have to define the amount of columns, rows and the total amount of images in your sprite sheet. You can then do this in your render loop:

const t = clock.getElapsedTime() * fps;

const imageIndex = Math.floor( t % totalCount );
const col = imageIndex % cols;
const row = Math.floor( imageIndex / cols );
			
spriteSheet.offset.x = col / cols;
spriteSheet.offset.y = 1 - ( ( 1 + row ) / rows );

thank you, i will try that !

well did not figure it out…

here is example of javascript that i want archive on Threejs

https://jsfiddle.net/v2sjknqd/

Oh, your image is different than I’ve expected:

it just a tileset, 16px by 16px ,i just map it with position of Map array to position on screen, i want archieve same thing in Threejs

i have tried with your spritesheet and it worked
but as i putted my tiles sheet 3rows and 3cols 16px by 16px ,it does not even displays lol

https://jsfiddle.net/v6r13L0w/

Your image URL is not valid. Try it like so: https://jsfiddle.net/3uf8ba5w/1/

2 Likes

Yes ,that works , but it displays not in original width and height,also positioning on screen does not works,i tried spriteSheet.position.set(200,400) didn’t worked
https://jsfiddle.net/1x94m3sy/

i am looking for that kind to be able place on screen depending on size of map
https://jsfiddle.net/v2sjknqd/

Um, I’m not sure it makes sense to replicate the logic from your fiddle by just transforming texture coordinates. As far as I can see, your fiddle performs multiple calls to CanvasRenderingContext2D.drawImage() per frame in order to produce the final result of the animated texture.

Have you considered to use THREE.CanvasTexture in order to wrap the final/target canvas element into a texture object and render it on a plane? In this way, you can reuse most of the existing code. Using a canvas element as a data source of a texture is also demonstrated in this example:

https://threejs.org/examples/webgl_materials_texture_canvas.html

" As far as I can see, your fiddle performs multiple calls to CanvasRenderingContext2D.drawImage() per frame in order to produce the final result of the animated texture."

yes it is because of animation several sprites, i 'm updating canvas at each frame

well i think the best way to explain you what i want to build is a 2d game in 3d world pixelworld, my pure javascript performes about 60 frames per second,but it will go down if i will add more sprites on it.
That’s i want give a try with ThreeJS !
as i saw some examples the thing is that i cannnot draw sprite directly in canvas ?, i need to create a material put a sprite on it then create a Geometry and finally create a Mesh
like here: var mesh1 = new THREE.Mesh( geometry, material );
the approach is like i want create a loop that loops through mapArray (example that i linked you above) and position the sprite based on array length of row and col to the Screen(canvas) position
i found this example https://github.com/mrdoob/three.js/blob/master/examples/webgl_raycast_sprite.html looks like position its easy, but maybe it’s not suited for best performance?

Hey, concerning your exemple here https://jsfiddle.net/f2Lommf5/16880/ , how can i choose the index to start and end of the sprite ? like i want to animate from 2s index to 4th etc

The code of the fiddle is too simple in order to support such requirements. You need a more advanced approach to make things more configurable. Unfortunately, I don’t have time to develop a solution for you. Maybe you find something useful in this thread:

thank you for help, i just figured it out