I am making an 2d rpg game with box2d. So, I've got a problem. When one of my bodies(the character) collides with another(a door) the map needs to change, should I just create new screens for maps and change them? Or is there a more simple solution?
You can change your current map on the same screen only. What you have to do is, Let's say your map variable name is testMap. Now let's say your player just collided with a door. Now let's say you will call a method called changeMap(). Here is what you will put inside changeMap() method. (Assuming you are using tiled maps, you can change logic accordingly here)
void changeMap() {
Gdx.app.postRunnable(() -> { //Post runnable posts the below task in opengl thread
testMap = new TmxMapLoader().load("someMap.tmx"); //load the new map
renderer.getMap().dispose(); //dispose the old map
renderer.setMap(testMap); //set the map in your renderer
});
}
Related
I'm using the OrthogonalTiledMapRenderer in libGDX 0.9.9 to render a tiled map in tmx format.
maprend = new OrthogonalTiledMapRenderer(board.getTiledMap(), sprtbatch);
This renderer renders just one single tile in the bottom left corner.
render() { //(shortened)
sprtbatch.setProjectionMatrix(camera.combined);
maprend.render(); }
Using an IsometricTiledMapRenderer with the same constructor renders the whole map.
Is there a known bug in the orthogonal renderer or am I using it wrong?
You need to call maprend.setView(camera); before calling maprend.render();.
Note: There is no need to set the projection matrix of the spritebach there.
I'm new to Geotools. I am developing a simple application that shows a map and I would like to dynamically place a bitmap or vector symbol on it (for example to show where the current position is, like in navigation systems).
Now, what I've done already is:
showing a map given one or more shapefile.
center the map on the last inserted position.
add shapes to new layers when needed.
What I need to do is to create an overlay with images at given coordinates on the map area (to be clear, I don't want to generate a raster layer on disk, I just want to paint on the screen).
My guess is that I have to somehow directly use the Graphics2D instance inside JMapPane, is that correct? In this case how can I convert from the geographic coordinates to pixel coordinates on the drawing pane? Or are there some geotools functions/classes that I should be looking for?
Thank you.
Answering myself, since I found the solution.
I did it by extending class org.geotools.map.DirectLayer, which provides a way to define a custom layer by extending its draw(Graphics2D, MapContent) method. Graphic elements are placed at the correct coordinates by using the worldToScreen affine transform provided by geotools. For example, to define a Point2D placed at the current position given real-world coordinates:
AffineTransform worldToScreen = viewport.getWorldToScreen();
Point2D worldPoint = new Point2D.Double(currentPosition.x, currentPosition.y);
Point2D screenPoint = worldToScreen.transform(worldPoint, null);
Once the draw() method is defined, just instantiate and add as a layer to your MapContent instance.
I have thousands of points that need to be plotted on google maps and got a very responsive maps using the example from https://github.com/ubilabs/google-maps-api-threejs-layer .
Did anyone have a play at this and wondering if it is possible to have different colored markers and possible marker click events?
Appreciate any pointers or examples online.
Millions of clickable data points can be painted on a google map using webgl.
A data point is represented by an x,y pair for a location on the canvas, an int for size, an off screen color, and an on screen color. These values are stored in separate typed arrays.
Each data point has a unique rgb color to act as a key in a lookup table of data point ids.
Create a texture to store the off screen colors and render it to an off screen buffer. On event, load the off screen buffer and use glReadPixels to retrieve the rgb color of the pixel clicked and then find the id in the lookup table. Points on the on screen buffer, what the user sees, can share a common color.
canvas.addEventListener('click', function(ev) {
# insert code to get mouse x,y position on canvas
pixels = new Uint8Array(4);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
if (colorToId[pixels[0] + " " + pixels[1] + " " + pixels[2]]) {
# Pixel clicked is a data point on the map
}
});
Webgl code is lengthy, so only the click event is included.
Here is a live demo and a repo. (angular and coffeescript)
Here is a second example using plain js: webgl-picking-geo-polygons
Here is react-webgl-leaflet
The solution is based on Brendan Kenny's Google Maps + HTML5 + Spatial Data Visualization which explains some of the code in the excerpt above at the 30 min mark, and Displaying WebGL data on Google Maps.
The demo features less than ten data points, but you can just as easily paint over 16 million pickable data points using all combinations of rgb values.
I discovered OpenLayers this past week. Very, very impressive framework. I would strongly suggest taking a look at it. OpenLayers.org is an open source JavaScript web mapping library distinguished from other alternatives, like Leaflet or Google Maps APIs, because of its huge set of components.
I spent the entire weekend creating sample apps by integrating OpenLayers with API's such as MapBox, WebGL etc... After all was said and done, I was extremely impressed with OpenLayers - and I plan to make use of OpenLayers in an upcoming POC/Project.
Here is a link to my test harness. From there you can also download the code for all of the examples, too.
Updates for 2021!!
Google Maps JS now has a WebglOverlayView class and exposes the WebGL context.
const webglOverlayView = new google.maps.WebglOverlayView();
webglOverlayView.onAdd = () => {
// Do setup that does not require access to rendering context.
}
webglOverlayView.onContextRestored = gl => {
// Do setup that requires access to rendering context before onDraw call.
}
webglOverlayView.onDraw = (gl, coordinateTransformer) => {
// Render objects.
}
webglOverlayView.onContextLost = () => {
// Clean up pre-existing GL state.
}
webglOverlayView.onRemove = () => {
// Remove all intermediate objects.
}
webglOverlayView.setMap(map);
Additionally, #googlemaps/three extends this class for easier use with ThreeJS.
// instantiate a ThreeJS Scene
const scene = new Scene();
// Create a box mesh
const box = new Mesh(
new BoxBufferGeometry(10, 50, 10),
new MeshNormalMaterial(),
);
// set position at center of map
box.position.copy(latLngToVector3(mapOptions.center));
// set position vertically
box.position.setY(25);
// add box mesh to the scene
scene.add(box);
// instantiate the ThreeJS Overlay with the scene and map
new ThreeJSOverlayView({
scene,
map,
});
Here is a link to a jQuery/google map app. Not exactly what you are looking for; however you might find the example useful. Feel free to use - it can be downloaded from my site.
Link to app on my website
Click here to download the zip
I´m making a level creator for my platformer game on AS3. I´m looking for a way of getting a graphical representation of a library object on my .fla, so the user can insert that object on the world on the desired coordinate. What I mean with this is that I just want a picture of the first frame of the mc, without taking its properties and methods (without the need to make a .jpg containing that image), because that´s when problems begin to appear, and I just want the object functionality on play mode, not the level creator.
Let´s say, for example, a ball that bounces all the time by updating its location every frame. On the level creator I just want to get the ball picture to insert it on the desired location. If I take the whole ball object to the level creator it won´t stop bouncing and it will mess things up.
I hope I´m clear... I just want to know if there is a practical solution to this; if not then I´ll make a class where all the world objects would extend to, that has a init() function that initializes all the object functionality, so it´s called only on play mode and not on level creator. Thanks for reading anyway.
What you're doing wrong is adding functionality directly to the MovieClip.
Please read one of my previous answers that covers this concept in more depth.
MovieClips should be used for the display only, representing the graphics of an actual game class, for example:
public class Player
{
// Graphics that represent the Player.
protected var display:MovieClip;
// Constructor.
public function Player()
{
display = new PlayerMovieClip();
}
}
Anyways, once you fix that you can take a Bitmap sample of MovieClips using BitmapData and its draw():
// Assume that 'mc' is your MovieClip.
var sample:BitmapData = new BitmapData(mc.width, mc.height, true, 0);
sample.draw(mc);
// This is your image.
var texture:Bitmap = new Bitmap(sample);
I would like to get the Bitmap of the content of a webpage as it is displayed in the BrowserField. Therefore I'd need the Graphic-object of the browser field. But the paint-method is protected unfortunately.
Is there a way to get this?
Thank's
Normally, if you want to do some custom drawing with a field ie. draw into the field's graphics context, you'd subclass Field and override the paint method. However, when it comes to BrowserField, you can't do that because it's declared final.
There is a workaround for this, though. You can subclass a Manager and add your BrowserField to an instance of that manager. So, for example, if you want to add your BrowserField instance to a VerticalFieldManager, you can use the following code to get access to the Graphics object the browser will be drawn into. In this sample code, you'll see that I use the graphics object and manager's superclass implementation to draw into a bitmap. Then, that bitmap is drawn to the screen.
VerticalFieldManager vfm = new VerticalFieldManager() {
// Override to gain access to Field's drawing surface
//
protected void paint(Graphics graphics) {
// Create a bitmap to draw into
//
Bitmap b = new Bitmap(vfm.getVirtualWidth(), vfm.getVirtualHeight());
// Create a graphics context to draw into the bitmap
//
Graphics g = Graphics.create(b);
// Give this graphics context to the superclass implementation
// so it will draw into the bitmap instead of the screen
//
super.paint(g);
// Now, draw the bitmap
//
graphics.drawBitmap(0,
0,
vfm.getVirtualWidth(),
vfm.getVirtualHeight(),
b,
0,
0);
}
};
And, there you have a Bitmap containing the contents of the manager. Should note, though, that this has the potential to consume a lot of memory.