Sprites don't follow bodies movements. PhysicsConnector + Update Rotation - java

I am using:
physicsWorld.registerPhysicsConnector(new PhysicsConnector(sprite, body, true, true));
When the body interact with another it moves correctly, but the sprite moves oddly.
The image show this situation.
How I correct that?
--
Code:
Sprite sp = new Sprite(x, y, resourcesManager.box_region, vbom);
Body body = PhysicsFactory.createBoxBody(physicsWorld, sp, BodyType.DynamicBody, FIXTURE_DEF);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(sp, body, true, true));

Related

How do I remove the points in XYLineAndShapeRenderer?

I'm making an application in Java using JFreeChart which shows an XY line chart. The problem is that it shows every point of the dataset on the lines, and I don't want to display these points. Any idea on how to remove the points or make them not visible?
This is a sample screenshot:
Here is the code:
JFrame frame = new JFrame();
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesPaint(0, Color.RED);
renderer.setSeriesStroke(0, new BasicStroke(2.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
new float[] { 2.0f, 4.0f }, 0.0f));
XYDataset ds = createDataset(i, p, capacity);
JFreeChart xylineChart = ChartFactory.createXYLineChart("", "",
"", ds, PlotOrientation.VERTICAL, true, true, false);
XYPlot plot = xylineChart.getXYPlot();
plot.setDomainGridlinePaint(Color.BLACK);
plot.setRangeGridlinePaint(Color.BLACK);
plot.setBackgroundPaint(Color.WHITE);
plot.setRenderer(renderer);
ChartPanel cp = new ChartPanel(xylineChart);
frame.getContentPane().add(cp);
By default, the no-argument constructor of XYLineAndShapeRenderer "Creates a new renderer with both lines and shapes visible." To remove the points, you can
Use the alternative constructor to specify the desired combination—lines without shapes, as shown here and in ChartFactory.createXYLineChart:
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);
Invoke setSeriesShapesVisible(), as #abhinavxeon suggests here and the author suggests here:
renderer.setSeriesShapesVisible(0, false)

Change space between lines in tick labels

