Sprite Animation Pictures are Overlapping - java

I'm trying to make an animation out of an png file, that has various states of an action. My problem is, that the pictures overlap each other while rendering. Is there a solution, where i can only show one picture?
I use the LibGDX lib.
#Override public void show()
{
batch = new SpriteBatch();
img = new Texture("core/assets/ghosty.png");
regions = TextureRegion.split(img, 32, 32);
sprite = new Sprite (regions[0][0]);
Timer.schedule(new Timer.Task(){
#Override
public void run(){
frame++;
if (frame>27){
frame = 0;
if (zeile ==1){
zeile = 0;
}
else
{
zeile = 1;
}
}
sprite.setRegion(regions[zeile][frame]);
}
}, 0, 1/20f);
}
#Override public void render(float delta)
{
//stage.draw();
batch.begin();
sprite.draw(batch);
batch.end();
}

You don't need an extra Timer task and a Sprite instead you need an Animation<>.
Here is a little example of how you render an Animation:
private SpriteBatch batch;
private Texture img;
private Animation<TextureRegion> animation;
private TextureRegion[][] regions;
private Array<TextureRegion> frames;
#Override
public void show() {
batch = new SpriteBatch();
img = new Texture(Gdx.files.internal("ghosty.png")); //Get Texture from asset folder
regions = TextureRegion.split(img, 32, 32);
frames = new Array<TextureRegion>();
int rows = 5, columns = 5; //How many rows and columns the region have
//Fill Frames array with the regions of Texture
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
frames.add(regions[i][j]);
}
}
//Create Animation. 0.1f is the time how long a frame will occur,
//is the animation to fast set this number to a higher value
//so the single frames will stay for a longer time
animation = new Animation<TextureRegion>(0.1f, frames, Animation.PlayMode.LOOP);
}
private float stateTime = 0;
#Override
public void render(float delta) {
//Clear the screen
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//update state time so animation will go further
stateTime += delta;
batch.begin();
//Draw the current frame
batch.draw(animation.getKeyFrame(stateTime), 50, 50);
batch.end();
}
Hope this will help you.
A more efficient and easier way to run animation is to use TextureAtlas instead of Texture. Here is an example for using TextureAtlas: Libgdx Animation not working

Related

Null Pointer Exception when using unProject in Libgdx

I have a smasher game project and having problem when the game switches from MainMenuScreen to MainGameScreen, because of camera.unproject.
Texture img;
Array<Rectangle> listBalloon;
long lastSpawnTime;
OrthographicCamera camera;
BalloonPopper game;
public MainGameScreen(BalloonPopper game) {
this.game = game;
listBalloon = new Array<Rectangle>();
spawnBalloon();
}
#Override
public void show() {
img = new Texture("testBalloon.png");
}
#Override
public void render(float delta) {
ScreenUtils.clear(1, 0, 0, 1);
game.batch.begin();
for(Rectangle blns: listBalloon) {
game.batch.draw(img, blns.x, blns.y, blns.width,blns.height);
}
game.batch.end();
if(TimeUtils.nanoTime() - lastSpawnTime > 1000000000) spawnBalloon();
for(Iterator<Rectangle> iter = listBalloon.iterator(); iter.hasNext();) {
Rectangle blns = iter.next();
blns.y += 200 * Gdx.graphics.getDeltaTime();
if(blns.y > 720) iter.remove();
if(Gdx.input.isTouched()) {
Vector3 blnXY = new Vector3();
blnXY.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(blnXY);
if(blns.contains(blnXY.x, blnXY.y)) {
iter.remove();
}
}
}
}
public void spawnBalloon() {
Rectangle bln = new Rectangle();
bln.x = MathUtils.random(0, 480 - 64);
bln.y = -20;
bln.width = 64;
bln.height = 128;
listBalloon.add(bln);
lastSpawnTime = TimeUtils.nanoTime();
}
In for(Iterator<Rectangle> iter = listBalloon.iterator(); iter.hasNext();) in render(), if I remove the camera.unproject, the program will move to MainGameScreen with no problem. However, sometimes clicking the spawned texture won't remove them and i have to click like a bit above of the texture so it can be removed. So the only thing i know to make it precisely find the location when clicking, is by adding camera.unproject. But yeah the problem is the null pointer exception.
So is there a way to fix this? THX !!

