I am creating a small isometric online game and would like to use the sheetengine.
Here is my basic idea:
create a scene of the size approx 4100x3000
creating 75x45 basesheets (since the World is 75x45 fixed and wont increase)
To place some objects on the map I use the class Sheet (I will only change the size and the position of the sheets after placing them)
For Zoom In/Out I actually redraw the whole scene - so I destroy all the basesheets and then place them from new in a bigger size - as for the Sheets ... I'm trying to change their size and their position
For moving the map I'm using the method scene.setCenter - since the scene is already of that huge size, I don't have to redraw the map after the translation
My questions:
How can I change the position and the size of the sheet after placing them? I know that using the SheetObject you can do all that, but I will have a huge amount of objects placed and the calculation time is taking to long with SheetObjects. That's why I'm not using that class... An object of the "class" Sheet has a property
sheet.data.translationx
I coudl also manipulate this and thsi works, but there must be method and I couldn't find it
Is there a better way of handling big scenes with sheetengine? I mean creating a scene that big is definitely not a good Idea. But if I make it smaller, I will not see the whole world after a translation - so how could I handle it differently?
Related
I have some geoJSON polygons that I render via layers on top of my map. Depending on the shape itself and the zoom level, sometimes the rendered shapes are too small and it doesn't make sense to even show them.
Is there a way to hide shapes that have rendered area less than some number?
So, as Babis.amas suggested, first I calculate the area of the feature with help of turf.area. It gives the value in square meters. Then I convert this value to pixels using the function mentioned here. And then it really depends on the shape type I'm dealing with. If the shape considered to be too small to be rendered, I just don't add it to the layer data feature collection.
I am working on trying to create a basic, grid-based, but performant weather-arrow visualization system.
EDIT 2:
Up-to-date version here: ( Mapbox Tracker ) of the system using the workflow which is described below
Usage Instructions:
- Click on Wind icon (on the left)
- Wait for triangles to occupy screen
- Pan time-slider (at the bottom)
As you will observe (especially on larger resolutions or when panning time slider quickly) there is quite a performance hit when drawing the triangles.
I would greatly appreciate any advice on where to start with either using something in the current API which would help, or any ideas on how to tap into the current graphics pipeline with some type of custom buffer where I would only need to rotate, scale, change color of triangles already populated in screen space.
I feel as though my specific use-case would greatly benefit from something like this, I really just don't know how to approach it.
I have a naive implementation running using this workflow:
Create a geojson FeatureCollection source
Create a fill layer
Using Data Driven property: fill-color
Data function:
Get map bounds
Project sw & ne into screen points (map.project(LatLng))
Divide height and width into portions
Loop through width and height portions
Lookup data
Access data rotation property
Create vertices based on center point + size
Rotate vertices
Create Point objects for vertices
Unproject Point Object and wrap map.unproject(Point).wrap()
Create Feature Object, assign Data driven Color
Assign unprojected LatLng as Coordinates to Polygon geometry
Add to Feature Array for Collection
Call setData on layer
So while this works, I'm looking for advice for a more performance friendly approach.
What I'm thinking here is whether I can somehow create a custom layer, one where I only need to draw to screen co-ordinates to represent the data relative to its LatLng point. So that I can draw colored, scaled, rotated triangles in screen space, and then have them update to relevant data from the new relative LatLng position.
E.g. Update some type of Mesh on screen instead of having to: unproject, then update feature collection source using map.getSource('arrows').setData(d), requestAnimationFrame(function) etc.
I've done similar in three.js in other projects but I would much rather use something that is more mapbox native. Does this sound feasible? Am I going to see a decent performance boost if so?
I've not dealt with raw gl calls before etc so I might need a pointer or two in the right direction if its going to need to get as low level as that.
EDIT:
Previous Implementation using gmaps / three.js : volvooceanrace
(wait for button on left to go from grey to black) click on top button which shows a 'wind' label when hovered over, slide red time bar underneath to change data.
Added screenshot of current working implementation
Mapbox GL Arrows
Not sure what was available in 2016, but a reasonable approach these days might be to use symbol layers, and the icon-rotate data-driven property to rotate each icon based on the property of its data point.
I am looking for some inputs on, how I can add wall thickness to a 3D model without using softwares like blender.
I am having a 3D model built dynamically using vertices and indexes to build the wall. Now I need to take this model for printing. I need to add wall thickness before I take it for printing.
Is there any library which does that, or a document which explains how to do it?
My thought (which wont work in every case):
If it is a cylinder model, then we can just increase the radius of it and just join the bigger and the smaller cylinders to get a wall thickness. But what if we have a asymmetrical object? this technique wont work here.
I am currently working on a map generator application based on javascript, and I have wrote more than 400 lines of code, that creates a hexagonal map, adds coordinates to tiles, adds textures on tiles like grass, ocean and elements like castles, units etc.
I have added quite a few useful functions to this offline map editor, like zoom in and zoom out, turning grid on/off, dragging the map, and a few others, and I'm currently studying on how to add save and load functionality to this offline game map editor.
It sort of looks like a paint application, except that instated of drawing pixels, you use it to draw a map with hex tiles. You simply click on Generate a new map and you give your desired map size (e.g 64 tiles width by 64 tiles height) and the map is drawn for you, the tiles are simple divs that have the relative background image as texture. Tiles are drawn one by one using a simple for loop. But as the code grows in size so does my worries.
Because the map I create on my own map editor will be used on an online multiplayer game, it will be huge! for example to support at least 20000 users on the upcoming game there should be at least 20000 tiles, only for the users to occupy, not to mention the territory they will own, mountains, jungles, barbarian tribes, and so on..
I have made the calculations and found out that a 512 by 512 (about 262000 tiles) map will sufficiently answer the needs of that many users. However, the map will be huge. so I decided to test and see how much load time does it take to make such a map using the codes I have created with the least process possible and I found out that it takes nearly a minute or more, which is not acceptable, from a gamers perspective.
A zoom in for example in such a huge map will mean looping through every 262000 tile to change their size. although the process takes less time than drawing/loading the map from scratch, but it is still slow.
I was thinking with a map that huge which won't even fit in a browser's window, why should I draw the entire map? why not instead load the part which the user is currently looking at. Loading/drawing only the part that is needed, this way reducing load time and increasing performance. But this is proving to be a real challenge, and there are very limited resources online about implementing such a functionality. Where to start? How to approach the problem and respective solution?
I would start out by separating your concerns a little more. You're able to view WxH number of pixels, and the top left of the user's screen sits at (x,y) coordinates.
Loading the entire map, as you have pointed out, is crazy. But by knowing how large the game world is, and by knowing the user's coordinates in that world, you can easily select the subset of items that are in view.
Keep in mind that at a zoomed out resolution you shouldn't be using the full-sized images. Loading 262000 images (for just the map!) is going to be too heavy and probably crash. You should have different images for different zoom levels. This is a much bigger question and you should buy a book and do more research on google. But at least the thinking about the "where the user is" vs "where the items in the world are" is a place that I would start at.
Hope that helps.
I've looked around for layering objects within the same canvas but haven't found a lot of information about it.
At the moment I've used the multiple canvas technique to layer things on top of each other
example:
canvas Holder <--- this holds all other canvas's
loading canvas
menu canvas
game canvas
background canvas
and by adding them to the "stage = new stage (mainCanvas)" in a specific order, i get the desired layering
stage.addChild(background);
stage.addChild(game);
stage.addChild(menu);
stage.addChild(loading);
This works great, however I'm wondering whether there is a way to change the zIndex of an image added to the 'game' canvas if I had 2 images in that canvas?
I've seen this sort of thing done in the fieldrunners game, the game follows a grid like format and when you place a shooter in the square above another shooter, is gets repositioned behind it..
http://fieldrunnershtml5.appspot.com/#sd --- works in chrome
any ideas how it was done?
Thanks
There is no need for multiple canvases. When you work with a game in canvas 2d you usually clear and redraw the canvas ~60 times per second. What you draw last ends up on top. So in order to simulate layers you sort all game objects in an array based on their z-index then you iterate over all objects in the array, invoking their draw methods.
There is much room for optimizing such a renderer, but this is a basic and simple way to make it work.
A canvas is just pixels - it has no "layers".
If you want to perform parallax scrolling, that sort of thing, put multiple canvases in the same place, and use transparency to show the ones behind.
Your technique using multiple canvases to implement layers is totally good approach. You should also keep track on which layer needs to be cleared/redrawn - for example map should be refreshed only when scrolled or GUI/HUD really doesn't need to be redrawn 60 times per second.
There is no such thing as z-index or objects in canvas, all mechanisms depends on your own implementation. For example you can make an array of commands or objects to draw - then sort it by zIndex (or whatever you name it) and execute each element.