I'm trying to update the game's viewport when the game resizes, but when I start the game, I get a java.lang.NullPointerException:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.utils.viewport.Viewport.apply(Viewport.java:49)
at com.badlogic.gdx.utils.viewport.ExtendViewport.update(ExtendViewport.java:90)
at com.badlogic.gdx.utils.viewport.Viewport.update(Viewport.java:57)
at me.chrisjosten.testgame.screens.MainScreen.resize(MainScreen.java:82)
at com.badlogic.gdx.Game.setScreen(Game.java:62)
at me.chrisjosten.testgame.create(MainScreen.java:13)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:136)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
In the class, that implements Screen, I have in the resize method, the place where the exception occurs, the following code:
#Override
public void resize(int w, int h) {
viewport.update(w, h);
}
where the viewport is an ExtendViewport created in the constructor of the class. I've tried putting that in the show method to, but then I get the same result.
The full code of the class:
package me.chrisjosten.testgame.screens;
import me.chrisjosten.testgame.MyGame;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.badlogic.gdx.utils.viewport.FillViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
public class MainScreen implements Screen{
private MyGame game;
private BitmapFont font;
private SpriteBatch batch;
private OrthographicCamera camera;
private Viewport viewport;
private boolean goingUp = false;
private float alpha = 1;
private int gameWidth = 100;
private int gameHeight = 100;
private int screenWidth;
private int screenHeight;
public MainScreen(MyGame g) {
game = g;
System.out.println("screen created");
}
#Override
public void show() {
System.out.println("show");
font = new BitmapFont(Gdx.files.internal("fonts/monospace.fnt"));
font.setColor(1, 1, 1, 1);
batch = new SpriteBatch();
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.translate(gameWidth / 2, gameHeight / 2);
viewport = new ExtendViewport(gameWidth, gameHeight, camera);
}
#Override
public void render(float delta) {
camera.update();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (goingUp) {
font.setColor(1, 1, 1, alpha);
alpha += 0.025;
} else {
font.setColor(1, 1, 1, alpha);
alpha -= 0.025;
}
if (alpha <= 0) {
goingUp = true;
alpha = 0;
} else if (alpha >= 1) {
goingUp = false;
alpha = 1;
}
batch.setProjectionMatrix(camera.combined);
batch.begin();
String press = "Press start";
font.draw(batch, press, gameWidth / 2 - font.getBounds(press).width / 2, 1);
batch.end();
}
#Override
public void resize(int w, int h) {
viewport.update(w, h);
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
font.dispose();
}
}
Does anyone know what I have done wrong?
By moving the code from the show method to the constructor, it works.
Related
So I am programming a game, and implemented preferences to save/load some simple data for sound/high score, nothing too much. The problem is that when I load preferences for the first time on a physical phone (samsung g. s3) it takes about 15sec and on s5 it takes about 5-8secs and in that time it shows black screen even though I have set the loading screen to be shown first, before preferences are used.
In my main application code I set screen to loadingScreen
loadingScreen = new com.package.game.Screens.LoadingScreen(this);
mainScreen = new com.package.game.Screens.MainScreen(this);
gameScreen = new com.package.game.Screens.GameScreen(this);
settingsScreen = new com.package.game.Screens.SettingsScreen(this);
this.setScreen(loadingScreen);
and then in my loading screen I access preferences:
#Override
public void show() {
this.progress_assets = 0f;
this.progress_assets = 0f;
font_loading = app.initFont(50, 1, 255, 255, 255, 1);
queueAssets();
loading_db();
}
private void loading_db() {
if(database.get_first_time()){
//do some introduction for first time run
Gdx.app.log("db","first time worked");
database.set_first_time();
progress_db=1f;
}else{
Gdx.app.log("db","first time is set false");
progress_db=1f;
}
}
and my preferences class:
package com.package.game.Engine;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.package.game.Application;
public class Database {
private Preferences preferences;
//database
private Preferences pref_settings;
private Preferences pref_score;
private Preferences pref_unlocks;
public Database(){
pref_settings = Gdx.app.getPreferences("com.package.game.settings");
pref_score = Gdx.app.getPreferences("com.package.game.score");
pref_unlocks = Gdx.app.getPreferences("com.package.game.unlocks");
}
//checking if first time run
public boolean get_first_time(){
return pref_settings.getBoolean("First_run",true);
}
public void set_first_time(){
pref_settings.putBoolean("First_run",false);
for(int i=0;i<7;i++){
pref_unlocks.putBoolean("unlock_"+i,true);
}
pref_unlocks.flush();
pref_settings.flush();
}
//settings
public boolean getSound(){
return pref_settings.getBoolean("sound_on",true);
}
public void setSound(boolean sound){
pref_settings.putBoolean("sound_on",sound);
pref_settings.flush();
}
//High Score Mode:
//Classic
public int getScore_classic(int place){
return pref_score.getInteger("score_classic_"+place,0);//default value 0 so we could place new score if we havent reached it
}
public void setScore_classic(int place,int scored){
pref_score.putInteger("score_classic_"+place,scored);
pref_score.flush();
}
//Recipe
public int getScoreRec(int place){
return pref_score.getInteger("score_recipe_"+place,0);//default value 0 so we could place new score if we havent reached it
}
public void setScoreRec(int place,int scored){
pref_score.putInteger("score_recipe_"+place,scored);
pref_score.flush();
}
//food unlocks
public boolean getFoodUnlock(int unlockID){
return pref_unlocks.getBoolean("unlock_"+unlockID,false);
}
public void setFoodUnlock(int unlockID,boolean state){
pref_unlocks.putBoolean("unlock_"+unlockID,state);
pref_unlocks.flush();
}
}
I'm not sure if creating 3 pref. files is good, but i would like to know how to show screen before pref. file being created/loaded.
Edit: Adding my main code
package com.mindutis.game;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.mindutis.game.Screens.LoadingScreen;
public class Application extends Game {
public static int V_WIDTH ;
public static int V_HEIGHT;
public OrthographicCamera camera;
public SpriteBatch batch;
public AssetManager assets;
public com.mindutis.game.Screens.LoadingScreen loadingScreen;
public com.mindutis.game.Screens.SplashScreen splashScreen;
public com.mindutis.game.Screens.MainScreen mainScreen;
public com.mindutis.game.Screens.GameScreen gameScreen;
public com.mindutis.game.Screens.SettingsScreen settingsScreen;
public BitmapFont f_game_name;
public String t_game_name;
public String[] font_type = new String[2];
private boolean firstFrame = true;
private boolean loading = true;
#Override
public void create() {
assets = new AssetManager();
camera = new OrthographicCamera();
V_WIDTH= Gdx.graphics.getWidth();
V_HEIGHT = Gdx.graphics.getHeight();
camera.setToOrtho(false, V_WIDTH, V_HEIGHT);
batch = new SpriteBatch();
//Global var.
//font initializer
font_type[0] = "fonts/comics_bold.ttf";
font_type[1] = "fonts/vdj.ttf";
//game name
t_game_name = " Catch a\nSandwich";
f_game_name = initFont(70, 0, 255, 255, 255, 1);
loadingScreen = new com.mindutis.game.Screens.LoadingScreen(this);
splashScreen = new com.mindutis.game.Screens.SplashScreen(this);
mainScreen = new com.mindutis.game.Screens.MainScreen(this);
gameScreen = new com.mindutis.game.Screens.GameScreen(this);
settingsScreen = new com.mindutis.game.Screens.SettingsScreen(this);
// this.setScreen(loadingScreen);
}
//int size=font size, int x = font type
public BitmapFont initFont(int size, int type, float red, float green, float blue, float alpha) {
BitmapFont font;
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal(font_type[type]));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.size = size;
font = generator.generateFont(parameter);
font.setColor(red / 255f, green / 255f, blue / 255f, alpha);
return font;
}
#Override
public void render() {
if (firstFrame){
Gdx.gl.glClearColor(.2f, .67f, .88f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
f_game_name.draw(batch, t_game_name, camera.viewportWidth / 2 - 150, camera.viewportHeight - 100);
batch.end();
firstFrame = false;
} else {
if(loading){
loading=false;
loadEverything();
}
// Notice you don't actually render anything so what you previously drew stays on the screen.
}
super.render();
}
private void loadEverything(){
// load your font, assets, prefs, etc.
this.setScreen(loadingScreen);
// setScreen(loadingScreen);
}
#Override
public void dispose() {
batch.dispose();
assets.dispose();
f_game_name.dispose();
loadingScreen.dispose();
splashScreen.dispose();
mainScreen.dispose();
gameScreen.dispose();
settingsScreen.dispose();
}
}
Loading screen class:
package com.mindutis.game.Screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.mindutis.game.Application;
import com.mindutis.game.Engine.Database;
public class LoadingScreen implements Screen {
private final Application app;
private Database database;
private BitmapFont font_loading;
private boolean load;
private ShapeRenderer shapeRenderer;
private Stage stage;
private String t_loading;
private float progress_assets,progress_db;
private boolean firstFrame = true;
private boolean loading = true;
public LoadingScreen(Application app) {
this.app = app;
database = new Database();
this.stage = new Stage(new FitViewport(com.mindutis.game.Application.V_WIDTH, com.mindutis.game.Application.V_HEIGHT, app.camera));
this.shapeRenderer = new ShapeRenderer();
t_loading = "Loading...";
load=false;
}
private void queueAssets() {
//good food
//bread
app.assets.load("img/Food/breadtop.png", Texture.class);
app.assets.load("img/Food/breadbot.png", Texture.class);
//rest of the food
app.assets.load("img/Food/food_sheet.png", Texture.class);
//misc
app.assets.load("img/Misc/coin.png", Texture.class);
app.assets.load("img/Misc/soon.png", Texture.class);
app.assets.load("img/Misc/shoptriangle.png", Texture.class);
//buttons
app.assets.load("img/Buttons/button.png", Texture.class);
app.assets.load("img/Buttons/soundBT.png", Texture.class);
app.assets.load("img/Buttons/btX.png", Texture.class);
app.assets.load("img/Buttons/btShop1.png", Texture.class);
//human
app.assets.load("img/Human/human.png", Texture.class);
app.assets.load("img/Human/human1.png", Texture.class);
app.assets.load("img/Human/human2.png", Texture.class);
}
#Override
public void show() {
this.progress_assets = 0f;
this.progress_assets = 0f;
font_loading = app.initFont(50, 1, 255, 255, 255, 1);
queueAssets();
loading_db();
}
private void loading_db() {
if(database.get_first_time()){
//do some introduction for first time run
Gdx.app.log("db","first time worked");
database.set_first_time();
progress_db=1f;
}else{
Gdx.app.log("db","first time is set false");
progress_db=1f;
}
}
#Override
public void render(float delta) {
if (firstFrame){
Gdx.gl.glClearColor(.2f, .67f, .88f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
app.batch.begin();
app.f_game_name.draw(app.batch, app.t_game_name, app.camera.viewportWidth / 2 - 150, app.camera.viewportHeight - 100);
app.batch.end();
firstFrame = false;
} else {
if(loading){
loading=false;}
//input
Gdx.input.setCatchBackKey(true);
Gdx.input.setInputProcessor(new InputAdapter() {
#Override
public boolean keyDown(int keycode) {
if (keycode == Input.Keys.BACK) {
// Do nothing
}
return false;
}
});
Gdx.gl.glClearColor(.2f, .67f, .88f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
update(delta);
app.batch.begin();
font_loading.draw(app.batch, t_loading, app.camera.viewportWidth / 2 - 150, 123);
app.f_game_name.draw(app.batch, app.t_game_name, app.camera.viewportWidth / 2 - 150, app.camera.viewportHeight - 100);
app.batch.end();
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.rect(32, 50, app.camera.viewportWidth - 64, 16);
shapeRenderer.setColor(Color.GREEN);
shapeRenderer.rect(32, 50, (progress_assets+progress_db)/2 * (app.camera.viewportWidth - 64), 16);
shapeRenderer.end();
}
// Notice you don't actually render anything so what you previously drew stays on the screen.
}
private void update(float delta) {
progress_assets = MathUtils.lerp(progress_assets, app.assets.getProgress(), .1f);
if (app.assets.update() && (progress_assets+progress_db)/2 >= app.assets.getProgress() - .01f) {
app.setScreen(app.mainScreen);
}
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, false);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
shapeRenderer.dispose();
font_loading.dispose();
stage.dispose();
}
}
You can quickly load a single texture to show while everything else loads. Load and show the texture the first time render() is called. Then the second time render() is called, load your stuff, dispose the texture, and switch screens.
public class LoadingScreen extends Screen {
private boolean firstFrame = true;
private Texture texture;
private ExtendViewport viewport;
private MyGame game;
private SpriteBatch batch;
private static final float LOAD_IMAGE_WIDTH = 480, LOAD_IMAGE_HEIGHT = 600;
// Use whatever the loading image dimensions are.
public LoadingScreen (MyGame game, SpriteBatch batch){
this.game = game;
this.batch = batch;
viewport = new ExtendViewport(LOAD_IMAGE_WIDTH, LOAD_IMAGE_HEIGHT);
}
public void resize (int width, int height) {
viewport.update(width, height, false);
viewport.getCamera().position.set(LOAD_IMAGE_WIDTH / 2, LOAD_IMAGE_HEIGHT / 2, 0);
viewport.getCamera().update();
}
public void show (){} // do nothing
public void render (float delta) {
if (firstFrame){
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
viewport.apply();
batch.setProjectionMatrix(viewport.getCamera().combined);
batch.setBlendingDisabled(true);
batch.begin();
batch.draw(texture, 0, 0, LOAD_IMAGE_WIDTH, LOAD_IMAGE_HEIGHT);
batch.end();
firstFrame = false;
} else {
loadEverything();
// Notice you don't actually render anything so what you previously drew stays on the screen.
}
}
private void loadEverything(){
// load your font, assets, prefs, etc.
texture.dispose();
main.setGameScreen();
}
}
I have very simple question. But i couldnt solve. I just want to draw a texture on the tilemap. With theese codes i can see the map and move, but i cant see texture.
Here is the screen:
package com.adsiz.areyoualive.screen;
import com.adsiz.areyoualive.game.Player;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
public class PlayScreen implements Screen, InputProcessor{
public ScreenManager screenManager;
public static float speed = 32;
//tilemap & camera
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer renderer;
//player
Player player;
//spritebatch
SpriteBatch spriteBatch;
public PlayScreen(){
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, w, h);
camera.update();
tiledMap = new TmxMapLoader().load("map/untitled.tmx");
renderer = new OrthogonalTiledMapRenderer(tiledMap);
spriteBatch = new SpriteBatch();
camera.position.set(0, 3200, 0);
Gdx.input.setInputProcessor(this);
player = new Player(0, 3200);
spriteBatch.setTransformMatrix(camera.combined);
}
#Override
public void render(float delta) {
Gdx.graphics.getGL20().glClearColor( 1, 1, 1, 1 );
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.graphics.getGL20().glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
camera.update();
renderer.setView(camera);
renderer.render();
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
player.draw(spriteBatch);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void show() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public boolean keyDown(int keycode) {
switch (keycode) {
case Keys.DOWN:
camera.translate(0, -1*speed);
player.moveDown();
break;
case Keys.UP:
camera.translate(0, speed);
player.moveUp();
break;
case Keys.LEFT:
camera.translate(-1*speed, 0);
player.moveLeft();
break;
case Keys.RIGHT:
camera.translate(speed, 0);
player.moveRight();
break;
}
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}
and here is my player.draw function:
public void draw(SpriteBatch batch){
batch.draw(playerTexture, getPosX(), getPosY(), playerTexture.getWidth(), playerTexture.getHeight());
}
i just want to show a simple texture and move it on the screen. What is wrong above there? May you help me?
Regards Guys!
I solved my own problem, I just changed map renderer to OrthogonalTileMapRenderer, and changed SpriteBatch's with Batch of OrthogonalTileMapRenderer.
package com.adsiz.areyoualive.screen;
import com.adsiz.areyoualive.game.Player;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
public class PlayScreen implements Screen, InputProcessor{
public ScreenManager screenManager;
public static float speed = 32;
//tilemap & camera
TiledMap tiledMap;
OrthographicCamera camera;
OrthogonalTiledMapRenderer renderer;
//player
Player player;
public PlayScreen(){
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, w, h);
camera.update();
tiledMap = new TmxMapLoader().load("map/untitled.tmx");
renderer = new OrthogonalTiledMapRenderer(tiledMap);
camera.position.set(0, 3200, 0);
Gdx.input.setInputProcessor(this);
player = new Player(0, 3200);
}
#Override
public void render(float delta) {
Gdx.graphics.getGL20().glClearColor( 1, 1, 1, 1 );
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.graphics.getGL20().glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
camera.update();
renderer.setView(camera);
renderer.render();
renderer.getSpriteBatch().begin();
player.draw(renderer.getSpriteBatch());
renderer.getSpriteBatch().end();
}
EDIT:
Following Per's answer: I added this and it works fine :
private class GameScreen implements Screen {
private Stage mStage;
private InputMultiplexer inputMultiplexer = new InputMultiplexer();
public GameScreen() {
Gdx.input.setInputProcessor(inputMultiplexer);
mStage = new Stage(0, 0, true);
MyInput mi = new MyInput(){ //which implements inputProcessor
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
General.Log("gamescreen touchDown");
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
};
inputMultiplexer.addProcessor(mi);
inputMultiplexer.addProcessor(mStage);
}
I would like to detect a click on a ui actor, I registered stage as the inputProcessor
Gdx.input.setInputProcessor(stage);
And I added this to my actor:
setBounds(0, 0, texture.getWidth(), texture.getHeight());
But still no response...
It is hard to help you without getting more info on your setup. But this code snippet works fine for me, look and see what you do different. And if you cant get it right create a small project with just the code that fails, easier for us to help you then.
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
public class MyGame extends Game {
#Override
public void create() {
setScreen(new GameScreen());
}
private class GameScreen implements Screen {
private Stage mStage;
public GameScreen() {
mStage = new Stage(0, 0, true);
}
#Override
public void render(float delta) {
mStage.act(delta);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mStage.draw();
}
#Override
public void resize(int width, int height) {
Gdx.gl.glViewport(0, 0, width, height);
mStage.setViewport(width, height);
}
#Override
public void show() {
Texture texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 40, 40);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
Image imageActor = new Image(region);
imageActor.setPosition(x * 50, y * 50);
imageActor.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
System.out.println("clicked");
}
});
mStage.addActor(imageActor);
}
}
Gdx.input.setInputProcessor(mStage);
}
#Override
public void hide() {}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void dispose() {}
}
}
With the ApplicationListener:
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
public class MyGame implements ApplicationListener {
private Stage mStage;
#Override
public void create() {
mStage = new Stage(0, 0, true);
Texture texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 40, 40);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
Image imageActor = new Image(region);
imageActor.setPosition(x * 50, y * 50);
imageActor.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
System.out.println("clicked");
}
});
mStage.addActor(imageActor);
}
}
Gdx.input.setInputProcessor(mStage);
}
#Override
public void resize(int width, int height) {
Gdx.gl.glViewport(0, 0, width, height);
mStage.setViewport(width, height);
}
#Override
public void render() {
mStage.act(Gdx.graphics.getDeltaTime());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mStage.draw();
}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void dispose() {}
}
This code makes image Border flicker(Flash) while moving left,right,down or up. Why image border flash wile moving even if I use Screen class render() method delta value.
package com.me.mygdxgame;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector3;
public class MoveSpriteExample extends GdxTest implements InputProcessor {
Texture texture;
SpriteBatch batch;
OrthographicCamera camera;
Vector3 spritePosition = new Vector3();
Sprite sprite;
public void resize (int width, int height) {
}
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
batch = new SpriteBatch();
camera= new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(false, w, h);
texture = new Texture(Gdx.files.internal("data/grasswall.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
sprite = new Sprite(texture);
sprite.setSize(32, 32);
spritePosition.y=100;
sprite.setPosition(spritePosition.x,spritePosition.x);
lastUpdateTime = System.nanoTime();
}
public void Update(float Delta)
{
if (Gdx.input.isKeyPressed(Keys.D)==true)
{
spritePosition.x += 150*(Delta / 1000000000.0);
}else if (Gdx.input.isKeyPressed( Keys.A)==true)
{
spritePosition.x -= 150*(Delta / 1000000000.0);
}
else if (Gdx.input.isKeyPressed( Keys.Z)==true)
{
spritePosition.y -= 150*(Delta / 1000000000.0);
}
else if (Gdx.input.isKeyPressed( Keys.W)==true)
{
spritePosition.y += 150*(Delta / 1000000000.0);
}
}
float lastUpdateTime;
float currentTime;
public void render() {
currentTime = System.nanoTime();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
Update(currentTime - lastUpdateTime);
sprite.setPosition(spritePosition.x,spritePosition.y);
batch.setProjectionMatrix(camera.combined);
batch.begin();
sprite.draw(batch);
batch.end();
lastUpdateTime = currentTime;
}
}
pls provide code with sample
As i said in the last post of you, you should take a look at the Tutorial!
First of all you do not need to calculate the delta time yourself. I already postet how you get it in the last post for you.
Ill give you a super short example with a moving sprite without flickering.
At first here is the ApplicationListener. (not a GDXtest)
public class MainClass implements ApplicationListener {
private Screen currentScreen = null;
#Override
public void create() {
Texture.setEnforcePotImages(false);
this.currentScreen = new TestScreen();
}
#Override
public void dispose() {
this.currentScreen.dispose();
}
#Override
public void render() {
this.currentScreen.render(Gdx.graphics.getDeltaTime());
}
#Override
public void resize(int width, int height) {
this.currentScreen.resize(width, height);
}
#Override
public void pause() {
this.currentScreen.pause();
}
#Override
public void resume() {
this.currentScreen.resume();
;
}
}
It's preaty simple and as you can see it does call the render of the screen automatically with the delta time! this.currentScreen.render(Gdx.graphics.getDeltaTime()).
The next thing you need is a simple Screen. So something that does implement the Screeninterface. Id really recommand that you use a Scene2D setup with a stage. But here is an example without.
public class TestScreen implements Screen {
private Sprite mySprite;
private SpriteBatch batch = new SpriteBatch();
public TestScreen() {
this.mySprite = new Sprite(new Texture(
Gdx.files.internal("data/appicon.png")));
this.mySprite.setPosition(50f, 50f);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
this.update(delta);
this.batch.begin();
this.mySprite.draw(batch);
this.batch.end();
}
public void update(float delta) {
if (Gdx.input.isKeyPressed(Keys.D) == true) {
mySprite.setX(mySprite.getX() + 150 * delta);
} else if (Gdx.input.isKeyPressed(Keys.A) == true) {
mySprite.setX(mySprite.getX() - 150 * delta);
} else if (Gdx.input.isKeyPressed(Keys.Z) == true) {
mySprite.setY(mySprite.getY() - 150 * delta);
} else if (Gdx.input.isKeyPressed(Keys.W) == true) {
mySprite.setY(mySprite.getY() + 150 * delta);
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
Regardas and do take a look at the tutorial. (Here is again the beginning of it)
Started making a game.
Here's some of my code.
package games.tribe.screens;
import games.tribe.model.World;
import games.tribe.view.WorldRenderer;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
public class GameScreen implements Screen {
private World world;
private WorldRenderer renderer;
/** This was the bit I'd missed --------------------------------------**/
#Override
public void show() {
world = new World();
renderer = new WorldRenderer(world);
}
/**------------------------------------------------------------------**/
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
renderer.render();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
}
here's the WorldRenderer Class:
package games.tribe.view;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import games.tribe.model.Block;
import games.tribe.model.TribalHunter;
import games.tribe.model.World;
public class WorldRenderer {
private World world;
private OrthographicCamera cam;
/**for debug rendering**/
ShapeRenderer debugRenderer = new ShapeRenderer();
public WorldRenderer(World world) {
this.world = world;
this.cam = new OrthographicCamera(10, 7);
this.cam.position.set(5, 3.5f, 0);
this.cam.update();
}
public void render() {
//render blocks
debugRenderer.setProjectionMatrix(cam.combined);
debugRenderer.begin(ShapeType.Rectangle);
for(Block block : world.getBlocks()) {
Rectangle rect = block.getBounds();
float x1 = block.getPosition().x + rect.x;
float y1 = block.getPosition().y + rect.y;
debugRenderer.setColor(new Color(1, 0, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
}
//render hunter
TribalHunter hunter = world.getHunter();
Rectangle rect = hunter.getBounds();
float x1 = hunter.getPosition().x + rect.x;
float y1 = hunter.getPosition().y + rect.y;
debugRenderer.setColor(new Color(0, 1, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
debugRenderer.end();
}
}
This is the exception I'm getting when I run it as a desktop application:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at games.tribe.screens.GameScreen.render(GameScreen.java:19)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:202)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:131)
AL lib: ReleaseALC: 1 device not closed
Line 46 of gdx.Game.render is this method:
#Override
public void render () {
if (screen != null) screen.render(Gdx.graphics.getDeltaTime());
}
Any help will be appreciated
Thanks in advance
In the GameScreen's render() method, has the renderer been initialized? That could be causing the problem if it hasn't.
Edit: The problem you're having, according to the top two lines of the error, is a NullPointerException on line 19 of the class GameScreen. The NullPointerException only occurs when an object is used for some action when the object itself is null because it likely hasn't been initialized.
Line 19 of the GameScreen is:
renderer.render();
...but the object renderer has not been initialized anywhere, so it is currently null which is the default. To avoid getting this error, you'll need to initialize the renderer object before you run that line of code. Perhaps with something like this:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
renderer = new WorldRenderer();
renderer.render();
}
I am not familiar with libgdx, so I can't be sure that's exactly how a WorldRenderer is initialized, but you need to do something of the sort. I hope this helps.