2d animation libgdx is not working

My animation is not working, only a static picture is displayed. I did everything according to the example from libgdx/wiki. Why does not it work?
public class Thorns extends GameObject implements IGameObject {
Animation<TextureRegion> animation;
private static final int FRAME_COLS = 1, FRAME_ROWS = 2;
public Thorns(Texture texture, Body body) {
super(texture, body,false);
Texture walkSheet = new Texture("Thorns.png");
TextureRegion[][] tmp = TextureRegion.split(walkSheet,
walkSheet.getWidth() / FRAME_COLS,
walkSheet.getHeight() / FRAME_ROWS);
TextureRegion[] walkFrames = new TextureRegion[FRAME_ROWS*FRAME_COLS];
int index = 0;
for (int i = 0; i < FRAME_ROWS; i++) {
for (int j = 0; j < FRAME_COLS; j++) {
walkFrames[index++] = tmp[i][j];
}
}
animation = new Animation<TextureRegion>(1.025f, walkFrames);
}
#Override
public void dispose() {
}
int stateTime;
#Override
public void draw(SpriteBatch spriteBatch) {
stateTime += Gdx.graphics.getDeltaTime();
TextureRegion currentFrame = (TextureRegion) animation.getKeyFrame(stateTime, false);
spriteBatch.draw(currentFrame, body.getTransform().getPosition().x, body.getTransform().getPosition().y);
//drawSprite(spriteBatch);
}
}
Animation does not start at all
Quite possible animation is running but you're not getting his view, because you've two frame animation with frame duration 1.025 sec. And your Animation is running without loop.
Try looped Aniamation so pass true as in second parameter of getKeyFrame (float stateTime, boolean looping) method.
#Override
public void draw(SpriteBatch spriteBatch) {
stateTime += Gdx.graphics.getDeltaTime();
TextureRegion currentFrame = animation.getKeyFrame(stateTime, true);
spriteBatch.draw(currentFrame, body.getTransform().getPosition().x, body.getTransform().getPosition().y);
}
EDIT
Change data type of stateTime to float from int.

LibGDX: Drawing 50x50 tiles is very slow

