I am writing a game for Android using AndEngine GLES 2. Everything was working properly - I had a background image, there were sprites moving around and even some music - until recently I tried something new (I wanted to be able to switch between two different scenes) when the display turned black.
I could still execute the game and there were no error shown. All log entries I made during the game were shown, even the music was playing so I knew the game was running "properly", but I couldn't see any image. Nothing. All black.
So I thought, changing everything back to before this "error" appeared, would do the trick. But still the screen is black.
I even tried commenting everything out but the background image - nothing.
Now if it is not too much to ask, could anyone please look over this short piece of code and tell me what is wrong there?
This are the variables I use:
private SmoothCamera camera;
private BitmapTextureAtlas bitmapTextureAtlas;
private Scene scene;
private Sprite background;
The EngineOptions I never changed, so they should be alright.
#Override
public EngineOptions onCreateEngineOptions() {
float positionX = 80f; // horizontal (x) position of the camera
float positionY = 280f; // vertical (y) position of the camera
float velocityX = 200f; // velocity of the horizontal camera movement
float velocityY = 200f; // velocity of the vertical camera movement
float zoomFactor = 1f; // the camera's zoom Factor (standard := 1)
this.camera = new SmoothCamera(positionX, positionY, this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight(), velocityX, velocityY, zoomFactor);
EngineOptions options = new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(this.camera.getWidth(), this.camera.getHeight()), this.camera);
return options;
}
Here I create the TextureAtlas and load a background image.
#Override
protected void onCreateResources() {
// create the TextureAtlas
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.bitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 1024, 1600, TextureOptions.NEAREST);
// background
this.background = new Sprite(0, 0, BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.bitmapTextureAtlas, this, "background.png", 0, 0, 1, 1), this.getVertexBufferObjectManager());
this.mEngine.getTextureManager().loadTexture(this.bitmapTextureAtlas);
}
And finally the Scene is instantiated and the background gets attached.
#Override
protected Scene onCreateScene() {
this.scene = new Scene();
this.scene.attachChild(this.background);
return this.scene;
}
Now why would this small Activity not show? I forgot: its a SimpleBaseGameActivity.
Well, since AndEngine GLES2 is not running on the emulator, I have to use my phone (Samsung Galaxy GIO) and can't test the app on another machine.
Did anyone stumble upon a similar problem?
Any help is really much appreciated and thank you for your time !
Christoph
I think the problem is here:
this.bitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 1024, 1600, TextureOptions.NEAREST);
The dimensions of the Atlas are supposed to be powers of 2.
Related
While trying to develop a small game with LibGDX, I have a behavior that I don't explain : when I run my game in Android Studio Emulator (Nexus 5X API28) and on my phone (Samsung Galaxy S20), I have noticed a difference that I can't explain :
on the emulator, the touch (emulated with a click) is detected as expected
on my phone the touch is detected ~50-100 pixel higher than expected
My guess is that there is something to do with the way LibGDX handle the phone resolution and/or ratio
Here is a sample of the type of code I have:
LevelScreen(final PixGame game) {
this.game = game;
mTouchPoint = new Vector3();
camera = new OrthographicCamera();
camera.setToOrtho(false, 720, 1280);
FitViewport viewport = new FitViewport(720, 1280, camera);
Gdx.gl.glViewport(0, 0, 720, 1280);
viewport.update(game.ScreenWidth, game.ScreenHeight, true);
mStage = new Stage(viewport);
InputProcessor processor1 = new InputAdapter() {
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
game.mTouchUp = false;
return false;
}
#Override
public boolean touchUp(int x, int y, int pointer, int button) {
game.mTouchUp = true;
return false;
}
};
InputMultiplexer inputMultiplexer = new InputMultiplexer(processor1,mStage);
Gdx.input.setInputProcessor(inputMultiplexer);
Gdx.graphics.setContinuousRendering(false);
}
#Override
public void render(float delta) {
if(game.mTouchUp) {
mTouchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(mTouchPoint);
game.mTouchUp = false;
Gdx.app.debug("TOUCH", "Touchpoint coordinates : " + mTouchPoint);
}
}
I have removed all the game part on the code above, this is just the way I detect and handle touch event (and probably it's not the smartest way but hey, I'm not a pro-developer).
I have a PNG image as a background, and if I touch the same spot on the emulator and on my phone, I have the following result :
EMULATOR : Touchpoint coordinates : (90.0,1103.7681,0.0)
PHONE : Touchpoint coordinates : (95.33334,1054.3251,0.0)
The X coordinate is about the same (within the margin of error of my finger), the Y coordinate has always a minus 50-100px gap. I have tested many times on different positions on the screen and still the same behavior.
Any guess what I should do to handle this? Maybe the difference of screen ratio between the two (16:9 vs 16:10) ? Many thanks for the help.
After different tries, I've figured out what was happening : the problem was indeed coming from the ratio that is different between the two phones (16:9 vs 16:10).
In order to neutralize that, I have changed the line
FitViewport viewport = new FitViewport(720, 1280, camera);
with
Viewport viewport = new ScalingViewport(Scaling.stretch, 720, 1280, camera);
This is now handling the touch coordinates the same way on the 2 devices.
What is the proper way to extend the background in top down game? I used LibGdx framework. Any idea or tutorial for top down game.My background is in PNG format and screen of 720x1280 portrait.I had a problem in extending the background.I want the camera follow the character and the background will extend. How could I do that? Here is the Screen shot of
https://i.stack.imgur.com/jl03R.png
Here is my code
To display background I used this
//background
Background = new Texture(Gdx.files.internal("floor.png")); //File from assets folder
Background.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
bgsprite = new Sprite(Background);
In render
spriteBatch.draw(Background,0,100,0, srcy, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
srcy +=3;
The background is scrolling but the camera don't follow the player(cat)
Source code for GameScreen
http://pastebin.com/Dxfx9f65
Thank's and Advance any help or suggestion are much appreciated. :)
Use two identical texture background. Each the size of the screen It can be the same file. It is important that are docked vertically. Move of at the same time. Alternately changing with each other.
Sample code:
declaration:
Texture background1, background2;
SpriteBatch batch;
float yMax, yCoordBg1, yCoordBg2;
final int BACKGROUND_MOVE_SPEED = 100; // pixels per second. Put your value here.
creation:
Background1 = new Texture(Gdx.files.internal("floor.png"));
Background2 = new Texture(Gdx.files.internal("floor.png")); // identical
yMax = 1280;
yCoordBg1 = yMax*(-1); yCoordBg2 = 0;
in method render:
yCoordBg1 += BACKGROUND_MOVE_SPEED * Gdx.graphics.getDeltaTime();
yCoordBg2 = yCoordbg1 + yMax; // We move the background, not the camera
if (yCoordBg1 >= 0) {
yCoordBg1 = yMax*(-1); yCoordBg2 = 0;
}
batch.begin();
batch.draw(background1, 0, yCoordBg1);
batch.draw(background2, 0, yCoordBg2);
batch.end();
The background can be made in the format jpg - will spend less memory.
I have a little application and inserted a particle. Everything is fine, but the Particle is stretched or at least looking weird. This should be a simple call, but i did not find an answer yet.
Particle in Particle Editor looks good, in App looks not good.
Loading Code
Gdx.app.setLogLevel(Application.LOG_DEBUG);
app.getAssets().getLogger().setLevel(Application.LOG_DEBUG);
Gdx.app.log("MyTag", "my informative message");
app.getAssets().load("badlogic.jpg",Texture.class);
app.getAssets().load("uiskin.json",Skin.class);
app.getAssets().load("particle1.p", ParticleEffect.class);
app.getAssets().load("particle2.p", ParticleEffect.class);
Init code
ParticleEffect effect;
SpriteBatch batch;
batch = new SpriteBatch();
effect = app.getAssets().get("particle2.p", ParticleEffect.class);
//Setting the position of the ParticleEffect
effect.setPosition(100, 100);
effect.start();
Render code
batch.begin();
//Updating and Drawing the particle effect
effect.draw(batch, delta);
batch.end();;
if(effect.isComplete()){
effect.reset();
}
Camera
app.V_WIDTH = width;
app.V_HEIGHT = height;
app.getCamera().setToOrtho(false, app.V_WIDTH, app.V_HEIGHT);
stage.getViewport().update(width, height, true);
I want to move some sprites from left to right with a constant slow speed. I have first tried RatioResolutionPolicy but I saw sprites were flickering a lot. Then I have changed resolutionpolicy to FixedResolutionPolicy, defined sprite textures as bitmap, scaled them and made sprites by these textures (for more detail: click here). This is better than first method but not completely good. I use setx() for moving sprites. When I change x positon for example by 2 pixels for each frame there is no problem. But for different devices that have different resolutions I must multiply 2 by a ratio. In this case sprites are flickering again, not much but it is annoying for me.
code for camera is below
#Override
public EngineOptions onCreateEngineOptions() {
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
Point size = new Point();
w.getDefaultDisplay().getSize(size);
V.CAMERA_WIDTH = size.x;
V.CAMERA_HEIGHT = size.y;
} else {
Display d = w.getDefaultDisplay();
V.CAMERA_WIDTH = d.getWidth();
V.CAMERA_HEIGHT = d.getHeight();
}
if (V.CAMERA_HEIGHT/V.CAMERA_WIDTH>480f/860f){
V.CAMERA_HEIGHT=V.CAMERA_WIDTH*480f/860f;
}
else {
V.CAMERA_WIDTH=V.CAMERA_HEIGHT*860f/480f;
}
V.ratio=V.CAMERA_HEIGHT/480f;
this.mCamera = new Camera(0, 0, V.CAMERA_WIDTH, V.CAMERA_HEIGHT);
final EngineOptions engineOptions = new EngineOptions(true,
ScreenOrientation.LANDSCAPE_FIXED, new FixedResolutionPolicy((int)V.CAMERA_WIDTH, (int)V.CAMERA_HEIGHT),
this.mCamera);
return engineOptions;
}
for moving sprites:
this.wallPosX -= this.speed;
this.setX(Math.round(this.wallPosX));
speed is a floating point varibale and it gets 4.4651165 for 1280x720 screen resolution. If I set it as an integer than there is no flickering, but this time sprite speed differs from device to device.
There are too many screen sizes and screen ratio's for android phones.
Use the Cropped Resolution Policy created by jgibbs. Follow Martin Varga's tutorial to get an understanding on how it works and how to implement it.
It works wonders.
Original from jgibbs
I recommend Martin's Tutorial
You shouldn't be worried about micro managing entities positional co-ordinates to suit every and any possible screen size.
I'm not sure this will fix the flickering though, that may be some other problem not related to your camera
I have noticed that this wasn't about Andengine, it was about opengl. Solution for this problem is this wonderful tool:
https://github.com/gemserk/imageprocessing
I've searched all around google and this website for infos about this problem, but cannot solve it..
I'm a newbie in game development and LibGDX, and cannot find a solution well explained on how to port my game to all the various screen sizes..
Would you kindly help me?
Thanx
When using the newest libgdx version, you will find the Viewport class...
The viewport describes the transformation of the coordinate system of the screen (being the pixels from 0,0 in the lower left corner to e.g. 1280,768 in the upper right corner (depending on the device)) to the coordinate system of your game and scene.
The Viewport class has different possibilities on how to do that transformation. It can either stretch your scene coordinate system to exactly fit the screen coordinate system, which might change the aspect ratio and for example "stretch" your images or buttons.
It's also possible to fit the scene viewport with its aspect ratio into the viewport, which might produce a black border. E.g. when you have developed the game for 4:3 screens and now embed it into 16:10 displays.
The (in my opinion) best option is through fitting the scene viewport into the screen by matching either the longest or shortest edge.
This way, you can have a screen/window coordinate system from (0,0) to (1280,768) and create your game coordinate system maybe from (0,0) to (16,10) in landscape mode. When matching the longest edge, this means that the lower left corner of the screen will be (0,0), the lower right will be (16,0)... On devices that don't have the same aspect ratio, the y-values on the upper corners might differ a bit.
Or when matching the shortest edge, this means your scene coordinates will always be shown from (x,0) to (x,10) ... But the right edge might not exactly have and x value of 16, since device resolutions differ...
When using that method, you might have to reposition some buttons or UI elements, when they are supposed to be rendered on the top or the right edges...
Hope it helps...
Once me too suffered from this problem but at end i got the working solution, for drawing anything using SpriteBatch or Stage in libgdx. Using OrthographicCamera we can do this.
first choose one constant resolution which is best for game. Here i have taken 1280*720 (landscape).
class ScreenTest implements Screen {
final float appWidth = 1280, screenWidth = Gdx.graphics.getWidth();
final float appHeight = 720, screenHeight = Gdx.graphics.getHeight();
OrthographicCamera camera;
SpriteBatch batch;
Stage stage;
Texture img1;
Image img2;
public ScreenTest() {
camera = new OrthographicCamera();
camera.setToOrtho(false, appWidth, appHeight);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
img1 = new Texture("your_image1.png");
img2 = new Image(new Texture("your_image2.png"));
img2.setPosition(0, 0); // drawing from (0,0)
stage = new Stage(new StretchViewport(appWidth, appHeight, camera));
stage.addActor(img2);
}
#Override
public void render(float delta) {
batch.begin();
batch.draw(img, 0, 0);
batch.end();
stage.act();
stage.act(delta);
stage.draw();
// Also You can get touch input according to your Screen.
if (Gdx.input.isTouched()) {
System.out.println(" X " + Gdx.input.getX() * (appWidth / screenWidth));
System.out.println(" Y " + Gdx.input.getY() * (appHeight / screenHeight));
}
}
// ...
}
run this code in any type of resolution it will going to adjust in that resolution without any disturbance.