Howto rotate a Sprite after resizing the Sprite with setBounds ? (LIBGDX) - libgdx

I have a Bitmap (png) loaded into my Sprite with a specific size (200) and a Center at 100/100 for rotation:
Sprite round = loadSprite(200,200);
round.setPosition(x,y)
When Rotating round.setRotation() the Sprite rotates around the correct Center.
Now I would like to size the Sprite to a new Size (400,400) and still want to rotate around the Center (200/200):
round.setBounds(x,y,400,400)
rount.setCenter(200,200);
When rotating again, it is still rotating around the old Center 100/100.
How to do this corectly ?

setCenter(x, y) set the position of the Sprite so it is centered to this position:
/** Sets the position so that the sprite is centered on (x, y) */
public void setCenter(float x, float y){
...
}
You need the function setOrigin(originX, originY):
/** Sets the origin in relation to the sprite's position for scaling and rotation. */
public void setOrigin (float originX, float originY) {
...
}

Related

glow effect with ShapeRenderer (libgdx)

I read about glow/particle effecta with sprites, which are working well.
Is there a simple way to create the similar blur effect with simple shaperender functionality like circles ?
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
batch.end();
shapeRenderer.begin(ShapeRenderer.ShapeType.Point);
shapeRenderer.setAutoShapeType(true);
drawCircle();
shapeRenderer.end();
batch.begin();
}
private void drawCircle() {
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
// apply effect ??
shapeRenderer.circle(10,10,2);
}
You can't use textures with default ShapeRender.
There are several way to do this but the easiest is to use ShapeDrawer library. It adds some "ShapeRenderer like" capabilities to a SpriteBatch and more. see https://github.com/earlygrey/shapedrawer
Yes, you could create a "glow" effect, this could be achieved by drawing using decreasing alpha values past the boundaries.
Firstly, to define the glow-effect parameters, let's determine the maximum boundary of the glowing object, where the glow ends, as being auraSize for the size of the aura.
Next, we need to know the size of the solid portion of the object, the bit that doesn't glow, and let's call this objSize for the size of the object.
To draw this, we can use a simple for loop and some if statements:
private void drawCircle() {
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
//Draw circles upto the size of aura
for(int radius = 0; radius < auraSize; radius++) {
/*
* Checks if radius fits object size, sets colour to solid white if so
* Interpolates alpha value to 0 based on distance to aura covered by radius otherwise
*/
if(radius <= objSize) {
shapeRenderer.setColor(Color.WHITE);
} else {
shapeRenderer.setColor(new Color(1, 1, 1,
MathUtils.lerp(1, 0, (radius - objSize) / (auraSize / objSize))));
}
//Draws the circle at the current radius
shapeRenderer.circle(10, 10, radius);
}
}

Draw sprite on Body - camera View Port and resize

I'm drawing sprites uppon bodies, with this method (inside my body wrapper):
private void drawBaseSprite(Batch batch){
Sprite baseSprite = this.getBaseSprite();
Vector3 bodyPixelPos = camera.project(new Vector3(body.getPosition().x, body.getPosition().y, 0));
// TODO: 17/11/16 Review this
float w = scale * (baseSprite.getTexture().getWidth())/camera.zoom;
float h = scale * (baseSprite.getTexture().getHeight())/camera.zoom ;
baseSprite.setSize(w,h);
baseSprite.setOrigin(w/2, h/2);
baseSprite.setPosition(bodyPixelPos.x -w/2, bodyPixelPos.y - h/2);
baseSprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
baseSprite.draw(batch);
}
Everything is good, until I try resizing the windows. Well, I'm following this resize logic (implements Screen) :
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
stage.camera.setToOrtho(false, Constants.VIEWPORT_HEIGHT *width/(float)height, Constants.VIEWPORT_HEIGHT);
}
Before resize:
After resize (larger width):
I find this absurd because this:
float w = scale * (baseSprite.getTexture().getWidth())/camera.zoom;
float h = scale * (baseSprite.getTexture().getHeight())/camera.zoom ;
doesn't change, while the images are x-scaled.
Am I correct in understanding that your problem is the image not staying on top of the body?
If so, the reason why it doesn't is that you are setting the size of the image relative to the camera, not to the body it is supposed to cover. When your camera's zoom is changed, you adjust the size of the image, but not the body, and they get out of sync.
I would recommend changing your logic such that the image height/width are determined purely by the body, and your body is scaled based on the camera zoom.
Well, this solved my problem, but I still don't deeply-know why.
private void drawBaseSprite(Batch batch){
Sprite baseSprite = this.getBaseSprite();
batch.setProjectionMatrix(camera.combined);
float someScale = 0.1f;
float w = scale * (baseSprite.getTexture().getWidth())/camera.zoom *someScale;
float h = scale * (baseSprite.getTexture().getHeight())/camera.zoom *someScale;
Vector3 bodyPixelPos = camera.project(new Vector3(body.getPosition().x, body.getPosition().y, 0))
.scl(someScale*camera.viewportHeight/(Gdx.graphics.getHeight()/20f)).sub(w/2, h/2, 0);
baseSprite.setSize(w,h);
baseSprite.setOrigin(w/2, h/2);
baseSprite.setPosition(bodyPixelPos.x, bodyPixelPos.y);
baseSprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
baseSprite.draw(batch);
}