I found some code on the libgdx GitHub that creates a tiled map and populates it. It all works fine until you enlarge the camera to draw ~50x50 tiles. At this point, I get ~5 fps and input is barely responding. Here is the modified code:
public class Core extends ApplicationAdapter {
private AssetManager am;
private SpriteBatch batch;
private BitmapFont font;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
private OrthoCamController cameraController;
#Override
public void create() {
am = new AssetManager();
am.load("tiles.png", Texture.class);
am.finishLoading();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
batch = new SpriteBatch();
batch.disableBlending();
camera = new OrthographicCamera();
camera.setToOrtho(false, (w / h) * 400, 400);
camera.update();
cameraController = new OrthoCamController(camera);
Gdx.input.setInputProcessor(cameraController);
font = new BitmapFont();
map = new TiledMap();
MapLayers layers = map.getLayers();
TiledMapTileLayer layer = new TiledMapTileLayer(200, 200, 8, 8);
TextureRegion[][] splitTiles = TextureRegion.split((Texture)am.get("tiles.png"), 8, 8);
for (int x = 0; x < 1000; x++) {
for (int y = 0; y < 1000; y++) {
int ty = 1;
int tx = 1;
Cell cell = new Cell();
cell.setTile(new StaticTiledMapTile(splitTiles[ty][tx]));
layer.setCell(x, y, cell);
}
layers.add(layer);
}
renderer = new OrthogonalTiledMapRenderer(map, batch);
}
#Override
public void render() {
Gdx.gl.glClearColor(100f / 255f, 100f / 255f, 250f / 255f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
renderer.setView(camera);
renderer.render();
}
#Override
public void resize(int width, int height) {
}
#Override
public void dispose() {
am.dispose();
map.dispose();
}
}
I seriously doubt that Libgdx can't handle that many tiles so my question is: how do I improve performance... or am I being too ambitious?
The only solution I could find was here but it looks like they removed the method used in it.
You probably want to put layers.add(layer); outside the for (int x = 0; x < 1000; x++) loop

Java2D Unacceptable Frame Rate

Java2D Game Running 20-30 FPS
I am writing a java2D game that as of now has an almost perfect memory footprint running only at around 2% of about a 4GB usable RAM space. The problem is the game only is running at around 20-30 fps just from rendering the character and the surrounding environment. I read already something about utilizing the GraphicsConfiguration, but when I tried that my fps soared right up to 120-130 fps while my memory increased to 70-80% and the frame was frozen in one place even if i moved the character. At this point I am stuck. I assume it has something to do with how many times i call g2d.fillRect() because after removing an area that's being referenced the game seems to speed up. The game seems to run smoothly at 20-30 fps, but I need to fix this otherwise my viewable gameobject painter loop will reduce my game to nothing but lag.
Rendering Method With Clipping Areas
private void renderEnvironment(Graphics2D g2d){
for(int paint_index = 0; paint_index < paint_textures.size(); paint_index++){
TexturePaint current_paint = paint_textures.get(paint_index);
//Area a = new Area(new Rectangle(0, 0, host_frame.getWidth(), host_frame.getHeight()));
//a.intersect(new Area(AffineTransform.getTranslateInstance(CamX, CamY).createTransformedShape(paint_regions.get(current_paint))));
g2d.setPaint(new TexturePaint(current_paint.getImage(), new Rectangle(CamX, CamY, current_paint.getImage().getWidth(), current_paint.getImage().getHeight())));
g2d.setClip(AffineTransform.getTranslateInstance(CamX, CamY).createTransformedShape(paint_regions.get(current_paint)));
//g2d.fill(a);
g2d.fillRect(0, 0, host_frame.getWidth(), host_frame.getHeight());
}
for(int paint_index = 0; paint_index < animated_textures.size(); paint_index++){
TextureAnimation current_paint = animated_textures.get(paint_index);
//Area a = new Area(new Rectangle(0, 0, host_frame.getWidth(), host_frame.getHeight()));
//a.intersect(new Area(AffineTransform.getTranslateInstance(CamX, CamY).createTransformedShape(paint_regions.get(current_paint))));
g2d.setPaint(new TexturePaint(current_paint.animatedPaint().getImage(), new Rectangle(current_paint.animatedPaint().getAnchorRect().getBounds().x + CamX, current_paint.animatedPaint().getAnchorRect().getBounds().y + CamY, current_paint.animatedPaint().getImage().getWidth(), current_paint.animatedPaint().getImage().getHeight())));
g2d.setClip(AffineTransform.getTranslateInstance(CamX, CamY).createTransformedShape(paint_regions.get(current_paint)));
//map_graphics.fill(a);
g2d.fillRect(0, 0, host_frame.getWidth(), host_frame.getHeight());
}g2d.setClip(null);
g2d.drawImage(character_sprite.spriteImage(), host_frame.getWidth() / 2, host_frame.getHeight() / 2, host_frame);
for(int paint_index = 0; paint_index < global_textures.size(); paint_index++){
TextureAnimation current_paint = global_textures.get(paint_index);
g2d.setPaint(new TexturePaint(current_paint.animatedPaint().getImage(), new Rectangle(current_paint.animatedPaint().getAnchorRect().getBounds().x + CamX, current_paint.animatedPaint().getAnchorRect().getBounds().y + CamY, current_paint.animatedPaint().getImage().getWidth(), current_paint.animatedPaint().getImage().getHeight())));
//g2d.setClip(new Rectangle(0, 0, host_frame.getWidth(), host_frame.getHeight()));
g2d.fillRect(0, 0, host_frame.getWidth(), host_frame.getHeight());
}
}
EDIT : TextureAnimation.java
public class TextureAnimation implements ActionListener {
private final Action behavior;
private final BufferedImage image;
private final Component host;
private TexturePaint paint;
private final Timer t;
private final boolean isGlobal;
public int x;
public int y;
public TextureAnimation(Action a, BufferedImage i, Component c, boolean global){
isGlobal = global;
behavior = a;
image = i;
host = c;
paint = new TexturePaint(image, new Rectangle(0, 0, image.getWidth(), image.getHeight()));
t = new Timer(300, this);
t.setInitialDelay(0);
}
public void playAnimation(){
t.start();
}
public Boolean isGlobal(){
return isGlobal;
}
public void delayAnimation(int ms_delay){
t.setInitialDelay(ms_delay);
t.restart();
}
public void setIntervalDelay(int ms_delay){
t.setDelay(ms_delay);
}
public void setTilePosition(int x, int y){
paint = new TexturePaint(image, new Rectangle(Gscale.setX(x), Gscale.setY(y), Gscale.setWidth(image.getWidth()), Gscale.setHeight(image.getHeight())));
}
public TexturePaint animatedPaint(){
return paint;
}
#Override
public void actionPerformed(ActionEvent e) {
behavior.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null));
//host.repaint(0,0, host.getWidth(), host.getHeight());
}
}
Researched Link
Java2D Performance Issues
Note : The Graphic2D parameter is taking on the graphics of the JPanel itself. So shouldn't java already create a Compatible image for me?

