libgdx box2d friction joint not working - libgdx

I am trying to make a simple example using the friction joints of box2d. I have created a circle that can be controlled with the mouse or arrow keys. There is also a box which is meant to be pushed with the circle. The problem is that when I push the box it keeps moving forever. I have added an auxiliary static box so I can join both boxes with a friction joint to simulate top-down friction. But it doesn't work. Here is the code.
public class MyGdxGame extends ApplicationAdapter {
Camera camera;
int windowWidth, windowHeight;
World physicsWorld;
Box2DDebugRenderer debugRenderer;
Body frictionerBox;
Body boxBody;
Body circleBody;
#Override
public void create () {
camera = new OrthographicCamera(2, 2);
Box2D.init();
physicsWorld = new World(new Vector2(0, 0), true);
debugRenderer = new Box2DDebugRenderer();
// frictioner box
BodyDef bDef = new BodyDef();
bDef.type = BodyDef.BodyType.StaticBody;
bDef.position.set(0, 0);
frictionerBox = physicsWorld.createBody(bDef);
PolygonShape fShape = new PolygonShape();
fShape.setAsBox(10, 10);
FixtureDef fixDef = new FixtureDef();
fixDef.shape = fShape;
fixDef.density = 1.f;
fixDef.friction = 1.f;
//Fixture fix =
frictionerBox.createFixture(fixDef);
// box
bDef = new BodyDef();
bDef.type = BodyDef.BodyType.DynamicBody;
bDef.position.set(0, 50);
boxBody = physicsWorld.createBody(bDef);
PolygonShape bShape = new PolygonShape();
bShape.setAsBox(25, 25);
fixDef = new FixtureDef();
fixDef.shape = bShape;
fixDef.density = 1.f;
fixDef.friction = 1.f;
boxBody.createFixture(fixDef);
// circle
BodyDef cDef = new BodyDef();
cDef.type = BodyDef.BodyType.DynamicBody;
cDef.position.set(20, 20);
circleBody = physicsWorld.createBody(cDef);
CircleShape cShape = new CircleShape();
cShape.setRadius(12);
fixDef = new FixtureDef();
fixDef.shape = cShape;
fixDef.density = 1.f;
circleBody.createFixture(fixDef);
FrictionJointDef frictionJointDef = new FrictionJointDef();
frictionJointDef.maxForce = 10;
frictionJointDef.maxTorque = 10;
frictionJointDef.initialize(frictionerBox, boxBody, new Vector2(0, 0));
physicsWorld.createJoint(frictionJointDef);
bShape.dispose();
cShape.dispose();
fShape.dispose();
}
#Override
public void render () {
handleInput();
physicsWorld.step(Gdx.graphics.getDeltaTime(), 6, 2);
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debugRenderer.render(physicsWorld, camera.combined);
}
#Override
public void resize(int width, int height)
{
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
windowWidth = width;
windowHeight = height;
System.out.println("resized");
}
private void handleInput()
{
final float ARROW_SPEED = 60.0f;
final float MAX_SPEED = 200.f;
final float MIN_SPEED = 20.f;
float vx, vy;
if(Gdx.input.isTouched() || Gdx.input.isButtonPressed(Input.Buttons.LEFT))
{
int tx = (Gdx.input.getX() - windowWidth/2);
int ty = -Gdx.input.getY() + windowHeight/2;
float cx = camera.position.x;
float cy = camera.position.y;
float px = circleBody.getPosition().x;
float py = circleBody.getPosition().y;
px = px - cx;
py = py - cy;
vx = tx - px;
vy = ty - py;
float speed = (float) Math.sqrt(vx*vx + vy*vy);
if( speed > MAX_SPEED )
{
vx = (vx/speed) * MAX_SPEED;
vy = (vy/speed) * MAX_SPEED;
}
if( speed > 0 && speed < MIN_SPEED )
{
vx = (vx/speed) * MIN_SPEED;
vy = (vy/speed) * MIN_SPEED;
}
}
else
{
vx = vy = 0;
if(Gdx.input.isKeyPressed(Input.Keys.W))
{
vy += 1;
}
if(Gdx.input.isKeyPressed(Input.Keys.S))
{
vy -= 1;
}
if(Gdx.input.isKeyPressed(Input.Keys.A))
{
vx -= 1;
}
if(Gdx.input.isKeyPressed(Input.Keys.D))
{
vx += 1;
}
float speed = (float) Math.sqrt(vx*vx + vy*vy);
if(speed > 0.f)
{
vx = (vx/speed) * ARROW_SPEED;
vy = (vy/speed) * ARROW_SPEED;
}
}
circleBody.setLinearVelocity(vx, vy);
}
}
What am I doing wrong?

