Make animation with box2d - java

I make simple game with libgdx. I want to add box2d physics engine. I have three sprites and one of them is animated (dynamic bodie). The rest are static. I don't know how to integrate this with box2d. Is there any solution. I spent a lot of hours for searched but found nothing.
My world renderer class:
public WorldRenderer(GameWorld world) {
this.world = world;
this.camera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.camera.position.set(CAMERA_WIDTH/2f, CAMERA_HEIGHT/2f, 0);
this.camera.update();
spriteBatch = new SpriteBatch();
loadTexture();
}
public void loadTexture() {
TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("gfx/textures.atlas"));
int indexr = 1;
int indexl = 1;
monkeyLeft = atlas.findRegion("left");
monkeyRight = atlas.findRegion("right");
platformTex = atlas.findRegion("platform");
bananaTex = atlas.findRegion("banana");
TextureRegion[] walkRightFrames = new TextureRegion[2];
TextureRegion[] walkLeftFrames = new TextureRegion[2];
for(int i=0;i<2;i++){
walkLeftFrames[i] = atlas.findRegion("left", indexl++);
walkRightFrames[i] = atlas.findRegion("right", indexr++);
}
goLeft = new Animation(RFD, walkLeftFrames);
goRight = new Animation(RFD, walkRightFrames);
}
public void render(){
spriteBatch.begin();
drawPlatform();
drawMonkey();
drawBanana();
spriteBatch.end();
}
public void drawMonkey() {
Monkey monkey = world.getMonkey();
monkeyFrame = monkey.isFacingLeft() ? monkeyRight : monkeyLeft;
if(monkey.getState().equals(Stan.WALK)){
monkeyFrame = monkey.isFacingLeft()? goLeft.getKeyFrame(monkey.getStateTime(), true) : goRight.getKeyFrame(monkey.getStateTime(), true);
}
spriteBatch.draw(monkeyFrame, monkey.getPosition().x*ppuX, monkey.getPosition().y*ppuY, Monkey.SIZE*ppuX, Monkey.SIZE*ppuY);
}
public void drawPlatform() {
for(Platform platform : world.getPlatforms()){
spriteBatch.draw(platformTex, platform.getPosition().x*ppuX, platform.getPosition().y*ppuY, Platform.SIZE*ppuX, Platform.SIZEH*ppuY);
}
}
public void drawBanana() {
Banana banana = world.getBanana();
spriteBatch.draw(bananaTex, banana.getPosition().x*ppuX, banana.getPosition().y*ppuY, Banana.SIZE*ppuX, Banana.SIZE*ppuY);
}

Create your world. Create your bodies, step your simulation. And render them using the width, height, body position and rotate angle like this:
batcher.draw(animkeyframe, body.getPosition().x-width/2F, body.getPosition().y-height/2F, width/2, height/2, width, height, 1, 1, MathUtils.radiansToDegrees*body.getAngle());
For more info about Box2d: Wiki Entry
I can see most these things in your WorldRenderer code. Only stepping the simulation is not there.

Related

Libgdx Animation not working