I need to implement a new "graphic generator". To ilustrate this requirement, I'll show an example of output using the old generator and the output of the one I'm trying to develop (or where I got so far).
My main issue right now is the space between the lines on the tick labels. The image must be 600x150, so I need to compress the text part of the graphic as much as I can (It doesn't need to be visually beautiful), but I could not find any suitable code so far.
Actually I need to eliminate as much "white spacing" as I can. If anyone have a hint how to implement the following, I would really appreciate:
Remove white gap between chart tittle and chart itself;
Remove white gap between tick labels and the bottow end of the image;
Remove the light gray line that represent the ticks on the bottom part of the chart. Right now the ticks labels and this line are overlapping.
This is the code I'm using to customize the chart:
CategoryPlot categoryplot = lineChart.getCategoryPlot();
lineChart.setTitle(
new org.jfree.chart.title.TextTitle(lineChart.getTitle().getText(),
new Font("SansSerif", Font.PLAIN, 10)
)
);
lineChart.setBackgroundPaint(Color.white);
categoryplot.setBackgroundPaint(Color.WHITE);
CategoryAxis domainAxis = new CategoryAxis();
domainAxis.setMaximumCategoryLabelLines(4);
categoryplot.setDomainAxis(domainAxis);
Font font = new Font("Courier", Font.PLAIN, 8);
categoryplot.getDomainAxis().setTickLabelFont(font);
categoryplot.getDomainAxis().setCategoryLabelPositionOffset(-6);
categoryplot.getDomainAxis().setTickLabelInsets(
new RectangleInsets(1.0, 1.0, 1.0, 1.0));
NumberAxis yAxis = (NumberAxis) categoryplot.getRangeAxis();
yAxis.setAutoRangeIncludesZero(false);
categoryplot.getRenderer().setSeriesStroke(
1,
new BasicStroke(
2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
1.0f, new float[] {6.0f, 6.0f}, 0.0f
)
);
categoryplot.setDomainGridlinesVisible(true);
categoryplot.setRangeGridlinesVisible(true);
categoryplot.setDomainGridlinePaint(Color.GRAY);
categoryplot.setRangeGridlinePaint(Color.GRAY);
categoryplot.getRenderer().setSeriesStroke(
2,
new BasicStroke(
2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
1.0f, new float[] {6.0f, 6.0f}, 0.0f
)
);
categoryplot.getRenderer().setSeriesPaint(0, Color.BLUE);
categoryplot.getRenderer().setSeriesPaint(1, Color.RED);
categoryplot.getRenderer().setSeriesPaint(2, Color.RED);
LineAndShapeRenderer renderer = (LineAndShapeRenderer) categoryplot.getRenderer();
renderer.setBaseShapesVisible(true);
renderer.setDrawOutlines(true);
renderer.setUseFillPaint(true);
renderer.setBaseFillPaint(Color.white);
renderer.setSeriesShape(0, new Ellipse2D.Double(-5, -5, 10, 10));

Rotate an image while it is being used

I am creating a car game and I want to rotate my car ( Image ) when I'm using the car but I don't know how. I've tried a few things that don't work. Here is what I have:
g2d.drawImage(DEFAULT_CAR_SKIN, DEFAULT_BOX.x, DEFAULT_BOX.y, null);
DEFAULT_BOX.setLocation(DEFAULT_BOX.x + 1, DEFAULT_BOX.y);
if (Game.rotateFront == true) {
AffineTransform identity = new AffineTransform();
AffineTransform trans = new AffineTransform();
trans.setTransform(identity);
trans.rotate(Math.toRadians(Game.Angle));
g2d.drawImage(DEFAULT_CAR_SKIN, trans, this);
}
But this code draws a new image but with the characteristics that I want.

Box2D crashes when destroying body (Expression: m_bodyCount < m_bodyCapacity)

Expression: m_bodyCount < m_bodyCapacity
That is the error I'm getting. The entire game crashes when I get this error. Now, here's the thing: I only get the error on certain I try to destroy, more specifically, bodies that were made during the game. What I mean is at the beginning of the game, I load the level and create all the bodies for each piece of the level. But, there are items that are made as the game runs, such as bullets, cannons, and coins. I can destroy any of the bodies created when the level is loaded, but when I try to destroy bodies created afterwards, I get the above error.
Here's an example. I spawn a CannonBall with my Cannon:
Cannon.class
if(reloadProgress >= RELOAD_TIME) {
CannonBall cannonBall = new CannonBall();
cannonBall.setXDirection(xDirection);
cannonBall.setYDirection(yDirection);
cannonBall.position.set(cannonBallPos);
Box2DHelper.makeFixture(cannonBall, BodyType.KinematicBody, origin, WorldController.b2world,
true, false);
Level.cannonBalls.add(cannonBall);
reloadProgress -= RELOAD_TIME;
} else {
reloadProgress += deltaTime;
}
Where Box2DHelper.makeFixture() is:
public static void makeFixture(GameObject object, BodyType type,
Vector2 origin, World b2world, boolean addUserData, boolean isMonster) {
BodyDef bodyDef = new BodyDef();
bodyDef.type = type;
bodyDef.position.set(object.position);
Body body = b2world.createBody(bodyDef);
if(addUserData)
body.setUserData(object);
object.body = body;
PolygonShape polygonShape = new PolygonShape();
origin.x = object.bounds.width / 2.0f;
origin.y = object.bounds.height / 2.0f;
polygonShape.setAsBox(object.bounds.width / 2.0f,
object.bounds.height / 2.0f, origin, 0);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = polygonShape;
if(isMonster) fixtureDef.filter.groupIndex = Constants.GROUP_MONSTER;
body.createFixture(fixtureDef);
polygonShape.dispose();
}
So now I've created my CannonBall and set its body. Now, after 10 seconds, if it hasn't hit anything, I destroy it:
CannonBall.class
if (existanceDuration >= CANNON_BALL_EXISTANCE_DURATION) {
//Destroy cannon ball
CollisionHandler.bodiesToRemoveList.add(this.body);
}
Now that I have added the body into the list, I have to remove it:
CollisionHandler.class:
public static void removeSpecifiedBodies() {
Iterator<Body> i = bodiesToRemoveList.iterator();
while (i.hasNext()) {
Body desBod = i.next();
removeObjectFromList(desBod); //This is just to remove the object as well
WorldController.b2world.destroyBody(desBod);
if (perCharHitAction == true) {
performCharacterDeathAction(Level.character);
perCharHitAction = false;
}
i.remove();
}
bodiesToRemoveList.clear();
}
But now, I need to actually call this method. I do this in my main update method, right after b2world.step():
WorldController.class:
public void update(float deltaTime) {
...
b2world.step(deltaTime, 8, 3);
if (CollisionHandler.bodiesToRemoveList.size() > 0)
CollisionHandler.removeSpecifiedBodies();
Now, like I stated before, this method works fine when I destroy objects made at the loading of the level, but on objects I later create, it doesn't.
Why does my game keep crashing after trying to destroy box2d bodies later created in my game?
Edit: I call this method right after the level has loaded for creating the object's bodies:
private void initPhysics() {
if (b2world != null)
b2world.dispose();
b2world = new World(new Vector2(0, -9.81f), true);
Vector2 origin = new Vector2();
b2world.setContactListener(new CollisionHandler());
// Create Box2D Fixtures
for (Grass grass : Level.grasses)
Box2DHelper.makeEdgeChain(grass, BodyType.StaticBody, origin,
b2world, true);
// Bricks
for (Brick brick : Level.bricks)
// Box2DHelper.makeFixture(brick, BodyType.KinematicBody, origin,
// b2world, true);
Box2DHelper.makeEdgeChain(brick, BodyType.StaticBody, origin,
b2world, true);
// Item Boxes
for (ItemBox box : Level.itemBoxes)
Box2DHelper.makeFixture(box, BodyType.KinematicBody, origin,
b2world, true, false);
//Enemies
for (Goomba goomba : Level.goombas)
Box2DHelper.makeFixture(goomba, BodyType.DynamicBody, origin,
b2world, true, true);
for (Koopa koopa : Level.koopas)
Box2DHelper.makeFixture(koopa, BodyType.DynamicBody, origin,
b2world, true, true);
// Cannons
for (Cannon cannon : Level.cannons)
Box2DHelper.makeFixture(cannon, BodyType.KinematicBody, origin,
b2world, true, true);
// Character
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(Level.character.position);
Body body = b2world.createBody(bodyDef);
body.setUserData(Level.character);
Level.character.body = body;
CircleShape polygonShapeHead = new CircleShape();
origin.x = Level.character.circleBoundOrigin.x * 2.0f;
origin.y = Level.character.circleBoundOrigin.y * 3.0f;
// polygonShapeHead.setAsBox(level.character.circleBoundOrigin.x,
// level.character.circleBoundOrigin.y, origin, 0);
polygonShapeHead.setPosition(origin);
polygonShapeHead.setRadius(Level.character.circleBoundOrigin.x);
FixtureDef fixtureDefHead = new FixtureDef();
fixtureDefHead.shape = polygonShapeHead;
fixtureDefHead.friction = Level.character.friction.x;
body.createFixture(fixtureDefHead);
polygonShapeHead.dispose();
PolygonShape polygonShapeBod = new PolygonShape();
origin = Level.character.rectBoundOrigin;
polygonShapeBod.setAsBox(Level.character.rectBoundOrigin.x,
Level.character.rectBoundOrigin.y, origin, 0);
FixtureDef fixtureDefBod = new FixtureDef();
fixtureDefBod.shape = polygonShapeBod;
fixtureDefBod.friction = Level.character.friction.x;
body.createFixture(fixtureDefBod);
polygonShapeBod.dispose();
}
Maybe the issue when creating bodies later in the game is the b2world?
I had the same Error - I figured out, that it happens if you destroy the same body multiple times.
In my case I put the body into a list in the contact listener.. but I didn't make sure it was in the list only once.
That also explains why your problem was fixed once you worked with a boolean flag, that also made sure the same body was only destroyed once.
In short: You get this error if you try to destroy the same body over and over again.

Scaling an image with LibGDX SpriteBatches

I have my image (for the sake of explaining, lets call it Image.png) and I'm trying to get it to scale to properly fit in my Bodies I have drawn. The bodies and everything work with the debug but I'm not a fan of it.. I'm using a SpriteBatch to draw the background image onto the screen(it would be nice to scale that too). How would I scaleImage.png to the same size/position as a Dynamic body that has been rendered?
EDIT:
While drawing the images, I cant get them to match up with the debug render Bodies..
Creating Body:
BodyDef bodydef2 = new BodyDef();
bodydef2.type = BodyType.DynamicBody;
bodydef2.position.set(camera.viewportWidth + 30.0f, (int)(Math.random()*camera.viewportHeight)%(LastPlatformY+5)+20);
//System.out.println(bodydef2.position.y + " " + LastPlatformY);
Body block = world.createBody(bodydef2);
PolygonShape Shape2 = new PolygonShape();
Shape2.setAsBox(750*WORLD_TO_BOX, 200*WORLD_TO_BOX);
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = Shape2;
fixtureDef2.density = 1000.0f;
fixtureDef2.friction = 0.0f;
fixtureDef2.restitution = 0;
block.setLinearVelocity(new Vector2((float) (Platform_Velocity*-1), 0));
block.createFixture(fixtureDef2);
//Lock 'block' to X-Axis, Relative to floor.
PrismaticJointDef jointDef = new PrismaticJointDef();
jointDef.collideConnected = true;
jointDef.initialize(block, groundBody, block.getWorldCenter(), new Vector2(1, 0));
world.createJoint(jointDef);
Platforms.add(block);
Platforms_Created++;
LastPlatformY = (int)bodydef2.position.y;
Drawing Image:
sp.draw(platforms, (float)(Platforms.get(i).getPosition().x), (float)(Platforms.get(i).getPosition().y), 75,20);
EDIT #2:
turns out that if your camera is smaller than the size of your screen you have to do some compensation to account for that variation in positions.. Problem solved, thanks!
Just save the size of your body in two variables while creating your body and then call the appropriate draw method.
To get the position of your object call body.getPosition().
For example
Texture t = assetManager.get("your texture", Texture.class);
BodyDef bodyDef = new BodyDef();
body.type = BodyType.DynamicBody
float width = 64 * WORLD_TO_BOX;
float height = 64 * WORLD_TO_BOX;
Shape shape = new PolygonShape();
float[] points = new float[]{0,0,width,0,width,height,0, height};
shape.set(points);
FixtureDef def = new FixtureDef();
def.shape = shape;
...
body.createFixture(def);
shape.dispose();
And later when you want to draw
public void render(Spritebatch batch) {
batch.draw(t, body.getPosition().x * BOX_TO_WORLD, body.getPosition().y * BOX_TO_WORLD, width * BOX_TO_WORLD, height * BOX_TO_WORLD);
}

Categories