I figured it out. It seems that for the friction to be noticeable you have to set very high values to maxForce and maxTorque.
frictionJointDef.maxForce = 1000000;
frictionJointDef.maxTorque = 10000000;

Related

LibGDX Cut texture with an angle

Suppose I have a Texture and I want to split it in half on a line rotated with a given angle.
In result I expect to get two Texture objects with the corresponding halfs of the original texture. Would be very nice if it could be done with some kind of transformation/masking so that I wouldn't have to store copies of two new textures at runtime.
Is this even possible?
I tried to work around Gdx.gl.glSsisors() but couldn't make it work as it requires screen coords to be passed as parameters.
Also I tried to go with Pixmap but couldn't find anything that would indicate it's even possible.
This can be achieved by manually calculating two skewed quads and render those using a SpriteBatch.
Cutting a sprite along angle angle we get a directional vector representing the cut by
public void cut(float angle) {
Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle);
if we also define the four corners for the UV Mapping of the Texture, along with the center and one vector la going d away from the center and lb going -d
Vector2 c = new Vector2(0.5f, 0.5f);
Vector2 la = (new Vector2(d)).scl( 1.0f).add(c);
Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c);
Vector2 tl = new Vector2(0, 1);
Vector2 tr = new Vector2(1, 1);
Vector2 bl = new Vector2(0, 0);
Vector2 br = new Vector2(1, 0);
we can then calculate the intersection of the cut
Vector2 i1 = new Vector2();
Vector2 i2 = new Vector2();
if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
else {
if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
}
At this point we know that one half of the cut will consist of vertices i1, i2 and two of tl, tr, bl and br, so if we sort them by angle away from the cut and then take the first 4 from i1 we get the vertices required to build the skewed quad:
Vector2[] vertexList = new Vector2[] {
tl, tr, bl, br, i1, i2
};
Array<VertexAngle> vas = new Array<>();
for (Vector2 v : vertexList) {
Vector2 vd = (new Vector2(v)).sub(c);
float a = d.angle(vd);
VertexAngle va = new VertexAngle();
va.v = v;
va.a = a;
vas.add(va);
}
vas.sort(new Comparator<VertexAngle>() {
#Override
public int compare(VertexAngle a, VertexAngle b) {
return Float.compare(a.a, b.a);
}
});
Array<Vector2> nv = new Array<>();
for (VertexAngle va : vas)
nv.add(va.v);
int index = nv.indexOf(i1, true);
The a float array containing the vertex data for the draw call can be constructed and rendered with a call to draw on SpriteBatch.
For example:
Full source code for the above example is:
package com.bornander.sandbox;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
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.SpriteBatch;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import java.util.Comparator;
public class SandboxGame extends ApplicationAdapter {
OrthographicCamera camera;
SpriteBatch batch;
Texture texture;
CutTexture cutTexture;
public static class CutTexture
{
public static class VertexAngle {
public Vector2 v;
public float a;
}
public static class CutHalf {
public float[] vertices = new float[4 * 5];
public void translate(float x, float y) {
for(int i = 0; i < vertices.length; i += 5) {
vertices[i + 0] += x;
vertices[i + 1] += y;
}
}
}
public Vector2 position = new Vector2();
public Vector2 driftDirection = new Vector2();
public float drift = 0.0f;
public Texture source;
public CutHalf halfA = new CutHalf();
public CutHalf halfB = new CutHalf();
public void cut(float angle) {
Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle);
Vector2 c = new Vector2(0.5f, 0.5f);
driftDirection.set(d).rotate(90.0f);
Vector2 la = (new Vector2(d)).scl( 1.0f).add(c);
Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c);
Vector2 tl = new Vector2(0, 1);
Vector2 tr = new Vector2(1, 1);
Vector2 bl = new Vector2(0, 0);
Vector2 br = new Vector2(1, 0);
Vector2 i1 = new Vector2();
Vector2 i2 = new Vector2();
if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
else {
if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1))
i2.set(1.0f - i1.x, 1.0f - i1.y);
}
Vector2[] vertexList = new Vector2[] {
tl, tr, bl, br, i1, i2
};
Array<VertexAngle> vas = new Array<>();
for (Vector2 v : vertexList) {
Vector2 vd = (new Vector2(v)).sub(c);
float a = d.angle(vd);
VertexAngle va = new VertexAngle();
va.v = v;
va.a = a;
vas.add(va);
}
vas.sort(new Comparator<VertexAngle>() {
#Override
public int compare(VertexAngle a, VertexAngle b) {
return Float.compare(a.a, b.a);
}
});
Array<Vector2> nv = new Array<>();
for (VertexAngle va : vas)
nv.add(va.v);
int index = nv.indexOf(i1, true);
int idx = 0;
int lastIndex = 0;
for(int j = 0; j < 4; ++j) {
lastIndex = (index + j) % nv.size;
Vector2 vertex = nv.get(lastIndex);
float width = source.getWidth();
float height = source.getWidth();
float fx2 = position.x + width * vertex.x - width / 2.0f;
float fy2 = position.y + height * vertex.y - height / 2.0f;
halfA.vertices[idx++] = fx2;
halfA.vertices[idx++] = fy2;
halfA.vertices[idx++] = Color.WHITE_FLOAT_BITS;
halfA.vertices[idx++] = vertex.x;
halfA.vertices[idx++] = 1.0f - vertex.y;
}
idx = 0;
for(int j = 0; j < 4; ++j) {
Vector2 vertex = nv.get((lastIndex + j) % nv.size);
float width = source.getWidth();
float height = source.getWidth();
float fx2 = position.x + width * vertex.x - width / 2.0f;
float fy2 = position.y + height * vertex.y - height / 2.0f;
halfB.vertices[idx++] = fx2;
halfB.vertices[idx++] = fy2;
halfB.vertices[idx++] = Color.WHITE_FLOAT_BITS;
halfB.vertices[idx++] = vertex.x;
halfB.vertices[idx++] = 1.0f - vertex.y;
}
}
public void render(SpriteBatch batch) {
float dx = driftDirection.x * drift;
float dy = driftDirection.y * drift;
halfA.translate(dx, dy);
halfB.translate(-dx, -dy);
batch.draw(source, halfA.vertices, 0, 20);
batch.draw(source, halfB.vertices, 0, 20);
halfA.translate(-dx, -dy);
halfB.translate(dx, dy);
}
}
#Override
public void create () {
float aspectRatio = (float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth();
camera = new OrthographicCamera(800, 800 * aspectRatio);
camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f, 0.0f);
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("badlogic.jpg"));
Gdx.gl.glCullFace(0);
cutTexture = new CutTexture();
cutTexture.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f);
cutTexture.source = texture;
cutTexture.cut(0);
}
float[] cutAngles = new float[] { 0.0f, -22.5f, -45.0f, -12.0f, -75.0f, -90.0f};
int ai = 0;
#Override
public void render () {
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE))
{
cutTexture.drift = 0.0f;
cutTexture.cut(cutAngles[(ai++) % cutAngles.length]);
}
cutTexture.drift -= 64.0f * Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(0.6f, 0.6f, 1.0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glCullFace(GL20.GL_NONE);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
cutTexture.render(batch);
batch.end();
}
}

