Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 (libGDX) - android

I get Fatal signal 11 on my Samsung Galaxy S6 Edge when I try to enter the playscreen. On the desktop emulator it works fine and I can enter the playscreen class. I also tested with a Nexus 6 and it worked even there. What's wrong with my phone?
When I try to debug the app crashes when I'm reading this line:
app.getApplicationListener().render();
PlayScreen class:
public class PlayScreen2 implements Screen {
private TextureAtlas atlas;
private OrthographicCamera gamecam;
private Viewport gamePort;
private Hud2 hud;
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private World world;
public Box2DDebugRenderer b2dr;
public static Runner player;
private float dt;
private boolean keyPressed = false;
private boolean keyPressed2 = false;
public PlayScreen2(){
atlas = new TextureAtlas("Runner_And_Enemies.pack");
gamecam = new OrthographicCamera();
gamePort = new FitViewport(RunningGame.V_WIDTH / RunningGame.PPM, RunningGame.V_HEIGHT / RunningGame.PPM, gamecam);
hud = new Hud2(Globals.game.batch);
maploader = new TmxMapLoader();
map = maploader.load("level2.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1 / RunningGame.PPM);
gamecam.position.set(gamePort.getWorldWidth() / 2, gamePort.getWorldHeight() / 2 , 0);
world = new World(new Vector2(0, -10), true);
b2dr = new Box2DDebugRenderer();
new B2WorldCreator(world, map);
player = new Runner(world, this);
}
public TextureAtlas getAtlas(){
return atlas;
}
#Override
public void show() {
}
public void handleInput(float dt){
if (Gdx.input.isKeyPressed(Input.Keys.ANY_KEY)) {
if (!keyPressed) {
keyPressed = true;
if (player.b2body.getLinearVelocity().x <= 4) {
player.b2body.applyLinearImpulse(new Vector2(0.3f, 0), player.b2body.getWorldCenter(), true);
}
Hud2.addscore(1);
}
} else {
keyPressed = false;
}
if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) {
if (!keyPressed2) {
keyPressed2 = true;
if (player.b2body.getLinearVelocity().y <= 4.0f) {
player.b2body.applyLinearImpulse(new Vector2(0, 3.0f), player.b2body.getWorldCenter(), true);
}
}
} else {
keyPressed2 = false;
}
if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && player.b2body.getLinearVelocity().x >= -2)
player.b2body.applyLinearImpulse(new Vector2(-5.2f, 0), player.b2body.getWorldCenter(), true);
}
public void update(float dt){
handleInput(dt);
world.step(1 / 60f, 6, 2);
player.update(dt);
hud.update(dt);
gamecam.position.x = player.b2body.getPosition().x;
gamecam.update();
renderer.setView(gamecam);
}
#Override
public void render(float delta) {
update(delta);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
b2dr.render(world, gamecam.combined);
Globals.game.batch.setProjectionMatrix(gamecam.combined);
Globals.game.batch.begin();
player.draw(Globals.game.batch);
Globals.game.batch.end();
Globals.game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
#Override
public void resize(int width, int height) {
gamePort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
map.dispose();
renderer.dispose();
world.dispose();
b2dr.dispose();
hud.dispose();
}
}

Related

Simple game works on tablet but sometimes lags on phone

