Understanding coordinates in libgdx - libgdx

I'm currently working on a libgdx project. This is the structure I'm following:
Single Game - several screens - each screen has a stage - each stage has some groups - each group has some actors - each actor has an sprite.
I'm playing with dragging actors between the groups, but when I'm adding actors into a group, the coordinates are always 0,0 even if I specify others.
I've read something about local coordinates and stage coordinates.
The quesion is... how can I add an actor (and its sprite) in the middle of the group?

After adding an actor into group, coordinates of actor became relative to group. If you know width and height of group, you can use following code snippet if your actors origin is on its (0,0) point :
group.addAtor(actor);
actor.setX(group.getWidth() / 2 - actor.getWidth() / 2);
actor.setY(group.getHeight() / 2 - actor.getHeight() / 2);
If you set the origin to actors central point like below :
actor.setOrigin(actor.getWidth()/2, actor.getHeight()/2);
then you can use following code without considering actor's width and height :
actor.setX(group.getWidth() / 2);
actor.setY(group.getHeight() / 2);

Related

Rotation issue While Reflected (2D Platform Game)

My player's arm is programmed to follow my mouse and rotate accordingly and I've programmed bullets to be fired using this rotational value
(Math.atan2(this._dy, this._dx) * 180 / Math.PI
where _dy is the y location of the mouse (-) the y of my player's arm and the _dx is the x location of mouse (-) the y of my player's arm.
However, when I program the player to reflect when the mouse has crossed the x-coordinates, the bullet angle is also reflected. How would I fix this issue?
I've already tried subtracting 180 from the angle but it still doesn't fire towards the direction of the mouse.
First, make sure you have this parent-child-sibling relationship:
"A" should be the parent of "B" and "C". "B" and "C" should have no direct link. Their connection is that they have the same parent. So when you want to move the character, move the parent, and both will move. Now, for the good stuff:
Use key frames and sibling relationship
beginner level approach
Make the character and the arm both children of the same parent display object container (Movie Clip in this case). Now, instead of flipping anything by xScale, which I assume you did, you can just have both MC children (arm and character) go to frame 2 (or whatever is available) where the graphics are flipped.
xScale body, move arm to frame 2, change z order
moderate level approach (best result)*
Alternatively, you could do that same "sibling" setup as above, and then scale the character but not the arm (I think scaling the arm will mess it up again, but you could have the arm go to frame 2 and have it drawn reversed so the thumb and handle are pointing the right way. Bonus points for changing the z stacking order so the arm goes to the other side of the body. xScale for only the body allows you to only have one set of frames for animation of his legs and torso etc. but also avoid scaling the arm at all).
Global properties
advanced approach
A third option is to use global rotation and global points. I won't illustrate that here because I'm not that advanced and it would take me a while to figure out the exact syntax. If you already have mastered global properties, try this; if not, try one of the ones above.
* Example (best result)
if (facingRight == true && stage.mouseX < totalChar.x){
// totalChar is on the stage
// and contains two children:
// armAndGun and bodyHeadLegs
totalChar.armAndGun.gotoAndStop(2);
// in frame 2 of the arm MC, draw the
// arm and gun in the flipped orientation
totalChar.addChild(bodyHeadLegs);
// re-ads body to parent so it's
// z-order is above the arm;
totalChar.bodyHeadLegs.xScale = -1;// flips body and any animation of legs and head
facingRight = false;
// use a variable or property like this
// to keep him from constantly flipping
}
You'll need similar code to flip him back the other way.

How composite sprites scale together with libgdx

I have composited my sprites to build a monster truck with customizable bumpers, cabs, spoilers wheels etc. The class that holds these Sprites is MTruck and I can draw it perfectly provided I stay with scale 1.0.
mWheels.setPosition(posX + 17 * scale, posY);
mCab.setPosition(posX + 22 * scale, posY + 7 * scale);
mFender.setPosition(posX, posY + 75 * scale);
mWheels is positioned at the y origin of the Truck and mFender at the x origin.
I've tried all sorts of values for scale and extracting it separate from the scale I apply to mWheels, mCab etc but all that happens is the sprites scale but their positions become misaligned.
I'm going to have to render to a texture and scale that as I whole if I can't crack this.
perhaps, Set origin could help you:
void setOrigin(float originX, float originY)
Sets the origin in relation to the sprite's position for scaling and
rotation.
float getOriginX()
The origin influences setPosition(float, float),
setRotation(float) and the expansion direction
of scaling setScale(float, float)
float getOriginY()
The origin influences setPosition(float, float),
setRotation(float) and the expansion direction of
scaling setScale(float, float)
http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/Sprite.html
NEW EDIT: maybe if you are customizing the vehicle on a menu for example, as is practicable after this the customized vehicle and create an image at runtime, and scale, an use this image in Sprite, for maybe it's easier, but it's just an idea

Top-down game camera movement

I'm developing a top-down view game, and I've got a problem with the camera.
Currently camera simply follows the player entity - it seems fine to me, but people want another camera.
I'm using Starling, and StarlingPunk, but it shouldn't make much difference, its more theoretical question.
Camera works like this:
public function centerOnEntity(target:SPEntity):void
{
var newCameraX:Number = (target.x + target.width / 2) - SP.width / 2;
var newCameraY:Number = (target.y + target.height / 2) - SP.height / 2;
SP.camera.setPosition(newCameraX, newCameraY);
}
And basically, every frame, camera is centered on the user.
Following image will demonstrate the problem:
As you can see, I've got rectangular levels, and if level is small, or user is near to the level bounds a background image is displayed.
So, what kind of camera do I need?
I need a camera, that will show maximum level space, and minimum background image.
How can I achieve that?
Help would be appreciated!

How do I correctly translate my map after scaling?

I'm creating a camera in canvas like the one in Super Smash Bros, where the center of the camera follows the center point of all players and scales to encompass all the players.
I have it set up to find the distance between the 2 players, and if it's larger than the canvas size, the camera scale lowers to decrease the size of the blocks, player sprites, etc.
ctx.scale(cameraS,cameraS);
ctx.translate(-(cameraX*cameraS)+(CANVAS_WIDTH/2),-(cameraY*cameraS)+(CANVAS_HEIGHT/2));
These are what scale and move the drawn images to a position relative to the screen.
This is the actual game using the code and as you can tell, the scaling and moving of the images is slightly incorrect, but I'm not sure why!
https://dl.dropboxusercontent.com/u/51784213/Conjugate/index.html
For reference, the red dot is the position centered between both players. The lines show the dead center of the actual canvas. When scaling is 1(no scaling at all), the red dot is completely centered as it should be. When the scaling starts to decrease, the red dot begins to move off center in weird directions.
For the code to be working correctly, the dot should be centered at all times, even during the scaling process!
Transformations are applied in the reverse order; so you are first translating and then scaling. This means that for a point (x, y), after the current transformation, you get
(
(x + CANVAS_WIDTH/2 - cameraX*cameraS) * cameraS,
(y + CANVAS_HEIGHT/2 - cameraY*cameraS) * cameraS
)
What's actually needed here is the canvas be translated by scaled (cameraX, cameraY) and then be offset by actual (CANVAS_WIDTH/2, CANVAS_HEIGHT/2), so that (cameraX, cameraY) is at center of the visible canvas.
Or rather, the transformation needed here for a point (x, y) is
(
(x - cameraX) * cameraS + CANVAS_WIDTH/2,
(y - cameraY) * cameraS + CANVAS_HEIGHT/2
)
Hence, the code becomes, if you choose to apply translate first,
ctx.scale(cameraS,cameraS);
ctx.translate(-cameraX+CANVAS_WIDTH/(2*cameraS),-cameraY+CANVAS_HEIGHT/(2*cameraS));
Or, if you choose to apply scaling first
ctx.translate(-cameraX*cameraS + CANVAS_WIDTH/2, -cameraY*cameraS + CANVAS_HEIGHT/2);
ctx.scale(cameraS, cameraS);
Working JSFiddle.

How do I zoom into the mandelbrot set?

I can generate a 400x400 image of the Mandelbrot set from minReal to maxReal and from minImaginary to maxImaginary. So,
makeMandel(minReal, maxReal, minImaginary, maxImaginary);
I need to modify it so that I can have,
makeMandel(centerX, centerY, Zoomlevel);
// generates a region of the mandelbrot set centered at centerX,centerY at a zoom level of Zoomlevel
(Considering zoom level represents the distance between the pixels and is given by the formula Zoom level n = 2 ^ (-n) so that zoom level 1 means pixels are 0.5 units apart, zoom level 2, 0.25 and so on...)
My question is how do I calculate the arguments of the first makeMandel function from the arguments of the second one?
I know that the first function is capable of zooming and moving around but I don't know how to calculate the correct numbers for any given center and zoom level.
I've been trying to get this working for more than three days now and I'm really confused. I tried drawing tables, etc... on paper and working it out.
I read most documents that you find on Google when searching for the mandelbrot set and a couple of past stackoverflow questions but I still don't understand. Please help me out.
You may solve it the following way. If you have the two definitions
centerX = (minReal + maxReal)/2
sizeX = maxReal - minReal
you can calculate extends on the axis via
minReal = centerX - sizeX/2
maxReal = centerX + sizeX/2
The size then is calculated using the zoomLevel:
sizeX = 2^(-zoomLevel) * baseSize
The same formulas hold for y and imaginary axis.
sizeY = 2^(-zoomLevel) * baseSize
minImaginary = centerY - sizeY/2
maxImaginary = centerY + sizeY/2
The only thing to define as a constant is your baseSize, i.e. the extend in real and imaginary axis when zoomLevel is zero. You may consider different baseSize in real and imaginary direction to cover an non-square aspect ratio of your image.