Rotate sprite on sprite pixel level, not screen pixel level, in LibGDX - java

I'm making a pixelated game, and I'm trying to rotate a sprite. However, I'm not achieving the sort of rotating effect I'm aiming for.
Currently, my sprite looks like this when it rotates:
As you can see, it rotates relatively smoothly. You can see that the 'big pixels' rotate smoothly. However, this isn't the rotating effect I'm looking for. Instead, this is how I want it to rotate:
However, preferably in a way that doesn't distort the pixels as much. You can see the difference. I want the actual 'big pixels' to rotate, not the 'screen pixels'.
I think the issue might lie in how I scale the pixels to become bigger. What I'm doing, is that I'm zooming the camera in, moving it closer sorta. What I instead want to do, is to render like normal, then just scale up the screen pixels. That way I'd automatically achieve the rotation effect I want. I don't know how to do that, though.
This is how I currently 'scale up the pixels':
camera = new OrthographicCamera();
camera.setToOrtho(false, 1280 / 4, 720 / 4);
The game's resolution is 1280x720, so the way I make the pixels bigger is that I just zoom in 4x times.
However, what I instead want to do, is to render like normal, then just stretch the screen 4x times.
Any help on how I could do this would be greatly appreciated.

Have a look at this post. Here is a kind of solution for your problem. Just render first to small frame buffer with nearest neighbor interpolation and then to screen. Perhaps it is not effective way, but definitely the way to achieve such behavior.
Good luck!

Related

Real time screen recording in a LibGDX screen