I'm developing simple Android game, but I'm running into problems while testing it. When I run it on Lenovo Tab3 7 tablet (Android 5.0.1 ) or LG P880 phone (Android 4.0.3) it works fine. When I run it on Samsung S7 phone (Android 7.0) game usually runs fine. What I mean by this is that I can run it 10 times in a row with no problems, but sometimes game halts for 5-30 seconds or stops responding. This usually happens during starting of new Activity or very shortly after it.
Game has 4 Activities which use extended SurfaceView as layout. All SurfaceViews implement Runnable. Activities are: Splash screen (noHistory = "true" in Manifest), Menu, Difficulty choice and Game.
I use only mdpi drawables and scale them proportionally to all screen sizes. Bitmaps are loaded using BitmapFactory.decodeResource with BitmapFactory.Options inDensity = 1, inScaled = false.
When the problem occurs logcat shows only garbage collection. Sometimes game "pauses" (no taps are registered) for 5-30 seconds and resumes normally, sometimes it has to be restarted due to no response. I feel like game stops collecting input for some reason. Input is handled by overriding onTouchEvent and checking if ACTION_UP is within tapped image bounds. As I said, this happens only on S7 (I tried it on two phones), not on tablet or P880, so I'm thinking it might be something to do with Nougat or me forcing lower density on the phone.
So, since I'm running out of ideas what could be causing this and me being new to Android game development, does anyone know/have any idea where I should be looking for solution? Is there anything Nougat-specific I should be setting/checking? Does forcing pixel density affect device performance in any way?
Edit 1
globalApp
public class globalApp extends Application {
SoundPool soundPool;
SoundPool.Builder soundPoolBuilder;
AudioAttributes audioAttributes;
AudioAttributes.Builder audioAttributesBuilder;
int soundTap, soundCorrect, soundIncorrect, soundVictory, soundDefeat;
int soundBarrelVerySlow, soundBarrelSlow, soundBarrelNormal, soundBarrelFast, soundBarrelVeryFast;
#Override
public void onCreate() {
super.onCreate();
}
public void buildSoundPool(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
audioAttributesBuilder = new AudioAttributes.Builder();
audioAttributesBuilder.setUsage(AudioAttributes.USAGE_GAME);
audioAttributesBuilder.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION);
audioAttributes = audioAttributesBuilder.build();
soundPoolBuilder = new SoundPool.Builder();
soundPoolBuilder.setMaxStreams(2);
soundPoolBuilder.setAudioAttributes(audioAttributes);
soundPool = soundPoolBuilder.build();
}
else {
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
}
}
public void loadSounds(){
soundBarrelVerySlow = soundPool.load(this,R.raw.very_slow_move, 1);
soundBarrelSlow = soundPool.load(this, R.raw.slow_move, 1);
soundBarrelNormal = soundPool.load(this, R.raw.slow_move, 1);
soundBarrelFast = soundPool.load(this,R.raw.fast_move, 1);
soundBarrelVeryFast = soundPool.load(this,R.raw.very_fast_move, 1);
soundTap = soundPool.load(this, R.raw.tap_sound, 1);
soundCorrect = soundPool.load(this, R.raw.correct, 1);
soundIncorrect = soundPool.load(this, R.raw.incorrect, 1);
soundVictory = soundPool.load(this, R.raw.victory, 1);
soundDefeat = soundPool.load(this, R.raw.defeat, 1);
}
public void playTap(){
soundPool.play(soundTap, 1, 1,1, 0, 1);
}
public void playCorrect(){
soundPool.play(soundCorrect, 1, 1,1, 0, 1);
}
public void playIncorrect(){
soundPool.play(soundIncorrect, 1, 1,1, 0, 1);
}
public void playVictory(){
soundPool.play(soundVictory, 1, 1,1, 0, 1);
}
public void playDefeat(){
soundPool.play(soundDefeat, 1, 1,1, 0, 1);
}
public void playBarrelVerySlow(){soundPool.play(soundBarrelVerySlow, 1, 1, 1, 0, 1);}
public void playBarrelSlow(){soundPool.play(soundBarrelSlow, 1, 1, 1, 0, 1);}
public void playBarrelNormal(){
soundPool.play(soundBarrelNormal, 1, 1,1, 0, 1);
}
public void playBarrelFast(){soundPool.play(soundBarrelFast, 1, 1, 1, 0, 1);}
public void playBarrelVeryFast(){soundPool.play(soundBarrelVeryFast, 1, 1, 1, 0, 1);}
}
MenuItem
public class MenuItem {
private Bitmap bmp;
private Context context;
private Rect sourceRect;
private RectF destRect;
private int srcWidth;
private int srcHeight;
private int destW, destH;
private int x, y;
private int screenH;
public MenuItem(Context ctx, String bmpName, int w, int x, int y, int sX, int sY){
context = ctx;
BitmapFactory.Options bmpFOptions = new BitmapFactory.Options();
bmpFOptions.inDensity = 1;
bmpFOptions.inScaled = false;
int res = context.getResources().getIdentifier(bmpName, "drawable", ctx.getPackageName());
bmp = BitmapFactory.decodeResource(ctx.getResources(), res, bmpFOptions);
srcWidth = w;
srcHeight = bmp.getHeight();
this.x = x;
this.y = y;
screenH = sY;
sourceRect = new Rect(0,0, srcWidth, srcHeight);
destRect = new RectF();
setProportionalDestinationRect(sX, sY);
}
private void setProportionalDestinationRect(int scrX, int scrY) {
if (scrX != 1024 || scrY != 552){
float propX = (float)scrX/1024;
float propY = (float)scrY/600;
// All drawables are designed for 1024x600 screen
// if device screen is different, scale image proportionally
destW = (int)(srcWidth * propX);
destH = (int) (srcHeight * propY);
x = (int) (x*propX);
y = (int) (y*propY);
}
else {
destW = srcWidth;
destH = srcHeight;
}
destRect.set(x,y, x+destW,y+destH);
}
public void update(){
}
public Bitmap getBmp() {
return bmp;
}
public void setBmp(Bitmap bmp) {
this.bmp = bmp;
}
public Rect getSourceRect() {
return sourceRect;
}
public void setSourceRect(Rect sourceRect) {
this.sourceRect = sourceRect;
}
public RectF getDestRect() {
return destRect;
}
public void setDestRect(RectF destRect) {
this.destRect = destRect;
}
public boolean contains(int x, int y){
if (destRect.left <= x && destRect.right >= x)
if (destRect.top <= y && destRect.bottom >= y)
return true;
return false;
}
public void setY(int y) {
this.y = y;
if (screenH != 552){
float propY = (float)screenH/600;
y = (int) (y*propY);
}
destRect.set(x,y, x+destW,y+destH);
}
}
MainActivity
public class MainActivity extends Activity {
private boolean backPressedOnce = false;
long backPressedTime = 0;
private MainActivitySurface mainActivitySurface;
globalApp app;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
int x = getIntent().getIntExtra("screenWidth", 500);
int y = getIntent().getIntExtra("screenHeight", 500);
app = (globalApp) getApplication();
app.buildSoundPool();
app.loadSounds();
mainActivitySurface = new MainActivitySurface(this, app, x, y);
mainActivitySurface.setParentActivity(MainActivity.this);
setContentView(mainActivitySurface);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001) {
if (resultCode == RESULT_OK) {
int result = data.getIntExtra("difficulty", 3);
mainActivitySurface.setResultDifficulty(result);
}
}
}
#Override
protected void onPause() {
super.onPause();
mainActivitySurface.pause();
}
#Override
protected void onResume() {
super.onResume();
backPressedOnce = false;
mainActivitySurface.resume();
}
#Override
public void onBackPressed() {
if (backPressedOnce && backPressedTime + 2000 > System.currentTimeMillis()) {
Process.killProcess(Process.myPid());
System.exit(1);
} else {
Toast.makeText(this, "Press back again to exit.", Toast.LENGTH_SHORT).show();
backPressedOnce = true;
}
backPressedTime = System.currentTimeMillis();
}
}
MainActivitySurface
public class MainActivitySurface extends SurfaceView implements Runnable {
private Context context;
private SurfaceHolder surfaceHolder;
private Canvas canvas;
private Thread thread = null;
volatile private boolean running = false;
private boolean surfaceCreated = false;
private Intent playIntent;
private Intent difficultyIntent;
// Screen size
private int screenWidth, screenHeight;
//Menu items
private MenuItem menuItemPlay, menuItemDifficulty, middleBarrel, bg;
private int difficulty = 3;
private Activity parentActivity;
private globalApp app;
public MainActivitySurface(Context ctx, globalApp a, int scrW, int scrH){
super(ctx);
context = ctx;
screenHeight = scrH;
screenWidth = scrW;
app = a;
surfaceHolder = getHolder();
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
surfaceCreated = true;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
bg = new MenuItem(context, "main_activity_background_single", 1024, 0, 0, scrW, scrH);
menuItemPlay = new MenuItem(context, "menu_item_play_single", 233,(1024-233)/2,100, scrW, scrH);
menuItemDifficulty = new MenuItem(ctx, "menu_item_difficulty_single", 520,(1024 - 520)/2,400,scrW,scrH);
middleBarrel = new MenuItem(ctx, "middle_barrel_single", 323,(1024-323)/2,200,scrW,scrH);
playIntent = new Intent(context, GameActivity.class);
playIntent.putExtra("screenWidth", screenWidth);
playIntent.putExtra("screenHeight", screenHeight);
}
#Override
public void run() {
while (running){
draw();
}
}
private void draw() {
if(surfaceHolder.getSurface().isValid()){
canvas = surfaceHolder.lockCanvas();
canvas.drawBitmap(bg.getBmp(), bg.getSourceRect(), bg.getDestRect(), null);
canvas.drawBitmap(menuItemPlay.getBmp(), menuItemPlay.getSourceRect(), menuItemPlay.getDestRect(), null);
canvas.drawBitmap(menuItemDifficulty.getBmp(), menuItemDifficulty.getSourceRect(), menuItemDifficulty.getDestRect(), null);
canvas.drawBitmap(middleBarrel.getBmp(), middleBarrel.getSourceRect(), middleBarrel.getDestRect(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
public void resume(){
running = true;
thread = new Thread(this);
thread.start();
}
public void pause(){
running = false;
boolean retry = false;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
Log.d("info", "MainActivitySurface: Error joining thread");
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & event.ACTION_MASK){
case MotionEvent.ACTION_UP:
if (menuItemPlay.contains((int) event.getX(), (int) event.getY())){
app.playTap();
parentActivity.startActivity(playIntent);
parentActivity.overridePendingTransition(0,0);
break;
}
if (menuItemDifficulty.contains((int) event.getX(), (int) event.getY())){
app.playTap();
difficultyIntent = new Intent(parentActivity, DifficultyActivity.class);
difficultyIntent.putExtra("screenWidth", screenWidth);
difficultyIntent.putExtra("screenHeight", screenHeight);
difficultyIntent.putExtra("difficulty", difficulty);
parentActivity.startActivityForResult(difficultyIntent, 1001);
parentActivity.overridePendingTransition(0, 0);
break;
}
}
return true;
}
public void setParentActivity(Activity act){
parentActivity = act;
}
public void setResultDifficulty(int diff){
difficulty = diff;
playIntent.putExtra("difficulty", difficulty);
}
}
DifficultyActivity
public class DifficultyActivity extends Activity {
private DifficultySurface surface;
private globalApp app;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
app = (globalApp) getApplication();
surface = new DifficultySurface(this, app, getIntent().getIntExtra("screenWidth", 500), getIntent().getIntExtra("screenHeight", 500));
setContentView(surface);
}
#Override
protected void onPause() {
super.onPause();
app.soundPool.release();
surface.pause();
overridePendingTransition(0, 0);
}
#Override
protected void onResume() {
super.onResume();
app.buildSoundPool();
app.loadSounds();
surface.resume();
}
}
DifficultySurface
public class DifficultySurface extends SurfaceView implements Runnable {
private SurfaceHolder surfaceHolder;
private Thread thread = null;
private Canvas canvas;
private Context context;
private globalApp app;
private boolean surfaceCreated = false;
private boolean running = false;
private MenuItem bgProp, arrowBarrel, okButton, diffVeryEasy, diffEasy, diffNormal, diffHard, diffVeryHard;
private int difficulty;
public DifficultySurface(Context ctx, globalApp a, int scrW, int scrH){
super(ctx);
context = ctx;
app = a;
surfaceHolder = getHolder();
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
surfaceCreated = true;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
difficulty = ((Activity)context).getIntent().getIntExtra("difficulty", 3);
bgProp = new MenuItem(ctx, "difficulty_background", 1024, 0, 0, scrW, scrH);
diffVeryEasy = new MenuItem(ctx, "very_easy",796, 100, 100, scrW, scrH);
diffEasy = new MenuItem(ctx, "easy",796, 100, 200 , scrW, scrH);
diffNormal = new MenuItem(ctx, "normal",796, 100, 300, scrW, scrH);
diffHard = new MenuItem(ctx, "hard",796, 100, 400 , scrW, scrH);
diffVeryHard = new MenuItem(ctx, "very_hard",796, 100, 500, scrW, scrH);
okButton = new MenuItem(ctx, "ok_button", 100, 924, 500, scrW, scrH);
arrowBarrel = new MenuItem(ctx, "barrel_arrow", 100, 0, 100*difficulty, scrW, scrH);
}
#Override
public void run() {
while (running) {
if (surfaceCreated) {
update();
draw();
}
}
}
private void update() {
arrowBarrel.setY(difficulty*100);
}
private void draw() {
if (surfaceHolder.getSurface().isValid()){
canvas = surfaceHolder.lockCanvas();
canvas.drawBitmap(bgProp.getBmp(), bgProp.getSourceRect(), bgProp.getDestRect(), null);
canvas.drawBitmap(arrowBarrel.getBmp(), arrowBarrel.getSourceRect(), arrowBarrel.getDestRect(), null);
canvas.drawBitmap(diffVeryEasy.getBmp(), diffVeryEasy.getSourceRect(), diffVeryEasy.getDestRect(), null);
canvas.drawBitmap(diffEasy.getBmp(), diffEasy.getSourceRect(), diffEasy.getDestRect(), null);
canvas.drawBitmap(diffNormal.getBmp(), diffNormal.getSourceRect(), diffNormal.getDestRect(), null);
canvas.drawBitmap(diffHard.getBmp(), diffHard.getSourceRect(), diffHard.getDestRect(), null);
canvas.drawBitmap(diffVeryHard.getBmp(), diffVeryHard.getSourceRect(), diffVeryHard.getDestRect(), null);
canvas.drawBitmap(okButton.getBmp(), okButton.getSourceRect(), okButton.getDestRect(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & event.ACTION_MASK){
case MotionEvent.ACTION_UP:{
if (diffVeryEasy.contains((int) event.getX(), (int) event.getY())){
app.playTap();
difficulty = 1; }
if (diffEasy.contains((int) event.getX(), (int) event.getY())){
app.playTap();
difficulty = 2;
}
if (diffNormal.contains((int) event.getX(), (int) event.getY())){
app.playTap();
difficulty = 3;
}
if (diffHard.contains((int) event.getX(), (int) event.getY())){
app.playTap();
difficulty = 4;
}
if (diffVeryHard.contains((int) event.getX(), (int) event.getY())){
app.playTap();
difficulty = 5;
}
if (okButton.contains((int)event.getX(), (int) event.getY())){
app.playTap();
((Activity)context).getIntent().putExtra("difficulty", difficulty);
((Activity)context).setResult(Activity.RESULT_OK, ((Activity)context).getIntent());
((Activity)context).finish();
((Activity)context).overridePendingTransition(0, 0);
}
break;
}
}
return true;
}
public void pause(){
running = false;
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
((Activity)context).overridePendingTransition(0, 0);
}
public void resume(){
running = true;
thread = new Thread(this);
thread.start();
}
}
GameActivity
public class GameActivity extends Activity {
private GameSurface surface;
private globalApp app;
private int difficulty;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Setting full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
difficulty = getIntent().getIntExtra("difficulty", 3);
app = (globalApp) getApplication();
surface = new GameSurface(this, app, getIntent().getIntExtra("screenWidth", 500), getIntent().getIntExtra("screenHeight", 500), difficulty);
surface.setParentActivity(this);
setContentView(surface);
}
#Override
protected void onPause() {
super.onPause();
app.soundPool.release();
surface.pause();
}
#Override
protected void onPostResume() {
super.onPostResume();
app.buildSoundPool();
app.loadSounds();
surface.resume();
}
#Override
protected void onStop() {
super.onStop();
surface.stop();
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
Game halting happens either when I start DificultyActivity (I tap one MenuItem objects but nothing happens) or when I start GameActivity (game still shows MainActivity + MainActivitySurface).
Android Monitor show less than 40MB of allocated memory, so bitmaps shouldn't be the problem in my opinion. I tried recycling all bitmaps but the problem was present (that's why I opted to use only mdpi drawables; at first I used all pixel densities but tried lowering resources in case that was causing halts).
It is hard to find the problem without looking at the code. There's nothing nougat-specific way of handling the resources.
But android N claims to have a better memory management and since you are complaining a lot of garbage collections, it may be one of the cause. Make sure to recycle the unused bitmaps. And use RGB_565 as the preferred bitmap config which requires half memory than RGB_8888.
I have solved my problem. After posting question I came across this. It seems we had the same problem. When I slowed down drawing speed (using thread.sleep) there were no more issues.
Thanks to those who helped me.

libgdx android game not rendering properly

My game works fine on desktop, but when I load it on an android device or the emulator I get a black screen. The game is working; I can hear the sounds and click the UI buttons. When testing on my android phone, I can turn the screen off and on again, and then the game renders fine. I would appreciate an explanation of what I'm doing wrong.
public class TestProject extends Game {
GameScreen gameScreen;
EndScreen endScreen;
MenuScreen menuScreen;
#Override
public void create () {
Gdx.app.log("TestProject", "created");
AssetLoader.load();
gameScreen = new GameScreen(this);
endScreen = new EndScreen(this);
menuScreen = new MenuScreen(this);
setScreen(menuScreen);
}
#Override
public void dispose() {
super.dispose();
AssetLoader.dispose();
}
}
public class MenuScreen implements Screen{
private SpriteBatch spriteBatch;
final static float GAME_WIDTH = 200;
final static float GAME_HEIGHT = 100;
public static final float UNIT_SCALE = 1/8f;
static float aspectRatio;
private OrthographicCamera cam;
Viewport viewport;
Stage stage;
TestProject project;
public MenuScreen(TestProject theProject){
project = new TestProject();
this.project = theProject;
aspectRatio = (float)Gdx.graphics.getHeight() / (float)Gdx.graphics.getWidth();
spriteBatch = new SpriteBatch();
stage = new Stage();
Gdx.input.setInputProcessor(stage);
cam = new OrthographicCamera();
viewport = new ExtendViewport(GAME_WIDTH * aspectRatio, GAME_HEIGHT, cam);
viewport.apply();
cam.setToOrtho(false, GAME_WIDTH, GAME_HEIGHT);
cam.position.set(GAME_WIDTH / 2, GAME_HEIGHT / 2, 0);
stage.addActor(AssetLoader.playButton);
}
#Override
public void render(float delta){
//Clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.setProjectionMatrix(cam.combined);
AssetLoader.font.getData().setScale(.25f, -.25f);
AssetLoader.playButton.setPosition((Gdx.graphics.getWidth() / 2) - AssetLoader.playButton.getWidth() / 2,
(Gdx.graphics.getHeight() / 3) - AssetLoader.playButton.getHeight() / 2);
spriteBatch.begin();
spriteBatch.draw(AssetLoader.menuBG, 0, 0, 200, 100);
AssetLoader.font.draw(spriteBatch, "Shark Run", 55, 85);
spriteBatch.end();
stage.draw();
}
#Override
public void show() {
AssetLoader.playButton.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
project.setScreen(project.gameScreen);
}
});
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}

Is this the right way to detect a touch on a rectangle in LibGdx ? Does not seem to be working for me

This is the code for my gamescreen where i want burst my ballon when its touched .
orientation is portrait.
but it does not seem to work for me.
public class GameScreen implements Screen {
final BB game;
private BitmapFont font;
private static final int no_of_frames = 2;
Texture ballonFrames;
TextureRegion[] burstFrames = new TextureRegion[no_of_frames];
Animation burstAnimation;
Array<Rectangle> ballons;
TextureRegion currentFrame;
long lastBallonTime;
int ballonBursted;
OrthographicCamera camera;
int ballonMissed;
Sound ballonBursting;
public GameScreen(final BB gam) {
this.game = gam;
ballonFrames = new Texture(Gdx.files.internal("ballon_burst.png"));
font = new BitmapFont(Gdx.files.internal("font.fnt"), false);
ballonBursting = Gdx.audio.newSound(Gdx.files
.internal("BallonBursting.wav"));
TextureRegion[][] tmp = TextureRegion.split(ballonFrames,
ballonFrames.getWidth() / 2, ballonFrames.getHeight());
burstFrames[0] = tmp[0][0];
burstFrames[1] = tmp[0][1];
burstAnimation = new Animation(3.0f, burstFrames);
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
ballons = new Array<Rectangle>();
spawnBallon();
}
private void spawnBallon() {
Rectangle ballon = new Rectangle();
ballon.x = MathUtils.random(0, 800 - 64); //
ballon.y = 0;
ballon.width = 40;
ballon.height = 80;
ballons.add(ballon);
lastBallonTime = TimeUtils.nanoTime();
}
private boolean ballonBursted(Rectangle ballon) {
Vector2 touch = new Vector2(Gdx.input.getX(), Gdx.input.getY());
if (ballon.contains(touch))
return true;
else
return false;
}
#Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor(0, 0, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
InputProcessor processor;
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
font.draw(game.batch, "Ballon Bursted :" + ballonBursted, 0, 700);
font.draw(game.batch, "Ballon Missed:" + ballonMissed, 275, 700);
for (Rectangle ballon : ballons) {
game.batch.draw(burstFrames[0], ballon.x, ballon.y);
}
if (TimeUtils.nanoTime() - lastBallonTime > 1000000000) {
spawnBallon(); // a ballon every second
}
Iterator<Rectangle> iter = ballons.iterator();
while (iter.hasNext()) {
Rectangle ballon = iter.next();
ballon.y = ballon.y + 100 * Gdx.graphics.getDeltaTime();
if (ballonBursted(ballon) == true) {
ballonBursted++;
game.batch.draw(burstFrames[1], ballon.x, ballon.y);
ballonBursting.play();
iter.remove();
}
else if (ballon.y + 64 > 800) {
iter.remove();
ballonMissed++;
}
}
if (ballonMissed > 5) {
game.setScreen(new ScoreScreen(game, ballonBursted));
}
game.batch.end();
}
#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() {
ballonFrames.dispose();
ballonBursting.dispose();
game.batch.dispose();
}
I am using animation class of libgdx to change my image of ballon to the one where its bursted .
I am fairly new to libgdx and unable to figure out what wrong am i doing here .
Should i create a table and layout my ballon elements as actor?
Try something like this:
private boolean ballonBursted(Rectangle ballon) {
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
if (ballon.contains(touchPos.x, touchPos.y))
return true;
else
return false;
}
please read this https://stackoverflow.com/a/18555705/2158970
If I understand it right you just want to know if the touchpoint is contained in the Rectangle ballon. Then you could use Rectangle#contains() method:
ballon.contains(Gdx.input.getX(), Gdx.input.getY());
see also the source code of Rectangle class

how to open another class by clicking on a button on libgdx? (android development eclipse)

I am making my own game. I have already made a splash screen and a main menu. I have made a button "Play" in my menu but I can't link it to my main game, while I can link it to other classes.
Here is the code of the class I can't open:
package com.mygdx.Papermadness.screens;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Vector2;
public class PaperMadness extends InputAdapter implements ApplicationListener, Screen {
float timer;
public static Preferences prefs;
public static int counter; // The variable you want to save
private BitmapFont font;
//public int counter = 0;
boolean touch = false;
SpriteBatch batch;
SpriteBatch spriteBatch;
Texture spriteTexture;
Sprite sprite;
float scrollTimer = 0.0f;
Player player;
Paper paper;
Huiz huiz;
Lijn lijn;
String money = String.valueOf(counter);
ShapeRenderer sr;
public boolean kukar = false;
public void create() {
font = new BitmapFont();
Gdx.input.setInputProcessor(this);
player = new Player(new Vector2(50, 100), new Vector2(100, 100));
huiz = new Huiz(new Vector2(200, 300), new Vector2(110, 110));
// huiz = new Huiz(new Vector2(200, 300), new Vector2(110, 110));
paper = new Paper(new Vector2(Gdx.input.getX(),
Gdx.graphics.getHeight() - Gdx.input.getY()), new Vector2(50,
50));
lijn = new Lijn(new Vector2(0, 200), new Vector2(600, 2));
// sr = new ShapeRenderer();
spriteBatch = new SpriteBatch();
spriteTexture = new Texture("b9.png");
spriteTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
sprite = new Sprite(spriteTexture);
sprite.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
// bounds.set(Gdx.input.getX(),
// Gdx.graphics.getHeight() - Gdx.input.getY(),
// secondTexture.getWidth(), secondTexture.getHeight());
scrollTimer += Gdx.graphics.getDeltaTime();
if (scrollTimer > 1.0f)
scrollTimer = 0.0f;
sprite.setV(scrollTimer + 2);
sprite.setV2(scrollTimer);
player.update();
paper.update();
lijn.update();
huiz.update();
/*
* if (tree.getBounds().overlaps(ball.getBounds())) {
* System.out.println("Swendley Programinateur"); }
*
* if (tree.getBounds().overlaps(paper.getBounds())) {
* System.out.println("Souk Programinateur"); }
*/
spriteBatch.begin();
sprite.draw(spriteBatch);
spriteBatch.end();
batch.begin();
player.draw(batch);
huiz.draw(batch);
// paper.draw(batch);
if (Gdx.graphics.getHeight() / 1.25 < Gdx.input.getY()
&& Gdx.graphics.getWidth() / 2.7 < Gdx.input.getX()
&& Gdx.graphics.getWidth() / 1.7 > Gdx.input.getX()
&& Gdx.input.isTouched() && kukar == false && touch == false) {
kukar = true;
touch = true;
} else if (Gdx.input.isTouched() && kukar == true && touch == true) {
paper.draw(batch);
if (paper.getBounds().overlaps(huiz.getBounds())
|| paper.getBounds().overlaps(huiz.getBounds1())) {
// System.out.println("Huis Geraakt!");
touch = false;
counter++;
checkSpeed();
money = Integer.toString(counter);
// System.out.println(counter);
}
}
if (huiz.getBounds().overlaps(lijn.getBounds())
|| huiz.getBounds1().overlaps(lijn.getBounds())){
//System.out.println("Game Over");
}
font.draw(batch, money, Gdx.graphics.getWidth() / 2.06f,
Gdx.graphics.getHeight() / 1.05f);
font.setColor(Color.BLACK);
font.setScale(2, 2);
// house.draw(batch);
// house1.draw(batch);
lijn.draw(batch);
batch.end();
// sr.begin(ShapeType.Filled);
// sr.setColor(Color.YELLOW);
// sr.rect(Gdx.input.getX(), Gdx.graphics.getHeight() -
// Gdx.input.getY(),
// paper.getSize().x, paper.getSize().y);
// sr.setColor(Color.BLACK);
// sr.rect(huiz.getPosition().x, huiz.getPosition().y,
// huiz.getSize().x, huiz.getSize().y);
// sr.rect(house1.getPosition().x, house1.getPosition().y,
// house1.getSize().x, house1.getSize().y);
// sr.end();
}
public static void savePrefs(){
prefs = Gdx.app.getPreferences("game-prefs"); // The name of your prefs files
prefs.putInteger("counter", counter);
prefs.flush();
System.out.println(prefs);
}
public static void loadPrefs(){
prefs = Gdx.app.getPreferences("game-prefs");
counter = prefs.getInteger("counter",0); //Load counter, default to zero if not found
}
public void checkSpeed() {
if (counter <= 7) {
huiz.huisVelocity = 500f;
}
if (counter > 7 && counter <= 17) {
huiz.huisVelocity = 550f;
}
if (counter > 17 && counter <= 30) {
huiz.huisVelocity = 650f;
}
if (counter > 30 && counter <= 50) {
huiz.huisVelocity = 750;
}
if (counter > 50 && counter <= 75) {
huiz.huisVelocity = 900;
}
if (counter > 75 && counter <= 100) {
huiz.huisVelocity = 1000;
}
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
kukar = false;
touch = false;
return true;
}
#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() {
}
#Override
public void render() {
}
}
Here is the menu class:
package com.mygdx.Papermadness.screens;
import com.badlogic.gdx.Game;
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.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.mygdx.Papermadness.Papermadness;
public class MainMenu implements Screen {
private Stage stage;// done
private TextureAtlas atlas;// done
private Skin skin;// done
private Table table;// done
private TextButton buttonPlay, buttonExit;
private BitmapFont white, black;// done
private Label heading;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Table.drawDebug(stage);
stage.act(delta);
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
atlas = new TextureAtlas("ui/button.pack");
skin = new Skin(atlas);
table = new Table(skin);
table.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
white = new BitmapFont(Gdx.files.internal("font/white.fnt"), false);
black = new BitmapFont(Gdx.files.internal("font/black.fnt"), false);
// maakt buttons
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = skin.getDrawable("button.up");
textButtonStyle.down = skin.getDrawable("button.down");
textButtonStyle.pressedOffsetX = 1;
textButtonStyle.pressedOffsetY = -1;
textButtonStyle.font = black;
buttonExit = new TextButton("EXIT", textButtonStyle);
buttonExit.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.exit();
}
});
buttonExit.pad(15);
buttonPlay = new TextButton("PlAY", textButtonStyle);
buttonPlay.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
((Game) Gdx.app.getApplicationListener())
.setScreen(new PaperMadness());
}
});
buttonPlay.pad(15);
// maakt header
heading = new Label(Papermadness.TITLE, new LabelStyle(white,
Color.WHITE));
heading.setFontScale(2);
table.add(heading);
table.getCell(heading).spaceBottom(100);
table.row();
table.add(buttonPlay);
table.getCell(buttonPlay).spaceBottom(15);
table.row();
table.add(buttonExit);
// table.debug();
stage.addActor(table);
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
stage.dispose();
atlas.dispose();
skin.dispose();
white.dispose();
black.dispose();
}
}
public class MyGdxGame extends Game{
public static MenuScreen menuScreen;
public static GameScreen gameScreen;
#Override
public void create(){
menuScreen = new MenuScreen(this);
gameScreen = new GameScreen (this);
setScreen(menuScreen);
}
}
Here is MenuScreen
public class MenuScreen implements Screen{
MyGdxGame game;
public MenuScreen(MyGdxGame game){
this.game = game;
}
////////////when you want to change screen type game.setScreen(game.gameScreen)
...........
...........
}
and this is GameScreen
public class GameScreen implements Screen{
...........
...........
...........
}
this is a simple example , try to do the same in your code.
Here is a good tutorial
https://github.com/libgdx/libgdx/wiki/Extending-the-simple-game
If it helped , let me know about it.