Libgdx : GestureListener - pan not working properly

I am new to libgdx and trying to move a circle vy draging it. But its not working properly.
class deceleration is as follows -
public class gScreen1 extends ScreenAdapter
implements GestureDetector.GestureListener {
private static final float WORLD_WIDTH = 640;
private static final float WORLD_HEIGHT = 480;
...
#Override
public void show() {
super.show();
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.position.set(WORLD_WIDTH / 2, WORLD_HEIGHT / 2, 0);
camera.update();
viewport = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, camera);
shapeRenderer = new ShapeRenderer();
batch = new SpriteBatch();
}
private void drawGrid() {
Gdx.gl.glLineWidth(2);
shapeRenderer.setProjectionMatrix(camera.projection);
shapeRenderer.setTransformMatrix(camera.view);
shapeRenderer.setColor(Color.YELLOW);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
size = points.length;
for (int i = 0; i < size; i++) {
shapeRenderer.circle(pointsr[i].x , pointsr[i].y ,10);
}
shapeRenderer.end();
}
#Override
public void render(float delta) {
super.render(delta);
clearScreen();
drawGrid();
}
#Override
public boolean pan(float x1, float y1, float deltaX, float deltaY) {
Vector3 tmpCoords = new Vector3(x1,y1, 0);
camera.unproject(tmpCoords);
int x = (int)tmpCoords.x;
int y = (int)tmpCoords.y;
for( i = 0; i < size ; i++) {
int x2 = pointsr[i].x;
int y2 = pointsr[i].y;
if( ((x2 -x)*(x2 -x) + (y2 -y)*(y2 -y) ) < 400 )
break;
}
if( i < size ) {
pointsr[i].x += deltaX;
pointsr[i].y += deltaY;
}
}
Circles are not following movement of finger, some time they move a little bit but in opposite y direction of touch movement.