In short, I'm making a simulation where I have a bunch of creatures that can see each other. The way I want to do this is to capture an area around each creature and give it to their neural network, and make them evolve to recognize their surroundings. I am coding this using LibGDX, and I don't plan on making screenshots every single frame because I can imagine that that is already a very poor idea. However, the problem is that I don't know how to get the pixels inside a defined square without capturing the entire screen and then cherry picking what I want for each creature, which will cause a MASSIVE lag spike, since the area these creatures will be in is 2000x2000, and therefore 12 million different values (4 million RGB values).
Each creature is about 5 pixels (width and height), so my idea is to give them a 16x16 area around them, which is why iterating through the entire frame buffer won't work, it would pointlessly iterate through millions of values before finding the ones I asked for.
I would also need to be able to take pictures outside of the screen (as in, the part outside the window's boundaries), if that is even possible.
How can I achieve this? I'm aiming for performance, but I do not mind distributing the load between multiple frames or even multithreading.
The problem is you can't query pixels in a framebuffer.
You can capture a texture from a framebuffer, and you can convert a texture to a pixmap.
libgdx TextureRegion to Pixmap
You can then getPixel(int x, int y) against the pixmap.
However, maybe going the other way would be better.
Start with a pixmap, work with the pixmap, and for each frame convert the pixmap to a texture and render that texture fullscreen. This also removes the need for the creatures environment to match the screen resolution (although you could still set it up like that).

Libgdx Spritebatch bug

however, i have a weird issue, when drawing, it seems the outside 1px of an image is stretched to fit a rectangle, but the inside is only stetched to an extend, i was drawing to 48x48 tiles, but drew a 500x500 tile to show the issue. [ 500x500 draws fine ]
the worst part seems to be, it chooses when to stretch and not to stretch. and also what to strech. im sorry this is hard to explain but i have attached a image that i hope does a better job.
it could just be misunderstanding how to use a draw with spritebatch
edit: Tile is 48x48 not 64x64, ive just been working all day.
This is because you are not rendering "pixel perfect" which means your image does not line up with the pixel grid of your monitor. A quick fix might be to set a linear filter for your textures, since by default it uses nearest and thus a pixel on the screen will inherit the closest color it can get. A linear filter will interpolate colors and make that line "look" thinner.
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
If you are using texturepacker you can do this in one go by altering it's settings.
texturePackerSetting.filterMin = Texture.TextureFilter.Linear;
texturePackerSetting.filterMag = Texture.TextureFilter.Linear;
Or you could edit the atlas file itself by by changing the filter parameter to:
filter: Linear,Linear
This obviously costs more power since it needs to do more calculations for each pixel you drawn to the screen but I would not worry about this until your drawing is starting to get a bottleneck.
Another solutions is to draw pixel perfect which means you need to set your viewport to the size of the device gdx.graphics.getWidth, gdx.graphics.getHeight, in other words a ScreenViewport and draw your textures at exact sizes you want them. Of course this means a screen with more pixels sees more of your game world then a screen with less pixels and the more pixels a device has the smaller your textures will look. Another drawback of this is that you have to forget about any zooming or draw sprites for each level of zoom so they line up with the pixel grid of the device again.

Line Flickers along Tiles in libGDX

I am making a simple platformer with a tile-based map. However, when the camera moves there is white flickering which I think occurs along the tile boundaries, but it is hard to tell because they flicker quickly.
What I have tried:
adding padding to my Tileset. I have 4px padding around each tile, so it's not image bleeding.
setting the TextureFilter to nearest. It was never on anything else, so Linear wasn't the culprit.
Casting the camera position to an int. While this doesn't fix the flickering it also makes my camera jerky, so this is the worst possible solution.
Setting config.useCPUSync to false and config.vSync to true. While I have set vSync to true I can't set CPUSync to false because, as far as I am aware, this is no longer an option. I get a compile time error when I try.
I am just displaying the map by calling TiledMapRendere.render(), so I don't know if the padding from my Tileset or my Nearest TextureFilter are actually being applied correctly, but that is the only possible issue in my rendering process I can think of.
Any other ideas?
Edit:
So I tried rendering manually and I learned a few things.
Even if I cast every coordinate for each tile to an int and every coordinate in the camera, there is still flickering, so that is defiantly not the answer. However, I then set the TextureFilter on each tile to Linear and that DID solve the flickering, but I don't like how the textures look so it's not really a solution.
This took me forever to figure out: everywhere else I looked gave the solutions I tried above.
What I eventually did is extruded the outer pixels by 1 the same way I would have if I expected there to be blur. I think this worked because when the tiles were scaled, the application sometimes had to choose whether to use the outer pixel or a transparent pixel (my margins) and chose a transparent pixel. So now, the margin around each tile is just another pixel of the same color, so if it chooses that pixel it looks the same to us.

Java Tile Game Zooming

I am building a 2D top-down tile based game in Java. Naturally you can pan around and zoom in on the game, currently zooming in on 10 different levels, where each tile ranges 10x10 pixels to 100x100 pixels appropriately. Currently, the the tiles for each zoom level are stored in separate sprite sheets, read in at the startup of the program and stored in a buffered image array. I am sure this can't be the best way to go about this.
I am looking for any tips to enhance efficiency for the long-term, would it be better to have the 100x100 tiles only and scale them dynamically in java; somehow use vector graphics in java (I'm sure how, but I'm sure google could help me) or what?
Many thanks!
I'd go dynamic.
Normally in computer graphics you use matrices that, applied to the graphics context, modify everything you draw on it.
This is used to modify position, scale, rotation, etc. Rather than subtract the camera position to every tile, you apply the translation once to the graphics context, and then you draw your tiles in world position. The graphics context will take care of placing the tiles in the correct screen space.
I suggest you the following reads:
http://docs.oracle.com/javase/tutorial/2d/advanced/transforming.html
http://www.javalobby.org/java/forums/t19387.html
If you're doing fixed zooming (i.e. each zoom level is a fixed distance from the camer), as opposed to fluid zooming (the player can zoom in by 3.3x, 7.5x, and not just 1x, 2x, 3x, etc.) then it's massively wasteful to try to solve this by simply applying a zoom transform. It's tempting because that's the least complicated approach, and it's easy to understand from an implementation standpoint, but that means that at maximum zoom-out, you're going to be rendering an area that's 10x larger in the X direction, and 10x larger in the Y direction - so the area of the world that you have to render is 100x larger than at maximum zoom-in. I also doubt that you'll like the way your textures get squished by the hardware as you're zooming out. Computer graphics isn't the same as optics - subpixel rendering, and other things that happen in computer graphics aren't going to make your textures look very good if you hand that task off the the software/hardware.
Even if you do fluid zooming, I would still do level-of-detail textures, and dynamically swap them out depending on the distance between the world being rendered, and the camera.
Also, 10 zoom levels? Are you sure you really need 10 zoom levels? Zoom is usually used in 2D games to allow you to perform different activities at different levels of detail because a particular zoom level is especially well suited for a certain set of activities. I don't remember any 2D game that needed 10 zoom levels to accomplish this. 3-5 is the most I've ever seen, and I've never felt that it wasn't enough. It also seems like a lot of art work to produce the images at every zoom level for 10 zoom levels.
You're also likely going to find that applying an AffineTransform sounds like a good idea, but that it's extremely computationally expensive, and if you need 60fps performance, you're highly unlikely to achieve it this way. Don't take my word for it though, go try it and see how badly it falls over on itself.

Java - Keeping scaling relative to image's rotation

For an assignment, I need to make a "doll" in Java where you can move it around and rotate the arms and legs to make funny/cool poses. In addition, the legs should be able to stretch (but not get wider, this is important).
The way I wanted to handle the leg stretching was invert the rotation done to the leg to get it back in the neutral straight position, scale it in the y direction, and then re-perform the rotation. However, it appears the scaling is always going to be in the y direction, so once it's rotated, the leg will become wider. It will only look as it should if it's brought back straight and standing.
The code I have right now looks something like this:
leg.transform(AffineTransform.getRotateInstance(legAngle,pivot.getX(),pivot.getY()).createInverse());
leg.transform(AffineTransform.getScaleInstance(1,scaleFactor);
leg.transform(AffineTransform.getRotateInstance(legAngle,pivot.getX(),pivot.getY()));
How can I make sure the scaling stays relative to the image after rotation?
There are a couple of ways that come to mind. The first (simplest, but slowest) method is to render the stretched leg image to an image, then rotate and render that image. Another way is to use Math.cos and Math.sin to apply the proper scaling in each dimension for the desired effect in the image.

Categories

Resources