Libgdx Box2D body rotation around point sprite position

I need that my body rotate around specific point like shown in picture.
I already done that by this line of code (Please let me know if there is a better way)
PolygonShape shape = new PolygonShape();
shape.setAsBox(1.8f / PPM, 0.2f / PPM, new Vector2(2,2), 0); // vector2 is
now I want to position sprite accordingly to my rotating body. Here what I did
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
sprite.setPosition(body.getPosition().x * 32 - sprite.getWidth() / 2, body.getPosition().y * 32 - sprite.getHeight() / 2);
and here how I draw everything
public void draw(SpriteBatch sb){
System.out.println(body.getWorldCenter());
sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
sprite.draw(sb);
}
Strange things happen when I run my code. I seee that body rotating correctly, but sprite rotates around its origin (middle of a sprite) because of this line sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2); however I need that sprite position would be always the same as my body position. How can I cheve this?
The origin of all box2d bodies is their location.
Important: The box2d bodies of type box/circle get centered around their location, while the other types of bodies are NOT.
If you want to sync your rotation with the sprite, you should position the sprite origin over the body location and then rotate.
Example: if you have body at location 0,0 and sprite with origin 1,1 you should position that sprite on location -1,-1 in order for the two to rotate synchroniously!

Body and Sprite Positions

When I compile my hero doesn't touch the floor but stops anyways a few pixels above. I figured if I traced both bodies and their respective sprites I'd know which ones aren't coincinding.
trace("Hero: ", hero.position.y, "/", heroSprite.y);
trace("Floor: ", floor.position.y, "/", floorSprite.y);
I get the following,
Hero: 470.2(...) / 470.2
Floor: 0 / 0
Also, how is the floor position 0 in its y property when:
createWall(stage.stageWidth/2, 500, 100, 30); //(y = 500)
I read that while the nape body 'registration point' is in the middle, the sprite one is in the upper-left corner so when giving the sprite the same x and y of the body it won't match. Below the sprite will be out of position.
public function createWall(x:Number, y:Number, width:Number, height:Number):void
{
wall.shapes.add(new Polygon(Polygon.rect(x, y, width, height)));
wall.space = space;
wallSprite.graphics.beginFill(0x000000);
wallSprite.graphics.drawRect(x, y, width, height);
wallSprite.graphics.endFill;
addChild(wallSprite);
wall.userData.sprite = (wallSprite);
addChild(wall.userData.sprite);
}
I tried wallSprite.graphics.drawRect(-width/2, -height/2, width, height); but didn't work. Althought I believe the problem is there, placing the sprite properly.
Drawing does not affect the position of an object. In your case the wall is at 0,0 and you draw at x:stage.stageWidth/2 , y: 500 but that's not going to become the wall coordinates, those are still 0,0 anyway.

How to draw a rectangle or curve between two co-ordinates in libGDX

I am new to libGDX.I just want a Rectangle or a small curve drawn between the object and the clicked position .I know libGDX has RECTANGLE class but I need to rotate it but the problem is, it gets rotated in center origin and i want to rotate it from its starting position.
I just want to draw a rectangle or a curved line to be drawn between the object and the clicked position like this >>>
Code to get user click position :
int x1 = Gdx.input.getX();
int y1 = Gdx.input.getY();
Code to get the width(distance) between the object and the clicked position :
float abwidth = x1 - position.x;
Code to compute the rotation :
float f1 = Math.abs(y1 - position.y);
float f2 = Math.abs(x1 - position.x);
abwidth = Math.abs(abwidth);
float abdegree = Math.toDegrees(Math.atan((f1)/(f2)));
abdegree = abdegree * (-1);//done this because it was giving the opposite rotation i dont know if this is wrong but it made the angle upwards
The above computed degree when put in the following code -- > shapeRenderer.rect(x,y,width,height, 0, 0, abdegree ); is not giving me the perfect angle So what would be a perfect way to rotate the straight horizontal rectangle to the click position.
Or is there any way of achieving this in some other way instead of using rectangle like using curve or something else ?
You can use this class for rendering shapes
and it has
rect(float x, float y, float width, float height, float originX, float originY, float rotation)
method for drawing rectangles
set originX,originY to 0,0 or other numbers to change rotation origin point