Flash as3 Var movieClip duplicates

Having multiple movieclips being able to move around on a grid, once dragging it, it seems to duplicate and the 'original' remains in place.
What causes it to duplicate in my code?
import flash.display.MovieClip
[SWF(width = 1300, height = 1000)]
var tileSize: int = 100;
var cols: int = stage.stageWidth / tileSize;
var rows: int = stage.stageHeight / tileSize;
var grid: Sprite = Sprite(addChild(new Sprite()));
grid.graphics.lineStyle(0, 0x000000, 0);
var i: int = 0;
for (i = 1; i < cols; i++) {
var posX: Number = i * tileSize
grid.graphics.moveTo(posX, 0);
grid.graphics.lineTo(posX, stage.stageHeight);
}
for (i = 1; i < rows; i++) {
var posY: Number = i * tileSize
grid.graphics.moveTo(0, posY);
grid.graphics.lineTo(stage.stageWidth, posY);
var ball: the_ball = new the_ball();
addChild(ball);
ball.x = tileSize * 5;
ball.y = tileSize * 5;
ball.buttonMode = true;
ball.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
function onDown(evt: MouseEvent): void {
addEventListener(Event.ENTER_FRAME, onRunSnapping);
}
function onRunSnapping(evt: Event): void {
ball.x = Math.round(mouseX / tileSize) * tileSize;
ball.y = Math.round(mouseY / tileSize) * tileSize;
}
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
function onUp(evt: MouseEvent): void {
removeEventListener(Event.ENTER_FRAME, onRunSnapping);
}
}
It's not duplicating, there are just many movieclips stacked on top of each other.
You add a new ball for each row you add on the exact same position.
I dont know how you want the balls to be distributed, but try to replace
ball.y = tileSize * 5; with ball.y = posY; to see what im talking about.

Setting a correct angular velocity to a canvas object

