The object coordinates doesn't appear at right place - java

I had to adjust my scene coordinates to find useful gravity for my objects.
So I decided to reduce the screen coordinates so that the gravity behavior on my objects was getting ok.
But I have a problem right now, is that when I type sprite.setPosition(0,0), the sprite seems doesn't appear in the right place.
Here is my code:
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.audio.Sound;
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.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.World;
public class MyGdxGame extends ApplicationAdapter {
public OrthographicCamera camera;
Sound sound;
BitmapFont font,font2;
SpriteBatch batch;
Texture img1,img2,img3,img4,img5,img6;
Sprite sprite1,sprite2,sprite3;
World world;
Body solKose,sagKose,ustKose,altKose,body1,body2,body3;
int width=0;
float axes=0;
private int enemyGoalCounter, playerGoalCounter=0;
Sphere _player;
Sphere _enemyPlayer;
Sphere ball;
Vector2 directionVector;
Vector3 touchCoordinate;
int direction=-1;
#Override
public void create () {
camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
camera.viewportWidth = Gdx.graphics.getWidth()/100;
camera.viewportHeight = Gdx.graphics.getHeight()/100;
camera.update();
font = new BitmapFont();
font2 = new BitmapFont();
font.setColor(Color.RED);
font2.setColor(Color.BLUE);
touchCoordinate = new Vector3(0,0,0);
sound = Gdx.audio.newSound(Gdx.files.internal("taktak.wav"));
batch = new SpriteBatch();
img1 = new Texture("sphere2.png");
img2 = new Texture("sphere2.png");
img3 = new Texture("ball.png");
sprite1 = new Sprite(img1);
sprite2 = new Sprite(img2);
sprite3 = new Sprite(img3);
sprite1.setPosition(0,0);
sprite2.setPosition(0,0);
world = new World(new Vector2(0, 0),true);
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(sprite1.getX()/2,sprite1.getY()/2);
body1 = world.createBody(bodyDef);
CircleShape shape = new CircleShape();
shape.setRadius(1f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.restitution=0.6f;
body1.createFixture(fixtureDef);
shape.dispose();
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.DynamicBody;
bodyDef2.position.set(sprite2.getX()/2,sprite2.getY()/2);
body2 = world.createBody(bodyDef2);
CircleShape shape2 = new CircleShape();
shape2.setRadius(1f);
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = shape2;
fixtureDef.restitution=0.6f;
body2.createFixture(fixtureDef2);
shape2.dispose();
}
#Override
public void render () {
System.out.println();
camera.update();
play();
inputController(); // A function for keyboard input controlling
math(); // For Collision controlling
world.step(1f/60f, 6, 2);
sprite1.setPosition(body1.getPosition().x,body1.getPosition().y);
sprite2.setPosition(body2.getPosition().x,body2.getPosition().y);
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(sprite1,sprite1.getX(),sprite1.getY(),2,2);
batch.draw(sprite2,sprite2.getX(),sprite2.getY(),2,2);
batch.end();
}
#Override
public void dispose () {
batch.dispose();
world.dispose();
}
void play() {
}
void inputController() {
if(Gdx.input.isTouched()){
Vector2 directionVector = new Vector2(0,0);
touchCoordinate.x = Gdx.input.getX();
touchCoordinate.y = Gdx.input.getY();
camera.unproject(touchCoordinate);
double distance = Math.pow(sprite1.getWidth()/2,2)-(Math.pow((sprite1.getOriginX()-touchCoordinate.x),2)+Math.pow((sprite1.getOriginY()-touchCoordinate.y),2));
System.out.println(touchCoordinate);
if(distance>0){
body1.applyForceToCenter(20,20,true);
}else if(distance==0){
body1.applyForceToCenter(20,20,true);
}else{
////
}
}
//_player.setCenterPosition(touchCoordinate.x,touchCoordinate.y);
}
void math() {
goalSystem();
}
void restartPositions(){
}
void goalSystem() {
/*
if(!goal) {
if(ball.getCenterPosition(ball.position.x, ball.position.y).y < 20) {
if((ball.getCenterPosition(ball.position.x, ball.position.y).x >= Gdx.graphics.getWidth()/2-325/2) && (ball.getCenterPosition(ball.position.x, ball.position.y).x <= Gdx.graphics.getWidth()/2+325/2)) {
goal=true;
enemyGoalCounter++;
restartPositions();
}
}
if(ball.getCenterPosition(ball.position.x, ball.position.y).y > Gdx.graphics.getHeight()-20) {
if((ball.getCenterPosition(ball.position.x, ball.position.y).x >= Gdx.graphics.getWidth()/2-325/2) && (ball.getCenterPosition(ball.position.x, ball.position.y).x <= Gdx.graphics.getWidth()/2+325/2)) {
goal=true;
playerGoalCounter++;
restartPositions();
}
}
}
*/
}
public class Sphere{
Vector2 firstPos,firstDirection;
float firstSpeed;
Vector2 position, direction,centerPosition;
float x,y,width,height;
float radius;
float xCenter,yCenter;
float speed;
float velocity;
public Sphere(float x, float y, float radius, float width, float height) {
this.x = x;
this.y = y;
this.radius = radius;
this.width = width;
this.height = height;
this.position = new Vector2(x,y);
this.direction = new Vector2(x,y);
this.speed = 0;
this.firstSpeed = speed;
this.firstPos = new Vector2(x,y);
this.firstDirection = new Vector2(x,y);
}
Vector2 getCenterPosition(float x, float y) {
centerPosition = new Vector2(x+width/2,y);
return centerPosition;
}
void setCenterPosition(float x, float y){
position.x = x-width/2;
position.y = y-height/2;
}
void setSpeed(float speed) {
this.speed = speed;
}
float getSpeed() {
return this.speed;
}
}
}
Image:

I think the issue is the camera and viewport not a rendered position issue. Your code to set the camera and viewport can be changed. If you are using viewports -You- decide the coordinate range for rendering, its arbitary. This rendering is -then- scaled as you like to fit the screen. In your case you get the width and height of the device (which is not constant across devices even aspect ratio changes) before setting your own viewport parameters?
So try instead
camera = new OrthographicCamera(100, 500); //You pick as you like
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0); //centre camera
viewport = new FitViewport(camera.viewportWidth, camera.viewportHeight, camera);//stretch proportionally
Read this as well
How Camera works in Libgdx and together with Viewport
(Also you didn't add the offset to y here.
Vector2 getCenterPosition(float x, float y) {
centerPosition = new Vector2(x+width/2,y);
....
)

Related

Why the laser line is just one, when should be 4 of them.why it's going from just PlayerShip and no from EnemyShip?

I make a game called Space Shooter. I added the lasers to both ships and put the Laser into LinkedList but when I run the game the laser is going on from one side of the player ship. Where are the other 3 lasers what should be on the sides. You can see what I mean in the photo below. I've already check the code twice but can't find what's wrong.
class GameScreen implements Screen {
//screen
private Camera camera;
private Viewport viewport;
//graphics
private SpriteBatch batch;
private TextureAtlas textureAtlas;
private TextureRegion[] backgrounds;
private float backgroundHeight; //height of background in World units
private TextureRegion playerShipTextureRegion, playerShieldTextureRegion,
enemyShipTextureRegion, enemyShieldTextureRegion,
playerLaserTextureRegion, enemyLaserTextureRegion;
//timing
private float[] backgroundOffsets = {0, 0, 0, 0};
private float backgroundMaxScrollingSpeed;
//world parameters
private final int WORLD_WIDTH = 72;
private final int WORLD_HEIGHT = 128;
//game objects
private Ship playerShip;
private Ship enemyShip;
private LinkedList<Laser>PlayerLaserList;
private LinkedList<Laser>EnemyLaserList;
GameScreen() {
camera = new OrthographicCamera();
viewport = new StretchViewport(WORLD_WIDTH, WORLD_HEIGHT, camera);
//set up the texture atlas
textureAtlas = new TextureAtlas("images.atlas");
//setting up the background
backgrounds = new TextureRegion[4];
backgrounds[0] = textureAtlas.findRegion("Starscape00");
backgrounds[1] = textureAtlas.findRegion("Starscape01");
backgrounds[2] = textureAtlas.findRegion("Starscape02");
backgrounds[3] = textureAtlas.findRegion("Starscape03");
backgroundHeight = WORLD_HEIGHT * 2;
backgroundMaxScrollingSpeed = (float) (WORLD_HEIGHT) / 4;
//initialize texture regions
playerShipTextureRegion = textureAtlas.findRegion("playerShip2_red");
enemyShipTextureRegion = textureAtlas.findRegion("enemyBlack2");
playerShieldTextureRegion = textureAtlas.findRegion("shield2");
enemyShieldTextureRegion = textureAtlas.findRegion("shield1");
enemyShieldTextureRegion.flip(false, true);
playerLaserTextureRegion= textureAtlas.findRegion("laserGreen15");
enemyLaserTextureRegion= textureAtlas.findRegion("laserRed03");
//set up game objects
playerShip = new PlayerShip(2, 3, 10, 10,
WORLD_WIDTH/2, WORLD_HEIGHT/4,2f,3,1,
0.05f, playerShipTextureRegion,playerShieldTextureRegion,playerLaserTextureRegion);
enemyShip = new EnemyShip(2, 1, 10, 10,
WORLD_WIDTH/2, WORLD_HEIGHT*4/5,0.3f,3,1,0.8f
, enemyShipTextureRegion,enemyShieldTextureRegion,enemyLaserTextureRegion);
PlayerLaserList = new LinkedList<>();
EnemyLaserList = new LinkedList<>();
batch = new SpriteBatch();
}
#Override
public void render(float deltaTime) {
batch.begin();
playerShip.update(deltaTime);
enemyShip.update(deltaTime);
//scrolling background
renderBackground(deltaTime);
//enemy ships
enemyShip.draw(batch);
//player ship
playerShip.draw(batch);
//lasers
//create new Laser
//player lasr
if (playerShip.canFireLaser()) {
Laser[] lasers = playerShip.fireLaser();
for (Laser laser: lasers) {
PlayerLaserList.add(laser);
}
}
//enemy lasers
if (enemyShip.canFireLaser()) {
Laser[] lasers = enemyShip.fireLaser();
for (Laser laser: lasers) {
EnemyLaserList.add(laser);
}
}
//draw the Lasers
//remove old Laser
ListIterator<Laser> iterator = PlayerLaserList.listIterator();
while(iterator.hasNext()) {
Laser laser = iterator.next();
laser.draw(batch);
laser.yPosition += laser.movementSpeed*deltaTime;
if (laser.yPosition > WORLD_HEIGHT) {
iterator.remove();
}
}
//enemy lsaer list
iterator = EnemyLaserList.listIterator();
while(iterator.hasNext())
{
Laser laser = iterator.next();
laser.draw(batch);
laser.yPosition -= laser.movementSpeed*deltaTime;
if(laser.yPosition + laser.height < 0)
{
iterator.remove();
}
}
//explosions
batch.end();
}
package com.mygdx.game;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
class EnemyShip extends Ship
{
public EnemyShip(float movementSpeed, int shield, float width, float height, float xCentre, float yCentre,
float laserWidth, float laserHeight, float laserMovementSpeed, float timeBetweenShoots,
TextureRegion shipTexture, TextureRegion shieldTexture, TextureRegion laserTextureRegion) {
super(movementSpeed, shield, width, height, xCentre, yCentre, laserWidth, laserHeight, laserMovementSpeed,
timeBetweenShoots, shipTexture, shieldTexture, laserTextureRegion);
}
#Override
public Laser[] fireLaser() {
Laser[] laser = new Laser[2];
laser[0] = new Laser(xPosition + width * 0.18f, yPosition - laserHeight,
laserWidth, laserHeight,
laserMovementSpeed, laserTextureRegion);
laser[1] = new Laser(xPosition + width * 0.82f, yPosition - laserHeight,
laserWidth, laserHeight,
laserMovementSpeed, laserTextureRegion);
timeSinceLastShoot = 0;
return laser;
}
#Override
public void draw(Batch batch) {
batch.draw(shipTexture, xPosition, yPosition, width, height);
if (shield > 0) {
batch.draw(shieldTexture, xPosition, yPosition-height*0.2f, width, height);
}
}
package com.mygdx.game;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class Laser
{
float movementSpeed;
//position and dimension
float xPosition, yPosition;
float width, height;
//graphics
TextureRegion textureRegion;
public Laser(float movementSpeed, float xPosition, float yPosition, float width, float height, TextureRegion textureRegion) {
this.movementSpeed = movementSpeed;
this.xPosition = xPosition;
this.yPosition = yPosition+33;
this.width = width;
this.height = height;
this.textureRegion = textureRegion;
}
public void draw(Batch batch)
{
batch.draw(textureRegion,xPosition,yPosition,width,height);
}
}package com.mygdx.game;
package com.mygdx.game;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
class PlayerShip extends Ship {
public PlayerShip(float movementSpeed, int shield, float width, float height, float xCentre, float yCentre,
float laserWidth, float laserHeight, float laserMovementSpeed, float timeBetweenShoots,
TextureRegion shipTexture, TextureRegion shieldTexture, TextureRegion laserTextureRegion) {
super(movementSpeed, shield, width, height, xCentre, yCentre, laserWidth, laserHeight, laserMovementSpeed,
timeBetweenShoots, shipTexture, shieldTexture, laserTextureRegion);
}
public Laser[] fireLaser()
{
Laser[] laser = new Laser[2];
laser[0] = new Laser(xPosition + width * 0.07f, yPosition + height * 0.45f,
laserHeight, laserWidth ,
laserMovementSpeed, laserTextureRegion);
laser[1] = new Laser(xPosition + width * 0.93f, yPosition + height * 0.45f,
laserHeight, laserWidth,
laserMovementSpeed, laserTextureRegion);
timeSinceLastShoot = 0;
return laser;
}
}

How to add background image in libgdx?

I want to add a background like blockbunny and I have a background image image in my assets/images folder under the android folder. I have tried to separate the image into three sections and add it as sky, clouds and mountains in Background class. For some reason, it is throwing null pointer exception because spritebatch is null in MyMainGame class. I have initialised SpriteBatch in create method of MyMainGame class.
Here is my MyMainGame.class
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.mygdx.manager.Content;
import com.mygdx.manager.GameInputProcessor;
import com.mygdx.manager.GameStateManager;
import com.mygdx.manager.MyInput;
import javafx.scene.layout.Background;
import static com.mygdx.manager.Box2DVariables.PPM;
public class MyMainGame implements ApplicationListener {
SpriteBatch batch;
Texture img;
public static final int Width=320;
public static final int Height=240;
public static final int SCALE=2;
public static final float STEP= 1/60f; //60 frames per second
private float accumulator;
private SpriteBatch sb;
protected OrthographicCamera cam;
protected OrthographicCamera hud;
private Texture tex;
private Background[] backgrounds;
private GameStateManager gsm;
public SpriteBatch getSb() {
return sb;
}
public OrthographicCamera getCam() {
return cam;
}
public OrthographicCamera getHud() {
return hud;
}
public static Content con;
#Override
public void create () {
Gdx.input.setInputProcessor(new GameInputProcessor());
con=new Content();
con.loadTexture("images//sprite.jpg","sprite");
con.loadTexture("images//background.png","background");
gsm=new GameStateManager(this);
sb=new SpriteBatch();
cam=new OrthographicCamera(160,120);
cam.setToOrtho(false,Width/2,Height/2);
hud=new OrthographicCamera();
hud.setToOrtho(false,Width/2,Height/2);
}
#Override
public void render () {
cam.update();
hud.update();
accumulator +=Gdx.graphics.getDeltaTime();
while(accumulator>=STEP){
accumulator-=STEP;
gsm.update(STEP);
gsm.render();
MyInput.update();
}
}
public void resize(int width,int height){
sb.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
}
public void dispose(){
con.disposeTexture("sprite");
con.disposeTexture("background");
}
public void pause(){
}
public void resume(){
gsm.setState(GameStateManager.PLAY);
}
}
GameState is an abstract class containing unimplemented methods
package com.mygdx.gamestate;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.mygdx.game.MyMainGame;
import com.mygdx.manager.GameStateManager;
public abstract class GameState {
protected GameStateManager gsm;
protected MyMainGame game;
protected SpriteBatch sb;
protected OrthographicCamera cam;
protected OrthographicCamera hud;
protected GameState(GameStateManager gsm){
this.gsm=gsm;
game=gsm.game();
sb=game.getSb();
cam=game.getCam();
hud=game.getHud();
init();
}
public abstract void init();
public abstract void update(float dt);
public abstract void draw();
public abstract void render();
public abstract void handleInput();
public abstract void dispose();
}
The Play class is extending GameState class
public class Play extends GameState{
// private BitmapFont font=new BitmapFont();
private World world;
private Body playerBody;
private int viewportWidth= 10 * 32 ;
int viewportHeight= 8 * 32 ;
private Box2DDebugRenderer b2d;
private OrthographicCamera B2DCAM;
private TiledMap tileMap;
private OrthogonalTiledMapRenderer orthomap;
private MyContactListener cl;
private float tileSize;
private Background[] backgrounds;
private Texture back;
//file name
private final String LEVEL_1 ="maps/tilemap1.tmx";
public Play(GameStateManager gsm) {
super(gsm);
//setup box2d
world=new World(new Vector2(0,-9.8f),true);
cl=new MyContactListener();
world.setContactListener(cl);
sb=new SpriteBatch(1000);
//cam=new OrthographicCamera();
b2d=new Box2DDebugRenderer();
//create Player
createPlayer();
//create Tiles
createTiles();
orthomap = new OrthogonalTiledMapRenderer(tileMap,1/32f);
//setup Box2D Cam
B2DCAM=new OrthographicCamera();
B2DCAM.setToOrtho(false, MyMainGame.Width/PPM,MyMainGame.Height/PPM);
cam=new OrthographicCamera();
cam.setToOrtho(false,10,7);
back = MyMainGame.con.getTexture("background");
TextureRegion sky = new TextureRegion(back, 0, 0, 320, 240);
TextureRegion clouds = new TextureRegion(back, 0, 240, 320, 240);
TextureRegion mountains = new TextureRegion(back, 0, 480, 320, 240);
backgrounds = new Background[3];
backgrounds[0] = new Background(sky,cam, 0f);
backgrounds[1] = new Background(clouds, cam, 0.1f);
backgrounds[2] = new Background(mountains, cam, 0.2f);
/* //TODO - remove me
File file = new File(LEVEL_1);
if(file.exists())
System.out.println("file exists");*/
}
#Override
public void init() {
}
#Override
public void update(float dt) {
handleInput();
world.step(dt,6,2);
MyMainGame.con.getTexture("sprite");
for (Background b : backgrounds) {
b.update(dt);
}
}
#Override
public void draw() {
}
#Override
public void render() {
//clear screen
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
//
cam.position.set(playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2,0);
// cam.setToOrtho(false,playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2);
//cam.setPosition(playerBody.getPosition().x * PPM +MyMainGame.Width / 4, MyMainGame.Height / 2);
cam.setToOrtho(false,10,7);
cam.update();
sb.setProjectionMatrix(cam.combined);
for(int i = 0; i < backgrounds.length; i++) {
backgrounds[i].render(sb);
}
orthomap.setView(cam);
orthomap.render();
b2d.render(world,B2DCAM.combined);
}
#Override
public void handleInput() {
if(MyInput.isPressed((MyInput.SPACE))){
System.out.println("space pressed");
if(cl.isPlayerOnGround())
System.out.println(cl.isPlayerOnGround());
playerBody.applyForceToCenter(0,200,true);
}
}
#Override
public void dispose() {
world.dispose();
b2d.dispose();
tileMap.dispose();
orthomap.dispose();
}
private void createPlayer(){
BodyDef bodydef=new BodyDef();
FixtureDef fixdef=new FixtureDef();
PolygonShape shape=new PolygonShape();
//create player
bodydef.position.set(160/PPM,200/PPM);
bodydef.type= BodyDef.BodyType.DynamicBody;
playerBody=world.createBody(bodydef);
shape.setAsBox(5/PPM,5/PPM);
fixdef.shape=shape;
fixdef.filter.categoryBits= BIT_PLAYER;
fixdef.filter.maskBits=Box2DVariables.BIT_BLUE;
playerBody.createFixture(fixdef).setUserData("PLAYER");
//create foot sensor
shape.setAsBox(2/PPM,2/PPM,new Vector2(0,-5/PPM),0);
fixdef.shape=shape;
fixdef.filter.categoryBits= BIT_PLAYER;
fixdef.filter.maskBits=Box2DVariables.BIT_BLUE;
fixdef.isSensor=true;
playerBody.createFixture(fixdef).setUserData("FOOT");
}
private void createTiles(){
//load tile map
tileMap = new TmxMapLoader().load(LEVEL_1);
//orthomap = new OrthogonalTiledMapRenderer(tileMap,1);
tileSize=(int)tileMap.getProperties().get("tilewidth", Integer.class);
System.out.println("Tile Size " +tileSize);
TiledMapTileLayer layer;
layer=(TiledMapTileLayer)tileMap.getLayers().get("Blue");
createLayer(layer,Box2DVariables.BIT_BLUE);
layer=(TiledMapTileLayer)tileMap.getLayers().get("Green");
createLayer(layer,Box2DVariables.BIT_GREEN);
layer=(TiledMapTileLayer)tileMap.getLayers().get("Red");
createLayer(layer,Box2DVariables.BIT_RED);
System.out.println("Layer Height " +layer.getHeight());
System.out.println("Layer Width " +layer.getWidth());
}
private void createLayer(TiledMapTileLayer layer,short bits){
BodyDef bodydef=new BodyDef();
FixtureDef fixdef=new FixtureDef();
//go through cells in layer
for(int row=0;row<layer.getHeight();row++){
for(int col=0;col<layer.getWidth();col++){
//get cells
TiledMapTileLayer.Cell cell=layer.getCell(col,row);
//check if cell exists
if(cell==null) continue;
if(cell.getTile()==null) continue;
//create body and fixture from cell
bodydef.type= BodyDef.BodyType.StaticBody;
bodydef.position.set((col+0.5f)*tileSize/PPM,(row+0.5f)*tileSize/PPM);
ChainShape cs=new ChainShape();
Vector2[] v=new Vector2[3];
//bottom left
v[0]=new Vector2(-tileSize/2/PPM,-tileSize/2/PPM);
//top left
v[1]=new Vector2(-tileSize/2/PPM,tileSize/2/PPM);
//top right corner
v[2]=new Vector2(tileSize/2/PPM,tileSize/2/PPM);
cs.createChain(v);
fixdef.friction=0;
fixdef.shape =cs;
fixdef.filter.categoryBits=Box2DVariables.BIT_BLUE;
fixdef.filter.maskBits=BIT_PLAYER;
fixdef.isSensor=false;
world.createBody(bodydef).createFixture(fixdef);
}
}
}
}
I have loaded the Texture in MyMainClass.java and it is stored in HashMap in Content class
I am getting the background image as Texture named 'back', and seperating them as TextureRegions sky,clouds and mountains in Play constructor of Play class and passing them in Background class.
TextureRegion sky = new TextureRegion(back, 0, 0, 320, 240);
TextureRegion clouds = new TextureRegion(back, 0, 240, 320, 240);
TextureRegion mountains = new TextureRegion(back, 0, 480, 320, 240);
backgrounds = new Background[3];
backgrounds[0] = new Background(sky,cam, 0f);
backgrounds[1] = new Background(clouds, cam, 0.1f);
backgrounds[2] = new Background(mountains, cam, 0.2f);
Background class
package com.mygdx.manager;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.mygdx.game.MyMainGame;
public class Background {
private TextureRegion image;
private OrthographicCamera camera;
private float scale;
private float x;
private float y;
private int drawX;
private int drawY;
private float dx;
private float dy;
public Background(TextureRegion image, OrthographicCamera camera, float scale) {
this.image = image;
this.camera = camera;
this.scale = scale;
drawX = MyMainGame.Width / image.getRegionWidth() + 1;
drawY = MyMainGame.Height / image.getRegionHeight() + 1;
System.out.println("Image width"+image.getRegionWidth());
System.out.println("Image height"+image.getRegionHeight());
}
public void setVector(float dx, float dy) {
this.dx = dx;
this.dy = dy;
}
public void update(float ts) {
x += (dx * scale) * ts;
y += (dy * scale) * ts;
}
public void render(SpriteBatch sb) {
float x = ((this.x + camera.viewportWidth / 2 - camera.position.x) * scale) % image.getRegionWidth();
float y = ((this.y + camera.viewportHeight / 2 - camera.position.y) * scale) % image.getRegionHeight();
sb.begin();
int colXOffset = x > 0 ? -1 : 0;
int rowYOffset = y > 0 ? -1 : 0;
for (int rowY = 0; rowY < drawY; rowY++) {
for (int colX = 0; colX < drawX; colX++) {
sb.draw(image, x + (colX + colXOffset) * image.getRegionWidth(), y + (rowY + rowYOffset) * image.getRegionHeight());
}
}
sb.end();
}
}
I am getting an error in Play class in render method as null pointer exception.Dont really know whats going on! sb.setProjectionMatrix is giving nullpointer exception!
public void render() {
//clear screen
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
//
cam.position.set(playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2,0);
// cam.setToOrtho(false,playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2);
//cam.setPosition(playerBody.getPosition().x * PPM +MyMainGame.Width / 4, MyMainGame.Height / 2);
cam.setToOrtho(false,10,7);
cam.update();
sb.setProjectionMatrix(cam.combined);
for(int i = 0; i < backgrounds.length; i++) {
backgrounds[i].render(sb);
}
orthomap.setView(cam);
orthomap.render();
b2d.render(world,B2DCAM.combined);
}
How do I split the background image and add it as shown above in my Game?

How can an object get destroyed through the camera sight? [duplicate]

This question already has an answer here:
How to make player get destroyed through camera?
(1 answer)
Closed 5 years ago.
I've been having some trouble making the player get destroyed through the camera. In my application, I made the camera follow the player(the ball). But the camera can only follow the ball upwards. So what I want to accomplish is, when the player(the ball) reaches the bottom of the interface(the screen) it gets destroyed. After it gets destroyed it would be good, if a new activity(new screen) pops up, that says "Game over". Thanks a lot for the great support. Please take a look at the interface of the application.
package com.luca.tuninga;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.utils.viewport.Viewport;
public class MyGdxGame extends ApplicationAdapter {
public static float APP_FPS = 60f;
public static int V_WIDTH = 480;
public static int V_HEIGHT = 640;
Box2DDebugRenderer b2dr;
World world;
Body ballBody;
OrthographicCamera camera;
float cameraMaxY;
#Override
public void create() {
world = new World(new Vector2(0, -9.8f), false);
b2dr = new Box2DDebugRenderer();
camera = new OrthographicCamera();
camera.setToOrtho(false, V_WIDTH, V_HEIGHT);
cameraMaxY = camera.position.y;
ballBody = createBall();
createWalls();
}
private void update() {
world.step(1f / APP_FPS, 6, 2);
if (Gdx.input.isTouched()) {
ballBody.setLinearVelocity(0, MathUtils.clamp(ballBody.getLinearVelocity().y, 0, 3));
ballBody.applyForceToCenter(new Vector2(0, 650f), false);
}
if (ballBody.getPosition().y * 32 > cameraMaxY) {
camera.translate(0, (ballBody.getPosition().y * 32) - cameraMaxY);
camera.update();
cameraMaxY = camera.position.y;
}
}
#Override
public void render() {
Gdx.gl.glClearColor(.25f, .25f, .25f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
update();
b2dr.render(world, camera.combined.cpy().scl(32f));
}
#Override
public void dispose() {
super.dispose();
world.dispose();
}
private Body createBall() {
Body body;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.DynamicBody;
def.fixedRotation = true;
def.position.set(camera.position.x/ 32 + .5f, camera.position.y/ 32);
def.position.set(camera.position.x, camera.position.y);
def.gravityScale = 3;
CircleShape shape = new CircleShape();
shape.setRadius(0.5f);
body = world.createBody(def);
body.createFixture(shape, 1.0f);
return body;
}
private void createWalls() {
Body body;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.StaticBody;
def.fixedRotation = true;
PolygonShape shape = new PolygonShape();
shape.setAsBox(1, 200 / 32);
for(int i = 0; i < 20 ; i++) {
def.position.set(1.01f, i * (200 / 32));
body = world.createBody(def);
body.createFixture(shape, 1.0f);
def.position.set(V_WIDTH / 32 - 1, i * (200 / 32));
body = world.createBody(def);
body.createFixture(shape, 1.0f);
}
}
}
#Override
public void render() {
Gdx.gl.glClearColor(.25f, .25f, .25f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (ballBody.getPosition().y < camera.position.y){
destroyBall();
} else if (ballBody.getPosition().y > camera.position.y + 300){
camera.position.set(ballBody.getPosition().y - 300);
}
update();
b2dr.render(world, camera.combined.cpy().scl(32f));
}
I hope this works. You can write destroyBall() method yourself.

LIBGDX horizontal and vertical parallax background

Im trying to do a little game in LibGdx, right now i have a spaceship that can move with a touchpad in every directions and the camera follows it.
Im tryng to accomplish a parallax background made of stars that moves depending of where the spaceship is going.
Here it is the code, Im giving you all the class just to be sure to not mess up, for im new with this programming code.
public class TouchPadTest extends OrthographicCamera implements ApplicationListener {
public static final int WIDTH=480;
public static final int HEIGHT=800;
private OrthographicCamera camera;
private Stage stage;
private SpriteBatch batch;
private Touchpad touchpad;
private TouchpadStyle touchpadStyle;
private Skin touchpadSkin;
private Drawable touchBackground;
private Drawable touchKnob;
private Texture blockTexture;
private Sprite blockSprite;
private float blockSpeed;
public void create() {
batch = new SpriteBatch();
//Create camera
float aspectRatio = (float) Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, TouchPadTest.WIDTH, TouchPadTest.HEIGHT);
//Create a touchpad skin
touchpadSkin = new Skin();
//Set background image
touchpadSkin.add("touchBackground", new Texture("data/touchBackground.png"));
//Set knob image
touchpadSkin.add("touchKnob", new Texture("data/touchKnob.png"));
//Create TouchPad Style
touchpadStyle = new TouchpadStyle();
//Create Drawable's from TouchPad skin
touchBackground = touchpadSkin.getDrawable("touchBackground");
touchKnob = touchpadSkin.getDrawable("touchKnob");
//Apply the Drawables to the TouchPad Style
touchpadStyle.background = touchBackground;
touchpadStyle.knob = touchKnob;
//Create new TouchPad with the created style
touchpad = new Touchpad(10, touchpadStyle);
//setBounds(x,y,width,height)
touchpad.setBounds(15, 15, 200, 200);
//Create a Stage and add TouchPad
stage = new Stage(new FitViewport(Gdx.graphics.getWidth(),Gdx.graphics.getHeight()));
stage.addActor(touchpad);
Gdx.input.setInputProcessor(stage);
//Create block sprite
blockTexture = new Texture(Gdx.files.internal("data/shuttle2.png"));
blockSprite = new Sprite(blockTexture);
//Set position to centre of the screen
blockSprite.setPosition(Gdx.graphics.getWidth()/2-blockSprite.getWidth()/2, Gdx.graphics.getHeight()/2-blockSprite.getHeight()/2);
blockSpeed=5;
}
public void movePlayer(){
Vector2 v = new Vector2(touchpad.getKnobPercentX(), touchpad.getKnobPercentY());
float angle = v.angle();
if (touchpad.isTouched()){
blockSprite.setRotation(angle);
}
blockSprite.setX(blockSprite.getX() + touchpad.getKnobPercentX()*blockSpeed);
blockSprite.setY(blockSprite.getY() + touchpad.getKnobPercentY()*blockSpeed);
//Draw
camera.position.set(blockSprite.getX() + blockSprite.getWidth() / 2, blockSprite.getY() + blockSprite.getHeight() / 2, 0);
camera.update();
batch.setProjectionMatrix(camera.combined);
}
public void renderBackground() {
//---------------PARALLAX BACKGROUND---------------------//
}
public void dispose() {
}
public void render() {
Gdx.gl.glClearColor(0/255f,5/255f,15/255f,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//Move blockSprite with TouchPad
movePlayer();
batch.begin();
renderBackground();
blockSprite.draw(batch);
batch.end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void resize(int width, int height) {
}
}
For a better exemple, this is the kind of result that i want to achieve: https://www.youtube.com/watch?v=zA91SaOR-Io, if you can help me it will be amazing. Thank You.
This working example of a 3 layer parallax background was adapted from the LibGdx Parallax test and should give you an idea on how to implement a parallax effect. The three images used are all 1024x1024px.
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
public class Test extends ApplicationAdapter implements InputProcessor{
private SpriteBatch batch;
private ParallaxCamera camera;
private Texture bgClose;
private Texture bgMid;
private Texture bgFar;
final Vector3 curr = new Vector3();
final Vector3 last = new Vector3(-1, -1, -1);
final Vector3 delta = new Vector3();
#Override
public void create () {
bgClose = new Texture(Gdx.files.internal("starbg-close.png"));
bgMid = new Texture(Gdx.files.internal("starbg-mid.png"));
bgFar = new Texture(Gdx.files.internal("starbg-far.png"));
camera = new ParallaxCamera(1920,1080);
batch = new SpriteBatch();
Gdx.input.setInputProcessor(this);
}
#Override
public void render () {
//clear screen
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// background layer, no parallax, centered around origin
batch.setProjectionMatrix(camera.calculateParallaxMatrix(0, 0));
batch.disableBlending();
batch.begin();
batch.draw(bgFar, -(int)(bgFar.getWidth() / 2), -(int)(bgFar.getHeight() / 2));
batch.end();
batch.enableBlending();
batch.setProjectionMatrix(camera.calculateParallaxMatrix(0.25f, 0.25f));
batch.begin();
for (int i = 0; i < 9; i++) {
batch.draw(bgMid, i * bgClose.getWidth() - 512, -512);
}
batch.end();
batch.setProjectionMatrix(camera.calculateParallaxMatrix(.5f, .5f));
batch.begin();
for (int i = 0; i < 9; i++) {
batch.draw(bgClose, i * bgClose.getWidth() - 512, -512);
}
batch.end();
}
//.. omitted empty methods ..//
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
last.set(-1, -1, -1);
return false;
}
#Override
public boolean touchDragged(int x, int y, int pointer) {
camera.unproject(curr.set(x, y, 0));
if (!(last.x == -1 && last.y == -1 && last.z == -1)) {
camera.unproject(delta.set(last.x, last.y, 0));
delta.sub(curr);
camera.position.add(delta.x, delta.y, 0);
}
last.set(x, y, 0);
return false;
}
private class ParallaxCamera extends OrthographicCamera {
Matrix4 parallaxView = new Matrix4();
Matrix4 parallaxCombined = new Matrix4();
Vector3 tmp = new Vector3();
Vector3 tmp2 = new Vector3();
public ParallaxCamera (float viewportWidth, float viewportHeight) {
super(viewportWidth, viewportHeight);
}
public Matrix4 calculateParallaxMatrix (float parallaxX, float parallaxY) {
update();
tmp.set(position);
tmp.x *= parallaxX;
tmp.y *= parallaxY;
parallaxView.setToLookAt(tmp, tmp2.set(tmp).add(direction), up);
parallaxCombined.set(projection);
Matrix4.mul(parallaxCombined.val, parallaxView.val);
return parallaxCombined;
}
}
}

libgdx why doesn't the Camera follow the character?

I'm new with libgdx and I have read a Tutorial (the Tutorial Code is my base).
I have a character that I can move, but the camera won't follow the character :(
Here's my WorldRenderer.java:
package com.evolutio.tee.view;
import com.evolutio.tee.model.Block;
import com.evolutio.tee.model.Tee;
import com.evolutio.tee.model.World;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
public class WorldRenderer {
private static final float CAMERA_WIDTH = 10f;
private static final float CAMERA_HEIGHT = 7f;
private World world;
private OrthographicCamera cam;
/** for debug rendering **/
ShapeRenderer debugRenderer = new ShapeRenderer();
/** Textures **/
private Texture teeTexture;
private Texture blockTexture;
private SpriteBatch spriteBatch;
private boolean debug = false;
private int width;
private int height;
private float ppuX; // pixels per unit on the X axis
private float ppuY; // pixels per unit on the Y axis
public void setSize (int w, int h) {
this.width = w;
this.height = h;
ppuX = (float)width / CAMERA_WIDTH;
ppuY = (float)height / CAMERA_HEIGHT;
}
public WorldRenderer(World world, boolean debug) {
Tee tee = world.getTee();
this.world = world;
cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
cam.position.set(CAMERA_WIDTH / 2f, CAMERA_HEIGHT / 2f, 0);
cam.update();
this.debug = debug;
spriteBatch = new SpriteBatch();
loadTextures();
}
private void loadTextures() {
teeTexture = new Texture(Gdx.files.internal("tee/tee.png"));
blockTexture = new Texture(Gdx.files.internal("world/dreck.png"));
}
public void render() {
spriteBatch.begin();
drawBlocks();
drawTee();
spriteBatch.end();
//if (debug) drawDebug();
}
private void drawBlocks() {
for (Block block : world.getBlocks()) {
spriteBatch.draw(blockTexture, block.getPosition().x * ppuX, block.getPosition().y * ppuY, Block.SIZE * ppuX, Block.SIZE * ppuY);
}
}
private void drawTee() {
Tee tee = world.getTee();
spriteBatch.draw(teeTexture, tee.getPosition().x * ppuX, tee.getPosition().y * ppuY, Tee.SIZE * ppuX, Tee.SIZE * ppuY);
cam.position.set(tee.getPosition().x, tee.getPosition().y, 0);
}
private void drawDebug() {
// 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 Tee
Tee tee = world.getTee();
Rectangle rect = tee.getBounds();
float x1 = tee.getPosition().x + rect.x;
float y1 = tee.getPosition().y + rect.y;
debugRenderer.setColor(new Color(0, 1, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
debugRenderer.end();
}
}
at drawTee() I try to make the camera following the Tee.
cam.position.set(tee.getPosition().x, tee.getPosition().y, 0);
Try this
public class WorldRenderer {
private static final float CAMERA_WIDTH = 10f;
private static final float CAMERA_HEIGHT = 7f;
private World world;
private OrthographicCamera cam;
/** for debug rendering **/
ShapeRenderer debugRenderer = new ShapeRenderer();
/** Textures **/
private Texture teeTexture;
private Texture blockTexture;
private SpriteBatch spriteBatch;
private boolean debug = false;
private int width;
private int height;
private float ppuX; // pixels per unit on the X axis
private float ppuY; // pixels per unit on the Y axis
public void setSize (int w, int h) {
this.width = w;
this.height = h;
ppuX = (float)width / CAMERA_WIDTH;
ppuY = (float)height / CAMERA_HEIGHT;
}
public WorldRenderer(World world, boolean debug) {
Tee tee = world.getTee();
this.world = world;
this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.setToOrtho(false,CAMERA_WIDTH,CAMERA_HEIGHT);
this.cam.position.set(CAMERA_WIDTH / 2f, CAMERA_HEIGHT / 2f, 0);
this.cam.update();
this.debug = debug;
spriteBatch = new SpriteBatch();
loadTextures();
}
private void loadTextures() {
teeTexture = new Texture(Gdx.files.internal("tee/tee.png"));
blockTexture = new Texture(Gdx.files.internal("world/dreck.png"));
}
public void render() {
moveCamera(tee.getPosition().x, CAMERA_HEIGHT / 2);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
drawBlocks();
drawTee();
spriteBatch.end();
//if (debug) drawDebug();
}
public void moveCamera(float x,float y){
if ((tee.getPosition().x > CAMERA_WIDTH / 2)) {
cam.position.set(x, y, 0);
cam.update();
}
}
private void drawBlocks() {
for (Block block : world.getBlocks()) {
spriteBatch.draw(blockTexture, block.getPosition().x, block.getPosition().y, Block.SIZE, Block.SIZE);
}
}
private void drawTee() {
Tee tee = world.getTee();
spriteBatch.draw(teeTexture, tee.getPosition().x, tee.getPosition().y, Tee.SIZE, Tee.SIZE);
}
Using the sprite.setProjectionMatrix(cam.combined) before the spriteBatch.begin() is needed because if you don't the spriteBatch uses it's own camera, therefore your updates do nothing for what appears on screen.
You have to take out the ppuX, ppuY stuff. I know that's to resize the screen for different devices, but it screws up the camera, therefore if you keep it in and call the setProjectionMatrix, it will be way way zoomed in (actually the size of all images will be huge.)

Categories

Resources