I have been reading about libgdx and I have been stuck on this animation problem. I have reading about animation in libgdx from their github and when I run my app on my phone, the app crashes after the loading screen. Here is my player Actor that extends from Actor. I create the player actor in my menu screen class and add it to the stage. It is suppose to appear flying up and down in the menu screen but the app crashes. I know it is my player actor because when I comment out the player actor in my menu screen class the app does not crash. I use texture packer on my plane sprite and load it into my game.
public class PlayerActor extends Actor{
private DrunkPilot pGame;
private static final int NUM_ROWS = 5, NUM_COLS = 5;
private Animation<TextureRegion> drunkFlying;
private float stateTimer;
private TextureRegion region;
private Texture planeTex;
public PlayerActor(){
planeTex = pGame.assetManager.manager.get(Constants.plane);
planeTex = new Texture(Gdx.files.internal(Constants.plane));
drunkFlyingAnimation();
}
private void drunkFlyingAnimation(){
TextureRegion[][] tmp = TextureRegion.split(planeTex, planeTex.getWidth() / NUM_COLS, planeTex.getHeight() / NUM_ROWS);
TextureRegion[] flyFrames = new TextureRegion[NUM_COLS * NUM_ROWS];
int index = 0;
for (int i = 0; i < NUM_ROWS; i++) {
for (int j = 0; j < NUM_COLS; j++) {
flyFrames[index++] = tmp[i][j];
}
}
drunkFlying = new Animation<TextureRegion>(0.025f, flyFrames);
stateTimer = 0;
region = drunkFlying.getKeyFrame(0);
}
#Override
public void draw(Batch batch, float alpha){
super.draw(batch, alpha);
GdxUtils.clearScreen();
stateTimer += Gdx.graphics.getDeltaTime();
TextureRegion drunk = drunkFlying.getKeyFrame(stateTimer, true);
batch.draw(drunk, getX(), getY(), getWidth() / 2, getHeight() / 2, getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation());
}
public void dispose(){
planeTex.dispose();
}
}
Here is where I add my actor to the stage.
#Override
public void show() {
Gdx.input.setInputProcessor(menuStage);
menuTitle = new Image(menuTitleTexture);
menuStartImg = new Image(menuStartTexture);
menuTable = new Table();
menuTable.setFillParent(true);
menuTable.add(menuTitle).pad(20).align(Align.top);
menuTable.row();
menuTable.add(menuStartImg).align(Align.bottom).pad(30);
menuStage.addActor(parallaxBackground);
menuStage.addActor(menuTable);
menuStage.addActor(player);
}
When you use TexturePacker there is an easier way to create animations.
When we want to create a run animation
First you ad all animation images to TexturePacker you have to look that every frame has the same name + underscore + frameNumber.
So the name of the frames must be: run_1, run_2, run_3 etc.
When we created it we have a run.txt and run.png in our assets.
Now we can load the TextureAtlas with our AssetManager:
AssetManager assetManager = new AssetManager();
assetManager.load("run.txt", TextureAtlas.class);
assetManager.finishLoading();
TextureAtlas runAnimationAtlas = assetManager.get("run.txt", TextureAtlas.class);
With this TextureAtlas we can create our Animation:
float frameDuration = 0.1f; // the duration between the animation frames
Animation<TextureRegion> runAnimation = new Animation<TextureRegion>(frameDuration, runAnimationAtlas.findRegions("run"), Animation.PlayMode.LOOP);
And render the Animation:
batch.draw(runAnimation.getKeyFrame(stateTimer),posX, posY)

Libgdx - PPM world conversion

