I've been trying to create a game where there's a person falling. The size of my background texture is 480x3200, and I'm trying to create the game so that the camera keeps the person in the middle of the screen while falling down, and then stops at the bottom. But I can't get my background is extend beyond the screen it starts in, and then be able to see the rest of the image.
All of my code does right now is scale down the 480x3200 image down to fit onto my current screen (which I set to be 480x800), and then as the person falls, the background doesn't change.
Here's my WorldRenderer class where I've tried to do different things but every time, I can never get the person to see a different part of the image when it starts moving down.
public WorldRenderer(SpriteBatch b, World w) {
this.world = w;
this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.position.set(CAMERA_WIDTH / 2, Person.position.y,0);
this.cam.setToOrtho(false, CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.update();
spriteBatch = b;
loadTextures();
}
public void render(float delta) {
person = world.getPerson();
moveCamera();
cam.update();
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.disableBlending();
spriteBatch.begin();
renderBackground();
spriteBatch.end();
spriteBatch.enableBlending();
spriteBatch.begin();
renderObjects();
spriteBatch.end();
}
private void moveCamera() {
cam.position.set(cam.position.x, Person.position.y, 0);
cam.update();
}
private void renderObjects() {
renderPerson();
renderBlocks();
renderPlatforms();
}
private void renderBackground() {
spriteBatch.draw(backgroundTexture, cam.position.x - CAMERA_WIDTH / 2, cam.position.y - CAMERA_HEIGHT / 2, CAMERA_WIDTH, CAMERA_HEIGHT);
}
}
Does anyone have any suggestions?
Edit:
Thanks, I changed the draw in renderBackground to
spriteBatch.draw(backgroundTexture,0,0, CAMERA_WIDTH, CAMERA_HEIGHT * 4); and it works now.
spriteBatch.draw(backgroundTexture, cam.position.x - CAMERA_WIDTH / 2,
cam.position.y - CAMERA_HEIGHT / 2, CAMERA_WIDTH, CAMERA_HEIGHT);
This code is drawing the background image relative to the camera's position. That's why changing the camera's position has no effect on the background image's position. Change it to something like this:
spriteBatch.draw(backgroundTexture,0,0);
Or u can simply use ParrallaxBackground and ParrallaxLayer class
This way u dont have to manage ur camera
Its done in an optimized manner in the mentioned class.
Related
I'm using a GestureListener to try and create a panning menu, but even though the camera's coordinates are being changed and it's being updated, nothing moves. I think it might be because the stage is drawing relative to the camera but I'm not sure how I would change that.
How I'm going about it:
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
...
gesture = new GestureDetector(this);
InputMultiplexer im = new InputMultiplexer();
im.addProcessor(gesture);
im.addProcessor(stage);
Gdx.input.setInputProcessor(im);
} //end initialization of CustomizeScreen
public void render(float delta) {
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 60f)); //0, 18, 31 for layer style
stage.draw();
Table.drawDebug(stage);
batch.setProjectionMatrix(camera.combined);
g.batch.begin();
g.font.setScale(2);
g.font.setColor(Color.WHITE);
g.font.draw(g.batch, "Coins: " + Filer.getCoins(), 15, Gdx.graphics.getHeight() - 15);
g.font.draw(g.batch, message, 0, 150);
g.batch.end();
camera.update();
}
...
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
message = "Pan, delta:" + Float.toString(deltaX) +
"," + Float.toString(deltaY);
camera.translate(deltaX, 0, 0);
camera.update();
return false;
}
I've checked for camera coordinates (camera.position.x) in the update method, so I know it's actually changing something. But all my buttons remain the same. They are placed in thirds of the screen width (Gdx.graphics.getWidth() / 3).
Am I missing something, or doing it wrong? I'd think I'm doing it correctly based on everything I'm found on Google.
Thanks :)
The Stage class has different constructors. Some of those constructors take a Viewport, which contains a Camera. If you use a constructor without Viewport, the Stage creates a new Viewport with a new Camera.
In that case it will use the created Viewport (and Camera) for all it's drawing, unless you switch the Viewport by calling setViewport.
As you don't show, how you create the Stage i am not sure if thats the porblem in your case, but if that is the problem, you can solve it by creating a Viewport with your Camera and passing it to the Stage or by changing the Camera of the Viewport (stage.getViewport().setCamera(myCamera)).
Hope it helps.
I have a bug object that I want to move across the screen as soon as the game starts. The bug starts from the bottom left of the screen and is supposed to move to the top right and stop. What I have is the bug never really gets to the top right because the game screen(X and Y) size are not equal. How do I make the bug move to that position?
This is what I have.
public void create() {
spriteBatch = new SpriteBatch();
bug = new Sprite(new Texture("EnemyBug.png"));
bug.setSize(50, 85);
bug.setPosition(0,0);
}
public void render() {
xdeg++;
ydeg++;
Gdx.gl.glClearColor(0.7f, 0.7f, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.begin();
bug.translate(xdeg, ydeg);
bug.draw(spriteBatch);
spriteBatch.end();
}
I'll assume that you know your window width (W) and height (H). First find the W / H ratio:
float ratio = screenWidth / screenHeight;
Then update your bug position accordingly:
bug.translate(ratio, 1);
This will make the sprite move through the screen diagonal.
I have been wondering how I would go by making a health bar in libgdx/java. I am looking into a Shape Renderer thinking I can use a filled shape to create a health bar, though I am not sure on how to make an approach in that direction. On the other hand I have been looking into using scene2D and NinePatches to create a healthbar for the game. I have tried to use a NinePatch/Scene2D by looking up websites on google, though it seems when I add the code I always get an issue when I try to render it to my screen. So if anybody can help me create a functional health bar in libgdx using whatever method, I would be extremely thankful. Thank you.
I cannot post pictures yet, because I have not posted 10 posts. So here is the link http://gyazo.com/6650f3d820f31c99c3f8061ebed0bdec. Sorry
I don't have any experience with Scene2D and stages but here is how i would do a simple healthbar:
Create a rectangle and fill this with a color or texture.
When a player loses HP shorten that rectangle by the same percentage as the HP lost.
Create a basic Orthographic camera with the height/width of the screen. I usually call this viewportCam.
Below all the other draw logic you change the SpriteBatch too spriteBatch(viewportCam.Combined)
Within this spritebatch you draw the healthbar.
public void Draw()
{
spriteBatch(normalCam.combined);
spriteBatch.begin();
//Normal draw logic.
spriteBatch.end();
spriteBatch(viewportCam.combined);
spriteBatch.begin();
//Draw UI elements last so the will be drawn on top of the rest.
spriteBatch.end();
}
If you draw a slightly larger rectangle behind the healthbar you have yourself a border.
You can change color depending on how much percentage health is left.
Edit
Just came across this again and currently using another method. I a ninepatch from a 1 pixel wide red gradient. health = new NinePatch(gradient, 0, 0, 0, 0) this makes sure no artifacts occur while stretching it. From here I just calculate how long it needs to be and draw it.
width = currentHealth / totalHealth * totalBarWidth;
Now you can draw it anywhere you want.
health.draw(batch, 10, 10, width, gradient.getHeight);
If you want somekind of container for it you setup a ninepatch for it and draw it before the dynamic health in the background. So let's say the container is 2 bigger at top/bottom and 5 at left/right.
container = new NinePatch(containerRegion, 5, 5, 2, 2);
//Offset it by the dynamic bar, let's say the gradient is 4 high.
container.draw(batch, 5, 8, totalBarWidth + 10, 8);
health.draw(batch, 10, 10, width, 4);
I "hardcoded" the container 5 to the left and made it 10 longer so it fits horizontally. Vertically I lowered it by 2 and made it 8 high to fit the bar perfectly.
This is how you can do it ,implement logic your self
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch batch;
int i=0;
Texture texture,texture2;
#Override
public void create () {
batch = new SpriteBatch();
initTestObjects() ;
}
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture2,100,100,300,20);
batch.draw(texture,100,100,i,20);
if(i>300)
{
i=0;
}
i++;
batch.end();
}
private void initTestObjects() {
int width =1 ;
int height = 1;
Pixmap pixmap = createProceduralPixmap(width, height,0,1,0);
Pixmap pixmap2 = createProceduralPixmap(width, height,1,0,0);
texture = new Texture(pixmap);
texture2 = new Texture(pixmap2);
}
private Pixmap createProceduralPixmap (int width, int height,int r,int g,int b) {
Pixmap pixmap = new Pixmap(width, height, Format.RGBA8888);
pixmap.setColor(r, g, b, 1);
pixmap.fill();
return pixmap;
}
}
So I'm trying to speed up some drawing we're doing (drawing a portion of an arc with alpha transparency) and was attempting to cache the entire arc into a separate bitmap, and show it selectively with an alpha mask.
From the research I've done (the Xfermodes API demo for Android, this example, and this tool), if I have for example the following two graphics:
and draw using the following:
Xfermode DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
canvas.drawBitmap(circle, 0, 0, paint);
paint.setXfermode(DST_IN);
canvas.drawBitmap(arc, 0, 0, paint);
paint.setXfermode(null);
I should get this result:
Where the destination image (the circle) is clipped to the area where the source image (the arc) is drawn. Instead, I get the full circle. If I just draw the arc, it appears in the correct location, and if I use DST_OUT instead, I get the inverse of the expected result (the other three quadrants of the circle).
I've also made sure to disable hardware rendering for this view, in case there was an issue with this Xfermode, but it doesn't make a difference.
I broke it out into a separate project at the simplest level trying to get it to work, and using the following code, I still have the same problem:
public class ClippedView extends View {
private Xfermode DST_IN, DST_OUT;
private Paint paint;
public ClippedView(Context context) {
super(context);
init();
}
private void init() {
setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
DST_OUT = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GREEN);
canvas.drawRect(0, 0, getWidth() / 2, getHeight() / 2, paint);
paint.setColor(Color.BLACK);
paint.setXfermode(DST_IN);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, paint);
paint.setXfermode(null);
}
}
Am I using it wrong? Am I just missing something? Have I found a bug? :)
There's a much cheaper and easier way to achieve this: use clipping. Canvas.clipRect() is enough. Your solution is burning a lot of fillrate. You can get the effect you want by using SRC_IN instead of DST_IN. Be careful though: it will work only in a transparent Bitmap or in layer. When you draw directly on screen, the destination is already filled by the window background.
I am new and I just start my journey with libgdx. I would like to know how I can do image.png in resolution 960x640 as background in my game? This is possible? Thx for advices and forbearance. Maybe you hava a simply tutorial?
This is my render class:
public void render() {
texture = new Texture(Gdx.files.internal("E:/background.png"));
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
}
Second question. I need to insert two active images, active means when I click on that image, the next image show me on the screen. I want to implement action when I click on that picture.
In your create() method, create a new Texture referencing your image.png, and then use your existing SpriteBatch to render it in the render() loop. Immediately after your GL.clear() call, go your batch.draw(backgroundTexture, 0. 0) and make sure you're in OrthographicProjection mode for your camera.
first you have to set the view port
do this in your create method
`float scrw = 960;
float scrh = 640;
camera = new OrthographicCamera();
camera.viewportHeight = scrh;
camera.viewportWidth = scrw;
camera.position.set(camera.viewportWidth * .5f,
camera.viewportHeight * .5f, 0f);
camera.update();`
create a texture
texture = new Texture("data/background.png");
put this texture in a sprite like this
sprite=new sprite(texture);
and then set the size like this
sprite.setsize(960,640);
and draw it in your render methods between batch.begin
and batch.end
sprite.draw(batch);