In my libGdx project,I created a sprite from texture atlas,using createSprite().
I want to implement the sprite as rotated.
How can I do it?Here is my Code:
reelSprite = atlas.createSprite("reel");
Inside render():
for (Wall lWalls : leftWalls){
reelSprite.setOrigin(lWalls.getX(), lWalls.getY());
reelSprite.setRotation(180);
batch.draw(reelSprite, lWalls.getX(), lWalls.getY());
}
This code is not working.Please tell me what wrong I did.
You should use setRotation before you draw the sprite:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Sprite.html#setRotation-float-
And even before that set rotation point:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Sprite.html#setOrigin-float-float-
float rotate = 0;
rotate += (sprite.getRotation() - 40) * Gdx.graphics.getDeltaTime();
if(Math.abs(rotate) > 10) // change the number to set the rotation power cap
{
rotate = -10;
}
sprite.rotate(rotate);
I changed the code like this...
for (Wall lWalls : leftWalls){
reelSprite1.setPosition(lWalls.getX(), lWalls.getY());
reelSprite1.setOrigin(reelSprite1.getWidth()/2,reelSprite1.getHeight()/2);
reelSprite1.setRotation(180);
reelSprite1.draw(batch);
then it worked.
Related
I have a sprite like this.
I want to draw this sprite in such a way that sprite is growing from bottom to top, using sprite batch on tap.for that,I have written the following code:
if (MyInputProcessor.isTap)
{
Sprite stickSprite = new Sprite(stickTexture);
stickSprite.setPosition(stick.getX(),stick.getY());
for(float n=0;n<100;n++)
{
float i = 0.01f * n;
batch.draw(
stickSprite.getTexture(),
stick.getX(),
stick.getY(),
stickSprite.getWidth() / 2,
stickSprite.getHeight() / 2,
stickSprite.getWidth(),
stickSprite.getHeight()*i, //multiplying with height
stickSprite.getScaleX(),
stickSprite.getScaleY(),
0 ,
stickSprite.getRegionX(),
stickSprite.getRegionY(),
stickSprite.getRegionWidth(),
stickSprite.getRegionHeight(),
false,
false);
}
MyInputProcessor.isTap = false;
}
Here the i value increments but not taking effect in the code to scale.
Whats wrong with the code?
I called this method in render before drawing the sprite.
stickSprite.setSize(stickSprite.getWidth(), stickSprite.getHeight() + addincrementvalue);
I am flipping one of the object in my libGDX project. At the same time I want to flip its shape rendering circle also. How can I do it?
here is my code for shaperenderer:
shapeRenderer.setProjectionMatrix(camera.projection);
shapeRenderer.setTransformMatrix(camera.view);
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
if (obsObj.isSpider())
circle(shapeRenderer, ob.getCollisionCircle());
shapeRenderer.end();
and circle method is:
private void circle(ShapeRenderer renderer, Circle circle) {
shapeRenderer.circle(circle.x, circle.y, circle.radius, 100);
}
I am flipping sprite object like this..
obsSprite.setFlip(true,false);
Instead of using circle/Rectangle shape rendering,I tried shape rendering with polygons.
It worked well for rotation and flipping.
You can use transform matrix like this :
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.setTransformMatrix(...your transformation matrix...);
camera.combined contains both camera projection and view.
your transformation matrix might be scaling matrix in your case (scaleX = -1 for horizontal flipping and/or scaleY = -1 for vertical flipping)
I would like to make a 2D Side-scroller game, where the game world/game stage is moving to the left, i.e. The background is transitioning to the left like Flappy Bird. Any ideas how I am able to automatically loop a background Actor object which has the same width and height as the Stage's Orthographic camera?
Well it is really simple. All you need to do is use the moveBy(x, y) method on the Actor instance.
float xMovingDelta = 10;
float yMovingDelta = 10;
actor.moveBy(xMovingDelta, yMovingDelta);
// Make sure you call the moveBy() method in a loop eg. the render() method.
Here is an example from my past game: It uses a Table instance but they both have the moveBy() method.
private void mMenuToDiffMenuAnimation() { // I call this method from the render() meth.
if(difficultyTable.getX() > (540 - 64)){
menuTable.moveBy(-30, 0);
difficultyTable.moveBy(-30, 0);
}else {
fromMMToDiffMenu = false;
/* When the table's xPos is greater than 540 -64 stop the animation.*/
}
}
I have an array of sprites:
for (i = 0; i < 3; i++) {
var newLine:Sprite = new Sprite();
newLine.graphics.beginFill(0xFFFFFF);
newLine.graphics.drawRect((uiSizeX * (.25 + .25 * i)) + (doorSizeX - lineLengths[0][i]) / 2, uiSizeY * .5, lineLengths[0][i], lineHeight);
newLine.name = "lines" + i;
lines.push(newLine);
}
I later add each to a background Sprite:
for (i = 0; i < 3; i++) {
uiContainer.addChild(doors[i]);
uiContainer.addChild(lines[i]);
}
And later wish to change the width of the rectangles contained in each. When I set the width property using the array reference:
lines[i].width = lineLengths[trialNumber][i];
The rectangle moves towards the center of the stage and uiContainer. Trying to set the x value results in even stranger behavior. I've gathered from answers to other questions that this is because the sprite is empty, which is confusing since it seems like it should have a rectangle in it. How do I access or change the properties of the rectangle or make it so the sprite is not empty?
Never try to directly change the width or height of a sprite, unless you really really have to, because it leads to all sorts of unexpected behavior.
If you want to resize the sprite, then redraw the rectangle:
var sprite = lines[i];
sprite.graphics.beginFill(0xFFFFFF);
sprite.graphics.drawRect(newWidth, newHeight);
Also don't forget to call endFill:
sprite.graphics.endFill();
You should probably wrap all this logic into a separate class so that you can redraw your sprites more easily. Even better, create a class that extends Sprite and that contains all the logic to redraw/resize.
I suppose this doesn't work because canvas is drawing a bitmap of a vector (and a bitmap is not a path).
Even if it did work, the bitmap is likely always has a rectangular permitter.
Is there any way to leverage something like isPointInPath when using drawImage?
example:
The top canvas is drawn using drawImage and isPointInPath does not work.
The bottom canvas is drawn using arc and isPointInPath works.
a link to my proof
** EDIT **
I draw a circle on one canvas, and use isPointInPath to see if the mouse pointer is inside the circle (bottom canvas in my example).
I also "copy" the bottom canvas to the top canvas using drawImage. Notice that isPointInPath will not work on the top canvas (most likely due to reasons I mentioned above). Is there a work-around I can use for this that will work for ANY kind of path (or bitmap)?
A canvas context has this hidden thing called the current path. ctx.beginPath, ctx.lineTo etc create this path.
When you call ctx.stroke() or ctx.fill() the canvas strokes or fills that path.
Even after it is stroked or filled, the path is still present in the context.
This path is the only thing that isPointInPath tests.
If you want to test if something is in an image you have drawn or a rectangle that was drawn with ctx.fillRect(), that is not possible using built in methods.
Typically you'd want to use a is-point-in-rectangle function that you write yourself (or get from someone else).
If you're looking for how to do pixel-perfect (instead of just the image rectangle) hit detection for an image there are various methods of doing that discussed here: Pixel perfect 2D mouse picking with Canvas
You could try reimplementing ctx.drawImage() to always draw a box behind the image itself, like so (JSFiddle example):
ctx.customDrawImage = function(image, x, y){
this.drawImage(image, x, y);
this.rect(x, y, image.width, image.height);
}
var img1 = new Image();
img1.onload = function(){
var x = y = 0;
ctx.drawImage(img1, x, y);
console.log(ctx.isPointInPath(x + 1, y + 1));
x = 1.25 * img1.width;
ctx.customDrawImage(img1, x, y);
console.log(ctx.isPointInPath(x + 1, y + 1));
Note: you might get side effects like the rectangle appearing over the image, or bleeding through from behind if you are not careful.
To me, isPointInPath failed after canvas was moved. So, I used:
mouseClientX -= gCanvasElement.offsetLeft;
mouseclientY -= gCanvasElement.offsetTop;
I had some more challenges, because my canvas element could be rescaled. So first when I draw the figures, in my case arc, I save them in an array together with a name and draw them:
if (this.coInit == false)
{
let co = new TempCO ();
co.name= sensor.Name;
co.path = new Path2D();
co.path.arc(c.X, c.Y, this.radius, 0, 2 * Math.PI);
this.coWithPath.push(co);
}
let coWP = this.coWithPath.find(c=>c.name == sensor.Name);
this.ctx.fillStyle = color;
this.ctx.fill(coWP.path);
Then in the mouse event, I loop over the items and check if the click event is in a path. But I also need to rescale the mouse coordinates according to the resized canvas:
getCursorPosition(event) {
const rect = this.ctx.canvas.getBoundingClientRect();
const x = ((event.clientX - rect.left ) / rect.width) * this.canvasWidth;
const y = ((event.clientY - rect.top) / rect.height) * this.canvasHeight;
this.coWithPath.forEach(c=>{
if (this.ctx.isPointInPath(c.path, x, y))
{
console.log("arc is hit", c);
//Switch light
}
});
}
So I get the current size of the canvas and rescale the point to the original size. Now it works!
This is how the TempCO looks like:
export class TempCO
{
path : Path2D;
name : string;
}