My sprite moves too slowly. Basically I want to apply less force to move my player. Current this:
getBody().applyForceToCenter(new Vector2(-10000000f,0f), true);
is the force needed to make it move a tiny bit.
I know the reason why I am not able to move it is since I haven't scaled the sprite (64x64) it weights more than 400kg. What should be the correct scale?
This is my game screen.
public class GameScreen implements Screen {
//Reference to our Game, used to set Screens
private Logang game;
//basic playscreen variables
private OrthographicCamera gamecam;
private Viewport gamePort;
//Box2d variables
private World world;
private Box2DDebugRenderer b2dr;
boolean drawn = true;
private Player p;
private int pX = 100, pY = 300;
public GameScreen(Logang game) {
this.game = game;
//create cam used to follow mario through cam world
gamecam = new OrthographicCamera();
gamePort = new ScalingViewport(Scaling.stretch, Logang.GWIDTH, Logang.GHEIGHT, gamecam);
gamePort.apply();
gamecam.position.set(gamecam.viewportWidth / 2, gamecam.viewportHeight / 2, 0);
gamecam.update();
Box2D.init();
//create our Box2D world, setting no gravity in X, -10 gravity in Y, and allow bodies to sleep
world = new World(new Vector2(0, Logang.GRAVITY), true);
//allows for debug lines of our box2d world.
b2dr = new Box2DDebugRenderer();
//create a FitViewport to maintain virtual aspect ratio despite screen size
p = new Player(new Sprite(new Texture("hud_p3.png")), world, pX, pY, 1);
//initially set our gamcam to be centered correctly at the start of of map
line();
}
#Override
public void show() {
}
public void update(float dt) {
//handle user input first
p.update(dt);
//update our gamecam with correct coordinates after changes
}
#Override
public void render(float delta) {
//separate our update logic from render
update(delta);
//Clear the game screen with Black
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1f / 60f, 6, 2);
gamecam.position.set(p.getSprite().getX(),Logang.GHEIGHT / 2, 0); // x and y could be changed by Keyboard input for example
gamecam.update();
game.getBatch().setProjectionMatrix(gamecam.combined);
//renderer our Box2DDebugLines
b2dr.render(world, gamecam.combined);
System.out.println("Player x: " + p.getSprite().getX() + " Camera X: " + gamecam.position.x + " Body X: " + p.getBody().getPosition().x);
//System.out.println("Player y: " + p.getSprite().getY() + " Camera Y: " + gamecam.position.y + " Body Y: " + p.getBody().getPosition().y);
game.getBatch().begin();
if (p.getBody() != null)
p.render(game.getBatch());
EntityManager.renderTerra(game.getBatch(), delta);
game.getBatch().end();
}
public void line() {
Texture tmp = new Texture("hud_p3.png");
tmp.setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
for (int i = 0; i < 50; i++) {
EntityManager.add(new Ground(new Sprite(tmp), world, (int)(i * Logang.TILE), 1, 2));
}
// EntityManager.changeSize(((Logang.TILE) * 5),Logang.TILE);
}
#Override
public void resize(int width, int height) {
//updated our game viewport
gamePort.update(width, height);
gamecam.position.set(gamecam.viewportWidth / 2, gamecam.viewportHeight / 2, 0);
}
public World getWorld() {
return world;
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
world.dispose();
b2dr.dispose();
}
And this is my entity class
private World world;
private Sprite sprite;
private Body body;
private int tipo;
public Entity(Sprite sprite, World world, int x, int y, int tipo) {
this.sprite = sprite;
this.world = world;
getSprite().setPosition(x, y);
sprite.setSize(Logang.TILE, Logang.TILE);
sprite.setOriginCenter();
define(tipo);
this.tipo = tipo;
}
public void update(float dt){
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
getBody().applyForceToCenter(new Vector2(-10000000f,0f), true);
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
getBody().applyForceToCenter(new Vector2(10000000f,0f), true);
}
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
//getBody().applyLinearImpulse(0f,-Logang.GRAVITY,
getBody().getPosition().x, getBody().getPosition().y, true);
}
}
public void define(int tipo) {
BodyDef bdef = new BodyDef();
bdef.position.set((getSprite().getX() + getSprite().getWidth() / 2),
(getSprite().getY() + getSprite().getHeight() / 2));
switch (tipo) {
case 1: {
bdef.type = BodyDef.BodyType.DynamicBody;
break;
}
case 2: {
bdef.type = BodyDef.BodyType.StaticBody;
break;
}
case 3: {
bdef.type = BodyDef.BodyType.DynamicBody;
break;
}
}
body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
fdef.density=0.001f; // (weight: range 0.01 to 1 is good)
PolygonShape shape = new PolygonShape();
shape.setAsBox(getSprite().getWidth() / 2, getSprite().getHeight() / 2);
fdef.shape = shape;
body.createFixture(fdef);
body.setUserData(this);
shape.dispose();
}
public void render(SpriteBatch batch) {
if (tipo != 2) {
float posX = getBody().getPosition().x;
float posY = getBody().getPosition().y;
getSprite().setPosition(posX - getSprite().getWidth() / 2, posY -
getSprite().getHeight() / 2);
}
getSprite().draw(batch);
}
public Sprite getSprite() {
return sprite;
}
public void setSprite(Sprite sprite) {
this.sprite = sprite;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
And this are the in game variables
public static final int GWIDTH = 800;
public static final int GHEIGHT = (GWIDTH/16)*9;
public static final float PPM = 100f;
public static final float GRAVITY = -10f;
public static final float TILE = 64;
Could you please give me a fix?
I already tried to divide body and gamecam position still no effect
What should be the correct scale?
The right scale would be the scale in real life where 1 unit in LibGDX (Box2D) represents 1 meter in real life. I always advice people to use this scale and zoom the camera properly.
Mind though, if you are using very large objects and zoom the camera all the way back objects appear to be falling slowly. This is obviously because your camera contains a much larger space. Not only would it fall slowly but it won't interact properly with the world if the item is supposed to be smaller.
Adept the camera to your world, not your world to your camera.
More detailed answer I gave

Libgdx problems with viewport/camera/rendering

I am having trouble for the last 2 days to figure out what is wrong with my application. I'm trying to build a game, a platformer where the player needs to go up, (somewhat like doodlejump). I have build my testmap in tmx format. I have been trying to start the camera and the viewport to show the left-bottom of the world, so the player can move to the right and also upward. But this seems to difficult for a beginning libgdx learner!
I am using a Playscreen, a HUD and a MainActivity:
PlayScreen
private MainActivity game;
private OrthographicCamera gamecam;
private Viewport gameport;
private HUD hud;
private TmxMapLoader mapLoader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private World world;
private Box2DDebugRenderer b2dr;
private Jack player;
public PlayScreen(MainActivity game){
// Initiates the game, camera, viewport and HUD
this.game = game;
gamecam = new OrthographicCamera();
hud = new HUD(game.batch);
gameport = new FitViewport(MainActivity.V_WIDTH, MainActivity.V_HEIGHT, gamecam);
// loading the map
mapLoader = new TmxMapLoader();
map = mapLoader.load("level1revised.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1 / MainActivity.PPM);
//initially set our gamecam to be centered correctly at the start of of map
gamecam.position.set(gameport.getWorldWidth() / 2, gameport.getWorldHeight() / 2, 0);
// Box2D world (graphics)
world = new World(new Vector2(0, -10), true);
b2dr = new Box2DDebugRenderer();
// New Jack
player = new Jack(world);
BodyDef bdef = new BodyDef();
PolygonShape shape = new PolygonShape();
FixtureDef fdef = new FixtureDef();
Body body;
// The ground as an object is defined
for(MapObject object: map.getLayers().get(2).getObjects().getByType(RectangleMapObject.class)){
Rectangle rect = ((RectangleMapObject) object).getRectangle();
bdef.type = BodyDef.BodyType.StaticBody;
bdef.position.set((rect.getX() + rect.getWidth()/2)/MainActivity.PPM, (rect.getY() + rect.getHeight()/2) /MainActivity.PPM);
body = world.createBody(bdef);
shape.setAsBox(rect.getWidth()/2, rect.getHeight()/2);
fdef.shape = shape;
body.createFixture(fdef);
}
public void update(float dt){
handleInput(dt);
world.step(1 / 60f, 6, 2);
//gamecam.position.x = player.b2body.getPosition().x;
gamecam.update();
renderer.setView(gamecam);
}
#Override
public void render(float delta) {
update(delta);
// Clear the screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// render the map
renderer.render();
// render the box2d
b2dr.render(world, gamecam.combined);
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
#Override
public void resize(int width, int height) {
gamecam.viewportWidth = width;
gamecam.viewportHeight = height;
}
HUD & Mainactivity
public HUD(SpriteBatch sb){
worldTimer = 300;
timeCount = 0;
score = 0;
viewport = new FitViewport(MainActivity.V_WIDTH, MainActivity.V_HEIGHT, new OrthographicCamera());
stage = new Stage(viewport, sb);
Table table = new Table();
table.top();
table.setFillParent(true);
countdownlabel = new Label(String.format("%03d", worldTimer), new Label.LabelStyle(new BitmapFont(), Color.RED));
scoreLabel = new Label(String.format("%06d", score), new Label.LabelStyle(new BitmapFont(), Color.RED));
timeLabel = new Label("TIME", new Label.LabelStyle(new BitmapFont(), Color.RED));
levelLabel = new Label("level 1", new Label.LabelStyle(new BitmapFont(), Color.RED));
table.add(timeLabel).expandX().padTop(10);
table.add(levelLabel).expandX().padTop(10);
table.row();
table.add(scoreLabel).expandX().padTop(10);
stage.addActor(table);
}
public class MainActivity extends Game {
public SpriteBatch batch;
public static final int V_WIDTH = 720;
public static final int V_HEIGHT = 480;
public static final float PPM = 1;
public static final String TITLE = "Jack the Pirate";
#Override
public void create () {
batch = new SpriteBatch();
setScreen(new PlayScreen(this));
}
#Override
public void render () {
super.render();
}
}
I have no clue where to look anymore, been through the basics countless times :( My tmx tilemap is 14 tiles wide, and 70 tiles high. The tiles themselves are 16x16. My test device is a Samsung Galaxy S3, and i wanted to use it in portrait mode.
Any ideas where to look? Thanks in advance for help!

Libgdx Box2d collision detection using physics body editor

Hy guys,
I am developing a game for android using libgdx. I am completely stuck at the part of detecting collision between two bodies.
I have a player which I create through the function below
public Body createPlayer(String file_path, String fixture_name) {
// 0. Create a loader for the file saved from the editor.
BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal(file_path));
// 1. Create a BodyDef, as usual.
BodyDef bd = new BodyDef();
bd.type = BodyDef.BodyType.DynamicBody;
// 2. Create a FixtureDef, as usual.
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.friction = 0.5f;
fd.restitution = 0.3f;
// 3. Create a Body, as usual.
body= world.createBody(bd);
//body.setBullet(true);
// 4. Create the body fixture automatically by using the loader.
loader.attachFixture(body, fixture_name, fd, 1);
body.setUserData(this);
return body;
}
and an enemy that I create with the same function of the player where I change only the file_path and the fixture_name.
The file_path points to a .json file that I created with box2d editor (site: http://www.aurelienribon.com/blog/projects/physics-body-editor/).
After the creation of the body I draw the player and the enemy with two similar functions ( I only post one):
private void drawPlayer(){
player_sprite = new Sprite(player_TR);
player_sprite.setSize(player.getWidth(), player.getHeight());
player_sprite.setPosition(player.getX(), player.getY());
player_sprite.setOrigin(0, 0);
player_sprite.draw(sb);
}
If I start the game everything is drawn where it should be. Obviously if the player touches the enemy nothing happen.
So i started trying to search how to make the two bodies collides but I don't really understand how to use ContactListener and beginContact.
beginContact wants as input a Contact but what is a Contact?
I have found this code online which appears to solve my problem but I don't know how to use it:
worldbox.setContactListener(new ContactListener() {
#Override
public void beginContact(Contact contact) {
if(contact.getFixtureA().getBody().getUserData()== "body1" &&
contact.getFixtureB().getBody().getUserData()== "body2")
Colliding = true;
System.out.println("Contact detected");
}
Can you help me (if it is possible through some code) to solve my problem?
Thanks in advance,
Francesco
Update of my question
Here is my render method:
public class GameRenderer{
private GameWorld myWorld;
private ShapeRenderer shapeRenderer;
private SpriteBatch sb;
private Camera camera;
private Constants constant;
private Rectangle viewport;
//dichiaro le variabili per caricare gli asset
private Player player;
private ScrollHandler scroller;
private Bordo frontBordoSX_1, backBordoSX_1, frontBordoSX_2, backBordoSX_2;
private Bordo frontBordoDX_1, backBordoDX_1, frontBordoDX_2, backBordoDX_2;
/*
private Ostacolo ob1_sx, ob2_sx, ob3_sx;
private Ostacolo ob4_dx, ob5_dx, ob6_dx;
*/
private TextureRegion player_TR;
private TextureRegion bordoSX_1, bordoSX_2;
private TextureRegion bordoDX_1, bordoDX_2;
private TextureRegion obstacleSX, obstacleSX_flip;
private TextureRegion obstacleDX, obstacleDX_flip;
private TextureRegion enemyS;
private TextureRegion blackBar;
//box2dpart
private World worldbox;
private Sprite fbDx_1,fbDx_2,fbSx_1,fbSx_2;
private Sprite player_sprite;
private Body player_body, bordo_destro;
private MyContactListener contactListener;
public GameRenderer(GameWorld world) {
myWorld = world;
constant = new Constants();
camera = new OrthographicCamera(constant.getWidth(), constant.getHeight());
shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(camera.combined);
sb = new SpriteBatch();
sb.setProjectionMatrix(camera.combined);
contactListener = new MyContactListener();
worldbox= new World(new Vector2(0,-10),true);
worldbox.setContactListener(contactListener);
//initialize objects and assets
initGameObjects();
initAssets();
}
private void initGameObjects(){
player = myWorld.getPlayer();
scroller = myWorld.getScroller();
frontBordoSX_1 = scroller.getFrontBordoSX_1();
backBordoSX_1 = scroller.getBackBordoSX_1();
frontBordoSX_2 = scroller.getFrontBordoSX_2();
backBordoSX_2 = scroller.getBackBordoSX_2();
frontBordoDX_1 = scroller.getFrontBordoDX_1();
backBordoDX_1 = scroller.getBackBordoDX_1();
frontBordoDX_2 = scroller.getFrontBordoDX_2();
backBordoDX_2 = scroller.getBackBordoDX_2();
/* other objects
ob1_sx = scroller.getOb1_sx();
ob2_sx = scroller.getOb2_sx();
ob3_sx = scroller.getOb3_sx();
ob4_dx = scroller.getOb4_dx();
ob5_dx = scroller.getOb5_dx();
ob6_dx = scroller.getOb6_dx();
*/
}
private void initAssets(){
player_TR = AssetLoader.player;
bordoSX_1 = AssetLoader.bordoSX;
bordoSX_2 = AssetLoader.bordoSX;
bordoDX_1 = AssetLoader.bordoDX;
bordoDX_2 = AssetLoader.bordoDX;
obstacleDX = AssetLoader.obstacleDX;
obstacleSX = AssetLoader.obstacleSX;
obstacleDX_flip = AssetLoader.obstacleDX_flip;
obstacleSX_flip = AssetLoader.obstacleSX_flip;
enemyS = AssetLoader.enemyS;
blackBar = AssetLoader.blackBar;
//box2d part
}
private void drawMargin(){
//bordo SX
/*
sb.draw(bordoSX_1, frontBordoSX_2.getX(), frontBordoSX_2.getY(), frontBordoSX_2.getWidth(),
frontBordoSX_2.getHeight());
sb.draw(bordoSX_2, frontBordoSX_1.getX(), frontBordoSX_1.getY(), frontBordoSX_1.getWidth(),
frontBordoSX_1.getHeight());
*/
fbSx_1 = new Sprite(bordoSX_1);
fbSx_1.setSize(frontBordoSX_1.getWidth(),frontBordoSX_1.getHeight());
fbSx_1.setPosition(frontBordoSX_1.getX(), frontBordoSX_1.getY());
fbSx_1.setOrigin(0, 0);
fbSx_1.draw(sb);
fbSx_2 = new Sprite(bordoSX_2);
fbSx_2.setSize(frontBordoSX_2.getWidth(),frontBordoSX_2.getHeight());
fbSx_2.setPosition(frontBordoSX_2.getX(), frontBordoSX_2.getY());
fbSx_2.setOrigin(0, 0);
fbSx_2.draw(sb);
fbDx_1 = new Sprite(bordoDX_1);
fbDx_1.setSize(frontBordoDX_1.getWidth(),frontBordoDX_1.getHeight());
fbDx_1.setPosition(frontBordoDX_1.getX(), frontBordoDX_1.getY());
fbDx_1.setOrigin(0, 0);
fbDx_1.draw(sb);
fbDx_2 = new Sprite(bordoDX_2);
fbDx_2.setSize(frontBordoDX_2.getWidth(),frontBordoDX_2.getHeight());
fbDx_2.setPosition(frontBordoDX_2.getX(), frontBordoDX_2.getY());
fbDx_2.setOrigin(0, 0);
fbDx_2.draw(sb);
sb.draw(blackBar,-constant.getWidth()/2,-constant.getHeight()/2,
(float) (0.573913)*(constant.getWidth()/6),constant.getHeight());
sb.draw(blackBar,(float)(constant.getWidth()/2-(0.573913)*(constant.getWidth()/6)),-constant.getHeight()/2,
(float)(0.573913)*(constant.getWidth()/6),constant.getHeight());
}
private void drawPlayer(){
player_sprite = new Sprite(player_TR);
player_sprite.setSize(player.getWidth(), player.getHeight());
player_sprite.setPosition(player.getX(), player.getY());
player_sprite.setOrigin(0, 0);
player_sprite.draw(sb);
}
/*
private void drawOstacoli(){
sb.draw(obstacleSX_flip,ob1_sx.getX(),ob1_sx.getY(),ob1_sx.getWidth(),ob1_sx.getHeight());
sb.draw(obstacleSX,ob2_sx.getX(),ob2_sx.getY(),ob2_sx.getWidth(),ob2_sx.getHeight());
sb.draw(obstacleSX_flip,ob3_sx.getX(),ob3_sx.getY(),ob3_sx.getWidth(),ob3_sx.getHeight());
sb.draw(obstacleDX,ob4_dx.getX()+constant.getWidth()/2-ob4_dx.getWidth(),ob4_dx.getY(),ob4_dx.getWidth(),ob4_dx.getHeight());
sb.draw(obstacleDX_flip,ob5_dx.getX()+constant.getWidth()/2-ob5_dx.getWidth(),ob5_dx.getY(),ob5_dx.getWidth(),ob5_dx.getHeight());
sb.draw(obstacleDX,ob6_dx.getX()+constant.getWidth()/2-ob6_dx.getWidth(),ob6_dx.getY(),ob6_dx.getWidth(),ob6_dx.getHeight());
}
*/
public void render(float runTime) {
Box2D.init();
int width = constant.getWidth();
int height = constant.getHeight();
float ratio = constant.getRatio();
//viewport
float aspectRatio = (float) width / (float) height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ratio)
{
scale = (float)height/(float)height;
crop.x = (width - width * scale) / 2f;
} else if (aspectRatio < ratio) {
scale = (float)width/(float)width;
crop.y = (height - height*scale)/2f;
}
else
{
scale = (float) width / (float) width;
}
float w = (float) width * scale;
float h = (float) height * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
// update camera
camera.update();
// clear previous frame
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
// Draw Background color
shapeRenderer.setColor(255 / 255.0f, 255 / 255.0f, 250 / 255.0f, 1);
shapeRenderer.rect(-constant.getWidth() / 2, -constant.getHeight() / 2, constant.getWidth(),
constant.getHeight());
// End ShapeRenderer
shapeRenderer.end();
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
// Begin SpriteBatch
sb.begin();
// The player needs transparency, so we enable that again.
sb.enableBlending();
// Draw player at its coordinates.
drawPlayer();
//draw right and left side
drawMargin();
// End SpriteBatch
sb.end();
worldbox.step(1 / 60f, 6, 2);
}
}
And if I start the program my view is my player in the middle and to margins ,one on the left and one on the right. (unfortunatly I cannot post images of my view because I don't have enough rep).
Everithing is fine. I move my player with the accelerometer and it works fine without any problem. The only problem is that if I move the player near the margin the two entities overlap instead of colliding and I don't understand why.
I also fixed the line:
loader.attachFixture(body, fixture_name, fd, 1);
to
loader.attachFixture(body, fixture_name, fd, player_width);
but nothing changes.
First, from here, the object Contact manages contact between two shapes, and from here, the listener ContactListener will be called when two fixtures begin to touch.
So, to make your code work, you should set a custom object to your bodies with the method: setUserData(Object userData). Usually this method is used to link the sprite or the actor with the physic body, but for example purpose you could just send a simple ID (like a string).
So in this part:
// 3. Create a Body, as usual.
body= world.createBody(bd);
//body.setBullet(true);
You could add an identificator to your object like this:
body.setUserData("player");
to idenfity your object, and then, when the listener get fired, you could retrieve this value:
#Override
public void beginContact(Contact contact) {
String userDataA = contact.getFixtureA().getBody().getUserData().toString();
String userDataB = contact.getFixtureB().getBody().getUserData().toString();
if(userDataA.equals("player") && userDataB.equals("otherEntity")){
colliding = true;
//do stuffs when collision has started
} else if(userDataB.equals("player") && userDataA.equals("otherEntity")){
colliding = true;
//do stuffs when collision has started
}
System.out.println("Contact detected");
}
After that, you could be able to do whatever you want to do with this collision.
Hope you find this useful!

How do I gain access to an objects variable from another class?

I have looked around online and some things have helped but I am still yet to get this thing working. I am making a simple pong game but I want it so all my code is well set out. So I have a class for the player1 paddle, the computer paddle, the ball, the main screen and also the play screen.
So, for example, my player1Paddle class will have all the movement for that paddle, the computer paddle class(player2) will have all the movement for that and so on.
But when it comes to coding the simple AI of the computer paddle (basically follow the ball left to right) I am unable to get access to the balls position
if(player2Pong.position.x > ballPong.position.x)
It brings an error. Now i have instantiated the ball class and it works but I have basically made another ball but the movement is not there. Here are parts of the code to try and help. I know there's a lot of code, and probably some un-needed.
On my playScreen i call player2movement -
player2Pong.Player2Movement();
Heres the majority of the player2pong class.
public class Player2Pong {
public Vector2 position;
String textureLoc;
Texture Player2Texture;
float stateTime;
Rectangle player2Bounds;
String movement;
int speed = 2;
int playerXVector = 5;
SpriteBatch batch;
//PlayerPong playerpong;
Player2Pong player2pong;
Ball ballPong;
public int paddle_player2_Width = 80;
public int paddle_player2_Height = 10;
//PlayerPong player;
public Player2Pong(Vector2 position, Ball ball){
Player2Texture = new Texture(Gdx.files.internal(("paddle_player2.png")));
this.position = position;
player2Bounds = new Rectangle(position.x,position.y,paddle_player2_Width, paddle_player2_Height);
//this.player2pong = player2pong;
this.ballPong = ball;
}
public void update(){
}
public void Player2Movement(){
player2pong = new Player2Pong(new Vector2(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() - (Gdx.graphics.getHeight()/8)), ballPong);
System.out.println(player2pong.position.x);
if(player2pong.position.x > ballPong.getPosition().x){
System.out.println("right");
player2pong.position.x -= playerXVector;
}
else if(player2pong.position.x < ballPong.getPosition().x){
System.out.println("right");
player2pong.position.x += playerXVector;
}
if(player2pong.position.x > Gdx.graphics.getWidth() - player2pong.getPaddle_player2_Width()-5){
player2pong.position.x -= playerXVector;
}
if(player2pong.getPosition().x < 3){
player2pong.position.x += playerXVector;
}
}
public void draw(SpriteBatch batch){
batch.draw(Player2Texture, position.x, position.y, paddle_player2_Width, paddle_player2_Height);
}
Here is majority of the playScreen class
public class PlayScreenPong implements Screen{
private static final Color WHITE = null;
SpriteBatch batch;
PlayerPong playerPong;
Player2Pong player2Pong;
InputProcessor inputProcessor;
Game game;
Ball ballPong;
Texture paddle_player1, paddle_player2;
ArrayList<Ball> balls;
ArrayList<Player2Pong> player2;
Iterator<Ball> ballsIterator;
Vector2 position;
ShapeRenderer borderSR, ballSR;
Sound sound;
boolean rectangles = true;
Stage PlayScreenStage;
Label label;
LabelStyle style;
BitmapFont font;
int playerXVector = 10;
int player1Score = 0;
int player2Score = 0;
public PlayScreenPong(Game game){
this.game = game;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0,0,0,0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
playerPong.update();
//player2Pong.update();
borderSR.begin(ShapeType.Line);
borderSR.rect(1, 1, Gdx.graphics.getWidth()-5, Gdx.graphics.getHeight()-4);
borderSR.setColor(1,1,1,1);
borderSR.end();
batch.begin();
ballsIterator = balls.iterator();
while(ballsIterator.hasNext()){
Ball cur = ballsIterator.next();
cur.update();
cur.draw(batch);
}
batch.draw(playerPong.getPlayerTexture(), playerPong.getPosition().x, playerPong.getPosition().y, playerPong.paddle_player1_Width, playerPong.paddle_player1_Height);
player2Pong.draw(batch);
//batch.draw(player2Pong.getPlayer2Texture(), player2Pong.getPosition().x, player2Pong.getPosition().y, player2Pong.paddle_player2_Width, player2Pong.paddle_player2_Height);
batch.end();
score();
PlayScreenStage.act();
PlayScreenStage.draw();
if(rectangles == true){
ballPong.drawRectangle();
}
player2Pong.Player2Movement();
}
#Override
public void show() {
batch = new SpriteBatch();
paddle_player1 = new Texture(Gdx.files.internal("paddle_player1.png"));
paddle_player2 = new Texture(Gdx.files.internal("paddle_player2.png"));
borderSR = new ShapeRenderer();
balls = new ArrayList<Ball>();
player2 = new ArrayList<Player2Pong>();
if(Gdx.files.local("paddle_player1.dat").exists()){
try {
playerPong = new PlayerPong(new Vector2(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 8), "paddle_player1.png");
playerPong.setPosition(PlayerPong.readPlayer());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("File exists, reading file");
}else{
playerPong = new PlayerPong(new Vector2(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 8),"paddle_player1.png");
try {
PlayerPong.savePlayer(playerPong);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Player doesnt exist, creating and saving player");
}
// player2Pong = new Player2Pong(new Vector2(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() - (Gdx.graphics.getHeight()/8)), playerPong);
// player2.add(player2Pong);
ballPong = new Ball(new Vector2(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2), playerPong);
balls.add(ballPong);
}
public void score(){
PlayScreenStage = new Stage();
font = new BitmapFont(Gdx.files.internal("font.fnt"), false);
style = new LabelStyle(font, Color.WHITE);
label = new Label("Player 1: " + player1Score + " : " + player2Score + " :Player 2", style);
label.setPosition(Gdx.graphics.getWidth()/2 - label.getWidth()/2, Gdx.graphics.getHeight()/25);
label.setFontScale((float) 0.8);
PlayScreenStage.addActor(label);
Gdx.input.setInputProcessor(PlayScreenStage);
batch = new SpriteBatch();
//System.out.println(ballPong.getPosition().y);
//-------------------------------------if someone scores
if(ballPong.getPosition().y< 1){
player2Score = player2Score +1;
//oppositionScore +=1;
System.out.println("goal");
//ballPong.reset();
}
if(ballPong.getPosition().y > Gdx.graphics.getHeight()-1 -ballPong.getBallSizeY()){
player1Score = player1Score + 1;
//ballPong.reset();
}
}
As I said before its a bit long winded but all I want to do is sort the movement of the AI in the player2pong class, the movement of the ball in the ball class and the movement of the player in the player class and then call the methods in the render or show methods in the playscreen class. Feel free to ask any questions. I know its an easy answer but im new :( Got to start somewhere
Okay, so, I might be wrong with this, but it's worth a shot.
First off, you don't need to create a new Player2pong object every time you call the PlayerMovement() function, you already have one:P
Secondly, you never make assign anything to the player2Pong attribute. So when you try and call draw() on it, there's nothing to call it on!:P

Categories

Resources