Implementing Slow-motion with LibGDX

I am having trouble implementing smooth slow-motion rendering in LibGDX with the Artemis framework. I understand how to change "delta" in order for this to work (using this), but I'm unable to figure out how to actually implement it in the Screen interface's render method. How can I change the delta parameter of the Screen's render method to essentially slow down time?
My Screen Class:
public class GameScreen implements Screen {
private SpriteRenderSystem spriteRenderSystem;
private OrthographicCamera camera;
private Game game;
private World world;
private Random r = new Random();
public GameScreen(Game game){
camera = new OrthographicCamera();
camera.setToOrtho(false, 640, 480);
this.game = game;
world = new World();
world.setManager(new GroupManager());
spriteRenderSystem = world.setSystem(new SpriteRenderSystem(camera), true);
world.setSystem(new VelocitySystem());
world.setSystem(new AccelerationSystem());
world.setSystem(new CollisionSystem());
world.setSystem(new ExpirationSystem());
world.initialize();
for(int i = 0; i < 40; i += 4){
EntityFactory.createBlock(world, i*16, 0, "tiles/water").addToWorld();
EntityFactory.createBlock(world, (i+1) * 16, 0, "tiles/grass").addToWorld();
EntityFactory.createBlock(world, (i+2) * 16, 0, "tiles/mud").addToWorld();
EntityFactory.createBlock(world, (i+3) * 16, 0, "tiles/sand").addToWorld();
}
for(Entity e : EntityFactory.createExplosion(world, 320, 240)){
e.addToWorld();
}
}
#Override
public void render(float delta) {
// NEED HELP HERE
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
world.setDelta(delta);
world.process();
spriteRenderSystem.process();
}
(...)
}
Note: I am using the LibGDX + Artemis demo SpriteRenderSystem for rendering entities.
Have a float:
public float speed = 0.5F; //half for example
And in your render method, just multiply your delta with it:
#Override
public void render(float delta) {
delta*=speed; //<---
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
world.setDelta(delta);
world.process();
spriteRenderSystem.process();
}

Categories