I'm making a simple game in LibGDX. I want to use the Sprite classes methods for my main player, while using the Animation class in order to animate the player as well. I've gotten Animation to work, I just haven't been able to integrate it with the Sprite class.
Here is my code:
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
public class Game extends ApplicationAdapter {
SpriteBatch batch;
private TextureAtlas runAtlas;
private Animation runAnimation;
private TextureAtlas idleAtlas;
private Animation idleAnimation;
private TextureRegion currentIdleFrame;
private Sprite player;
private float elapsedTime = 0;
private float playerX = 10;
private float playerY = 10;
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public void create () {
batch = new SpriteBatch();
runAtlas = new TextureAtlas(Gdx.files.internal("runSpritesheet.atlas"));
runAnimation = new Animation(1/12f, runAtlas.getRegions());
idleAtlas = new TextureAtlas(Gdx.files.internal("idleSpritesheet.atlas"));
idleAnimation = new Animation(1/3f, idleAtlas.getRegions());
player = new Sprite();
}
#Override
public void render () {
currentIdleFrame = (TextureRegion) idleAnimation.getKeyFrame(elapsedTime, true);
elapsedTime += Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
if(Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)) {
batch.draw((TextureRegion) runAnimation.getKeyFrame(elapsedTime, true), playerX, playerY);
} else if (Gdx.input.isKeyPressed(Keys.DPAD_LEFT)) {
batch.draw((TextureRegion) runAnimation.getKeyFrame(elapsedTime, true), playerX, playerY);
} else {
player.setRegion(currentIdleFrame);
player.draw(batch);
}
batch.end();
}
#Override
public void dispose () {
batch.dispose();
runAtlas.dispose();
idleAtlas.dispose();
}
}
The focus is on the idle animation of the player in the "else" statement. I try setting the player sprite region to the current key frame of the idle animation sprite sheet. However, when I launch the game, no sprite with the idle animation comes up. I don't get any errors either. I am hoping someone knows how to fix this problem. Thanks for reading.
Related
For the game I'm making I use Tiled to make and edit maps. However, these maps don't load in the sample I've made so far:
package com.bluezamx.magillion.screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.objects.RectangleMapObject;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.FillViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.bluezamx.magillion.Magillion;
import com.bluezamx.magillion.utils.Constants;
public class WorldScreen implements Screen {
private Magillion game;
private OrthographicCamera gameCam;
private Viewport gamePort;
private Stage stage;
//Tiled variables
private TmxMapLoader mapLoader;
private TiledMap map;
private OrthogonalTiledMapRenderer maprenderer;
// Box2D variables
private World world;
private Box2DDebugRenderer debug;
public WorldScreen (Magillion game) {
this.game = game;
gameCam = new OrthographicCamera();
mapLoader = new TmxMapLoader();
map = mapLoader.load("TestWorld.tmx");
maprenderer = new OrthogonalTiledMapRenderer(map, 1 / Constants.PPM);
gamePort = new FillViewport(Constants.WIDTH / Constants.PPM, Constants.HEIGHT / Constants.PPM, gameCam);
gameCam.position.set((gamePort.getWorldWidth() / 2), (gamePort.getWorldHeight() / 2), 0);
world = new World(new Vector2(0,0), true);
debug = new Box2DDebugRenderer();
debug.SHAPE_STATIC.set(1, 0, 0, 1);
for(MapObject object : map.getLayers().get(1).getObjects().getByType(RectangleMapObject.class)) {
Rectangle rect = ((RectangleMapObject) object).getRectangle();
bdef.type = BodyDef.BodyType.StaticBody;
bdef.position.set(rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
body = world.createBody(bdef);
shape.setAsBox(rect.getWidth() / 2, rect.getHeight() / 2);
fdef.shape = shape;
body.createFixture(fdef);
}
}
#Override
public void show() {}
private void update(float dt) {
handleInput(dt);
world.step(1/60f, 6, 2);
player.update(dt);
gameCam.update();
maprenderer.setView(gameCam);
}
#Override
public void render(float dt) {
update(dt);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debug.render(world, gameCam.combined);
game.batch.setProjectionMatrix(gameCam.combined);
maprenderer.render();
game.batch.begin();
player.draw(game.batch);
game.batch.end();
}
#Override
public void resize(int width, int height) {}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void hide() {}
#Override
public void dispose() {
map.dispose();
maprenderer.dispose();
world.dispose();
debug.dispose();
}
}
When I run my file (which automatically sets the game screen to this file), I only get a black screen. The map itself doesn't show. The map is 640 * 480 big and placed in the standard android/assets folder.
I tried running my map in other code I found online and it worked there. I couldn't figure out what's wrong with mine, however.
You need to update your viewport with device screen width and height.
#Override
public void resize(int width, int height) {
// use true here to center the camera
gamePort.update(width,height,false);
}
Take a look of this answer, recently I added as solution.
It seems like your map is actually rendered, but simply your Viewport is out of map position.
Try using:
gamecam.setToOrtho(false, gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2);
instead of
gameCam.position.set((gamePort.getWorldWidth() / 2), (gamePort.getWorldHeight() / 2), 0);
I have a couple of sprites that follow a certain path in a TileMap and I base the sprite's movement off of DeltaTime. Since DeltaTime varies, it causes some of the sprites to overlap/past other sprites. Note that the sprite must go down one cell in the TileMap and in the opposite direction if it hits a certain tile. Here's the code for the sprite movement:
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.math.Vector2;
public class CentipedeBody1 extends Sprite {
enum State{
LEFT,RIGHT,DOWN
}
State currentState,previousState ;
public static final float DOWN_MOVEMENT=7f;
public float downMovCounter;
public float speed;
public float stateTime;
TextureRegion image;
Vector2 position,size;
Animation<TextureRegion> animation;
TextureRegion currentFrame;
TextureRegion[]frames;
Texture tilesImage = new Texture(Gdx.files.internal("tile.png"));
TextureRegion[][] splitTiles = TextureRegion.split(tilesImage, 8, 8);
public CentipedeBody1(TextureRegion image, Vector2 position, Vector2 size) {
super(new TextureRegion(image));
setPosition(position.x,position.y);
setSize(size.x,size.y);
currentState=State.LEFT;
previousState=State.LEFT;
speed=8f;
}
public void update(TiledMap map) {
float delta=Gdx.graphics.getDeltaTime();
if(currentState ==State.LEFT){
setPosition(getX()-speed*delta,getY());
if(getX()<0) {
previousState=currentState;
currentState = State.DOWN;
setFlip(true,false);
}
}
if(currentState ==State.RIGHT){
setPosition(getX()+speed*delta,getY());
if(getX()> 19) {
previousState=currentState;
currentState = State.DOWN;
setFlip(false,false);
}
}
if(currentState ==State.DOWN){
setPosition(getX(),getY()-1);
downMovCounter=0;
currentState =previousState==State.LEFT?
State.RIGHT:State.LEFT;
}
TiledMapTileLayer cur = (TiledMapTileLayer) map.getLayers().get(2);
TiledMapTileLayer.Cell cell = new TiledMapTileLayer.Cell();
if(cur.getCell(Math.round(getX()),Math.round(getY())).getTile().getProperties().containsKey("mushroom"))
{
if(getCurrentState()==State.LEFT)
{
setFlip(true,false);
}
else if(getCurrentState()==State.RIGHT)
{
setFlip(false,false);
}
previousState=currentState;
currentState = State.DOWN;
}
}
I am currently working with libGDX and got to a strange problem.
The textures that I use with batch and rectangles are stretched. Here is a picture.
As you can see, the background looks completely normal, but the person in the middle is a lot taller than the person in the left corner, which it should look like.
Here is my code:
import java.util.Iterator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.utils.Array;
import com.data.Manager;
public class GameScreen implements Screen{
private Texture backgroundTexture = Manager.manager.get(("Ressources/Hintergrund_Skizze.png"), Texture.class);
private Texture farmerBackTexture = Manager.manager.get(("Ressources/Farmer_Back_Skizze.png"), Texture.class);
private Texture farmerRightTexture = Manager.manager.get(("Ressources/Farmer_Right_Skizze.png"), Texture.class);
private Texture farmerLeftTexture = Manager.manager.get(("Ressources/Farmer_Left_Skizze.png"), Texture.class);
private Texture ufoTexture = Manager.manager.get(("Ressources/Ufo_Skizze.png"), Texture.class);
private Texture laserTexture = Manager.manager.get(("Ressources/Magic_Ball.png"), Texture.class);
private Image backgroundImage = new Image(backgroundTexture);
private Image farmerBackImage = new Image(farmerBackTexture);
private Stage levelStage = new Stage(), menuStage = new Stage();
private Table menuTable = new Table();
private Skin menuSkin = Manager.menuSkin;
private OrthographicCamera camera;
private SpriteBatch batch;
private Rectangle farmer, ufo;
private Array<Rectangle> lasers;
private boolean ufoMovementLeft = true;
private boolean leftArrow = false;
private boolean rightArrow = false;
private float laserMovement = 0;
private int ufoLife = 15;
#Override
public void show() {
levelStage.addActor(backgroundImage);
levelStage.addActor(farmerBackImage);
Gdx.input.setInputProcessor(levelStage);
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
farmer = new Rectangle();
farmer.x = 800 / 2 - 80 / 2; farmer.y = 80;
farmer.width = 80; farmer.height = 270;
ufo = new Rectangle();
ufo.x = 800 / 2; ufo.y = 375;
ufo.width = 185; ufo.height = 94;
lasers = new Array<Rectangle>();
}
public void movement() {
if(Gdx.input.isKeyPressed(Keys.LEFT)) leftArrow = true;
if(!Gdx.input.isKeyPressed(Keys.LEFT)) leftArrow = false;
if(Gdx.input.isKeyPressed(Keys.RIGHT)) rightArrow = true;
if(!Gdx.input.isKeyPressed(Keys.RIGHT)) rightArrow = false;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
levelStage.act();
levelStage.draw();
batch.setProjectionMatrix(camera.combined);
batch.begin();
movement();
if(leftArrow) {if(farmer.x >= 60) farmer.x -= 2; batch.draw(farmerLeftTexture, farmer.x, farmer.y);}
else if(rightArrow) {if(farmer.x <= 590) farmer.x += 2; batch.draw(farmerRightTexture, farmer.x, farmer.y);}
else batch.draw(farmerBackTexture, farmer.x, farmer.y);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
levelStage.dispose(); menuStage.dispose();
menuSkin.dispose();
ufoTexture.dispose();
laserTexture.dispose();
farmerBackTexture.dispose();
farmerRightTexture.dispose();
farmerLeftTexture.dispose();
}}
I hope you are able to help me find the mistake.
Cheers,
Joshflux
EDIT: I am pretty sure, that it has to do something with the size of the window. If I resize the height of the window from 800 to 200, the person in the left corner looks the same, but the person in the middle is way smaller. Still can't figure out how to solve it though...
The problem is that your levelStage uses a different camera.
new Stage();
Creates a stage with its own camera and a scaling viewport. And here you create another camera:
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
Note that this does NOT set the window size!
With a static size, as you never update it when you resize the window.
Since you use a stage for your level you could do this:
batch.setProjectionMatrix(levelStage.getCamera().combined);
If you don't want a scaling viewport create your own (take a look a the different viewports) and add it as an parameter to new Stage(viewport).
To set the window size you need to go to the desktop project and change it in the config class.
That happens because you are adding an actor to a scene and just drawing an texture after. you could use some information about differences of actors and texture drawing here:
libgdx difference between sprite and actor
When to use actors in libgdx? What are cons and pros?
Im trying to make a simple game in LibGdx, using Tiled MapEditor and I have a little problem with rendering, left and bottom borders flickers whenever i move a camera.
Pic Related: https://gyazo.com/63b9e364cd4b2e8154c1bd177c9ee990
MyGdxGame.java
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
AssetLoad load;
Player player;
TiledMapRenderer tiledMapRenderer;
TiledMap tiledMap;
float unitScale = 1 / 32f;
#Override
public void create () {
load = new AssetLoad();
load.manager.finishLoading();
if(load.manager.update()){
batch = new SpriteBatch();
player = new Player();
tiledMap = new TmxMapLoader().load("tilemaps/321.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap,unitScale);
batch.setProjectionMatrix(player.cam.combined);
}
}
#Override
public void render () {
update();
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
tiledMapRenderer.setView(player.cam);
tiledMapRenderer.render();
batch.end();
}
public void update(){
player.playerMove();
player.cam.update();
player.cam.position.set(player.x,player.y,0);
}
public void dispose(){
}
Player.java
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.OrthographicCamera;
public class Player {
public OrthographicCamera cam = new OrthographicCamera(1024,720);
int x = 10;
int y = 12;
public Player(){
cam.setToOrtho(false,30,20);
}
public void playerMove()
{
if(Gdx.input.isKeyPressed(Keys.W))
{
y += 1;
}
if(Gdx.input.isKeyPressed(Keys.A))
{
x -= 1;
}
if(Gdx.input.isKeyPressed(Keys.S))
{
y -= 1;
}
if(Gdx.input.isKeyPressed(Keys.D))
{
x += 1;
}
}
}
You update the cam before your set it's position rather than after, and the projection matrix is never updated. Hopefully these two things fix your problem.
public void update(){
player.playerMove();
player.cam.update();
player.cam.position.set(player.x,player.y,0);
}
should be
public void update(){
player.playerMove();
player.cam.position.set(player.x,player.y,0);
player.cam.update();
batch.setProjectionMatrix(player.cam.combined);
}
I am trying to create a Space Shooter game using LibGDX in Android Studio.
Everything else was working fine until I tried to create animation using javafx.animation.Animation class. While compiling my code, I get the following 3 errors and 1 warning !
Warning:[options] bootstrap class path not set in conjunction with -source 1.6
Error:(11, 24) error: package javafx.animation does not exist
Error:(22, 13) error: cannot find symbol class Animation
Error:(44, 26) error: cannot find symbol class Animation
I have checked that my android studio does have a plugin for javafx !
I have two classes in my code Shootergame.java and AnimatedSprite.java
The problem lies in AnimatedSprite.java class and the code for that class is below !
package com.ahmed.nullapointershooter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import javafx.animation.Animation;
/**
* Created by Hafeez ur Rehman on 8/30/2015.
**/
public class AnimatedSprite {
private static final int FRAMES_COL = 2;
private static final int FRAMES_ROW = 2;
private Sprite sprite;
private Animation animation;
private TextureRegion[] frames;
private TextureRegion currentFrame;
private float stateTime;
public AnimatedSprite(Sprite sprite) {
this.sprite = sprite;
Texture texture = sprite.getTexture();
TextureRegion[][] temp = TextureRegion.split(texture, texture.getWidth() / FRAMES_COL,
texture.getHeight() / FRAMES_ROW);
frames = new TextureRegion[FRAMES_COL * FRAMES_ROW];
int index = 0;
for (int i = 0; i < FRAMES_ROW; i++) {
for (int j = 0; j < FRAMES_COL; j++) {
frames[index++] = temp[i][j];
}
}
/**
* THE PROBLEM LIES HERE . I WANT TO DO THIS ----
*
*/
//animation = new Animation(0.1f, frames);
animation = new Animation() {
#Override
public void impl_playTo(long l, long l1) {
}
#Override
public void impl_jumpTo(long l, long l1) {
}
};
stateTime = 0f;
}
public void setPosition(float x, float y){
float widthOffset = sprite.getWidth() / FRAMES_COL;
sprite.setPosition(x - widthOffset / 2, y);
}
public void draw(SpriteBatch spriteBatch){
stateTime += Gdx.graphics.getDeltaTime();
//currentFrame = animation.getKeyFrame(stateTime, true);
spriteBatch.draw(currentFrame, sprite.getX(), sprite.getY());
}
}
and also code for Shootergame.java just for reference for what I am doing!
package com.ahmed.nullapointershooter;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class ShooterGame extends ApplicationAdapter {
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture background;
private AnimatedSprite spaceshipAnimated;
#Override
public void create() {
//Texture.setEnforcePotImages(false);
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
background = new Texture(Gdx.files.internal("NullapointerBackground.png"));
Texture spaceshipTexture = new Texture(Gdx.files.internal("Spaceshipcanvas.png"));
Sprite spaceshipSprite = new Sprite(spaceshipTexture);
spaceshipAnimated = new AnimatedSprite(spaceshipSprite);
spaceshipAnimated.setPosition(800 / 2, 0);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(background, 0, 0);
spaceshipAnimated.draw(batch);
batch.end();
}
#Override
public void resize(int width, int height) {
}
}
My problem solved . I was using Javafx to import animation class which was wrong at the first place because there is no javafx package in android. Instead I had to import
import com.badlogic.gdx.graphics.g2d.Animation; Now its working !