Why is my phone not loading a table in libgdx?

For some reason, my android phone will not load a table even though I have it being drawn. It shows up on the desktop version, but not on the android version. You can see my adding it in the render() method in the if statement. It loads perfectly on my desktop. This is only showing the code I used for the table. The desktop version and phone version has the same camera size. Everything else appears on my phone except for this table.
public class game implements Screen {
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
tManager.update(delta);
backBatch.begin();
splash.draw(backBatch);
backBatch.end();
stage.act(delta);
stage.draw();
world.step(TIMESTEP, VITERATIONS, PITERATIONS);
table2 = new Table(skin);
table2.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
int numContacts = world.getContactCount();
if (numContacts > 0) {
table2.add(heading3).spaceBottom(35).row();
table2.add(replayButton).spaceBottom(15).row();
table2.add(menuButton);
movement.x = -sSpeed;
movement.y = 10;
movement.rotate(720);
stage.addActor(table2);
Gdx.input.setInputProcessor(stage);
}
debugRenderer.render(world, camera.combined);
}
public void resize(int width, int height) {
camera.viewportWidth = 450;
camera.viewportHeight = 250;
camera.update();
stage.setViewport(450, 250, true);
stage.getCamera().translate(-stage.getGutterWidth(), -stage.getGutterHeight(), 0);
if (table != null){
table.setSize(450, 250);
}
}
#Override
public void show()
{
stage = new Stage();
world = new World(new Vector2(0, 0), true);
debugRenderer = new Box2DDebugRenderer();
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
//replay button
replayButton = new TextButton("REPLAY", skin);
replayButton.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y)
{
((Game) Gdx.app.getApplicationListener()).setScreen(new game());
}
});
replayButton.pad(15);
//main menu button
menuButton = new TextButton("MAIN MENU", skin);
menuButton.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y)
{
((Game) Gdx.app.getApplicationListener()).setScreen(new MainMenu());
}
});
menuButton.pad(10);
//game over
heading3 = new Label("game over", skin);
heading3.setFontScale(2);
}
private void createCollisionListener() {
//collisions in world
world.setContactListener(new ContactListener() {
public void beginContact(Contact contact) {
}
public void endContact(Contact contact) {
}
public void preSolve(Contact contact, Manifold oldManifold) {
}
public void postSolve(Contact contact, ContactImpulse impulse) {
}
});
}

Categories

Resources