I am building a space shooter game and would like the ship to fire rockets at the direction of the cursor. Therefore, I grab the radian value of the angle it should fire at, multiply it by the ship's speed and set it's x and y velocities respectively.
I have this as a Bullet class:
function Bullet(x, y) {
this.x = x;
this.y = y;
this.rotation = 0;
this.width = 6;
this.height = 3;
this.color = utils.getRandomColor();
this.speed = 80;
}
And here is the function which updates the movement of all instances of the bullet class:
function drawBullet(bullet) {
var dx = mouse.x - bullet.x,
dy = mouse.y - bullet.y,
angle = Math.atan2(dy, dx);
bullet.vx = Math.cos(angle) * bullet.speed;
bullet.vy = Math.sin(angle) * bullet.speed;
bullet.x += bullet.vx;
bullet.y += bullet.vy;
bullet.draw(ctx);
}
It starts okay, going in the right direction and velocity and stuff. But as soon as it reaches the mouse, it stops dead there and starts flickering. NOW, I realise that this is because of the way I am getting the angle, using the mouse position as a value - the problem is that I can't figure out a way to use just the angle for the velocity, not the distance to the mouse position. So it doesn't slow down.
All suggestions are welcome, thanks in advance!
If you don't need homing missile type behavior just pass the mouse coordinates when you create the bullet.
Example:
new Bullet(shooterX, shooterY, mouseX, mouseY)
I included an over engineered stack snippet but the relevant part is below.
var Bullet = function(x,y,tx,ty){
this.speed = 15;
this.x = x;
this.y = y;
var radians = Math.atan2(ty-y, tx-x);
// we now have our velX and velY we can just refer to
this.velX = Math.cos(radians) * this.speed;
this.velY = Math.sin(radians) * this.speed;
}
Bullet.prototype.update = function(){
// just update by our previous calculated velX and velY.
this.x += this.velX;
this.y += this.velY;
};
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 250,
height = 250,
output = document.getElementById("radians"),
output2 = document.getElementById("degrees"),
cX = 0,
cY = 0,
mX = 0,
mY = 0,
bullets = [];
canvas.width = width;
canvas.height = height;
canvas.addEventListener("mousemove", function (e) {
mX = e.pageX;
mY = e.pageY;
});
var Ball = function (x, y, radius, color) {
this.x = x || 0;
this.y = y || 0;
this.radius = radius || 10;
// makes our x and y the center of the circle.
this.x = (this.x-this.radius/2);
this.y = (this.y-this.radius/2);
// how far out do we want the point
this.pointLength = 50;
this.px = 0;
this.py = 0;
this.color = color || "rgb(255,0,0)";
}
Ball.prototype.shoot = function(tx, ty){
bullets.push(new Bullet(this.x, this.y, tx, ty));
}
Ball.prototype.update = function (x, y) {
// get the target x and y
this.targetX = x;
this.targetY = y;
var x = this.x - this.targetX,
y = this.y - this.targetY,
radians = Math.atan2(y,x);
this.px = this.x - this.pointLength * Math.cos(radians);
this.py = this.y - this.pointLength * Math.sin(radians);
// -y will make 0 the top, y will 0 us at the bottom.
output.textContent = radians;
output2.textContent = radians/Math.PI * 180
};
Ball.prototype.render = function () {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = "rgb(0,0,255)";
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.px, this.py);
ctx.closePath();
ctx.stroke();
};
var Bullet = function(x,y,tx,ty){
this.speed = 15;
this.x = x;
this.y = y;
var radians = Math.atan2(ty-y, tx-x);
this.velX = Math.cos(radians) * this.speed;
this.velY = Math.sin(radians) * this.speed;
}
Bullet.prototype.update = function(){
this.x += this.velX;
this.y += this.velY;
};
Bullet.prototype.render = function(){
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
};
var ball1 = new Ball(width/2, height/2, 10);
canvas.addEventListener("click", function (e) {
ball1.shoot(e.pageX, e.pageY);
});
function render() {
ctx.clearRect(0, 0, width, height);
ball1.update(mX, mY);
ball1.render();
bullets.forEach(function(b){
b.update();
b.render();
});
requestAnimationFrame(render);
}
render();
ol{list-style:none;}
<canvas id="canvas"></canvas>
<div>
<ol>
<li>
<span>Radians : </span><span id="radians"></span>
</li>
<li>
<span>Degrees : </span><span id="degrees"></span>
</li>
</ol>
</div>
Add a new property on bullet that stores the angle of motion, initialize it to -1. Then, on the very first drawBullet call, check if it has been initialized first. If not, set the angle...
function Bullet(x, y) {
this.x = x;
this.y = y;
this.rotation = 0;
this.width = 6;
this.height = 3;
this.color = utils.getRandomColor();
this.speed = 80;
this.angle = -1; // New, angle property initialized to -1
}
function drawBullet(bullet) {
if (bullet.angle === -1) { // Only pull the mouse cursor and get an angle
var dx = mouse.x - bullet.x, // If it hasn't already done so.
dy = mouse.y - bullet.y,
angle = Math.atan2(dy, dx);
bullet.angle = angle;
}
bullet.vx = Math.cos(bullet.angle) * bullet.speed; // Re-use the angle value.
bullet.vy = Math.sin(bullet.angle) * bullet.speed;
bullet.x += bullet.vx;
bullet.y += bullet.vy;
bullet.draw(ctx);
}

Box2d working on dynamically created bodies

I'm trying to learn box2d but i've a problem. I have 3 bodies in my project, 3 lines actually. i'm trying to set each lines y coordinate to -7 when they arrive to y coordinate 14. my code for checking if they are over 14 is below:
for (int i = 0; i < groundsArray.size(); i++) {
Body body2 = groundsArray.get(i);
float x_deg;
x_deg = body2.getTransform().getPosition().x;
if (body2.getUserData().equals("grounds" + i) && body2.getTransform().getPosition().y > 14) {
body2.setTransform(x_deg, -7, 0);
}
}
How i create bodies :
public void createGrounds(int i) {
// for some random positions
int rnd = random.nextInt(10);
int constant = -20;
int new_y = i * 7;
int result_x1 = constant + rnd;
int result_x2 = result_x1 + 16;
BodyDef bodyDef = new BodyDef();
FixtureDef fixtureDef = new FixtureDef();
// GROUND LEFT
// body definition
bodyDef.type = BodyType.StaticBody;
bodyDef.position.set(0, 0);
// ground shape
ChainShape groundShape = new ChainShape();
groundShape.createChain(new Vector2[] { new Vector2(result_x1, -new_y),new Vector2(result_x2, -new_y) });
// fixture definition
fixtureDef.shape = groundShape;
fixtureDef.friction = 5f;
fixtureDef.restitution = 0;
grounds = world.createBody(bodyDef);
grounds.createFixture(fixtureDef);
grounds.setUserData("grounds" + i);
groundsArray.add(grounds);
groundShape.dispose();
}
How i call createGrounds() inside show():
for (int i = 0; i <= 2; i++) {
createGrounds(i);
}
How i update the world and positions inside render():
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
accelX = Gdx.input.getAccelerometerX();
Vector2 gravity = new Vector2(-accelX * 6, -60.81f);
world.setGravity(gravity);
world.step(TIMESTEP, VELOCITYITERATIONS, POSITIONITERATIONS);
batch.setProjectionMatrix(camera.combined);
batch.begin();
world.getBodies(tmpBodies);
for (Body body : tmpBodies) {
if (body.getUserData().equals(ballsprite)
&& body.getUserData() instanceof Sprite) {
Sprite sprite = (Sprite) body.getUserData();
sprite.setPosition(
body.getPosition().x - sprite.getWidth() / 2,
body.getPosition().y - sprite.getHeight() / 2);
sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
sprite.draw(batch);
}
float x_deg;
float y_deg;
x_deg = body.getTransform().getPosition().x;
y_deg = body.getTransform().getPosition().y;
y_deg = y_deg + game_speed;
body.setTransform(x_deg, y_deg, 0);
}
// The part i couldn't solve
for (int i = 0; i < groundsArray.size(); i++) {
Body body2 = groundsArray.get(i);
float x_deg;
x_deg = body2.getTransform().getPosition().x;
if (body2.getUserData().equals("grounds" + i)
&& body2.getTransform().getPosition().y > 14) {
body2.setTransform(x_deg, -7, 0);
}
}
batch.end();
debugRenderer.render(world, camera.combined);
}
Maybe change your for cycle to this
for(int i = groundsArray.size(); i > 0; i--){}