LibGDX ShapeRenderer refusing the render - java

Currently i am trying to render a rectangle between the mouse and a body the catch is I want the line to have a maximum length.
Meaning when the distance between the 2 points on the screen is less than a certain amount the rectangle should be between the mouse and body. If not the rectangle should be between a radius(point on the line from body to mouse) and the body.
I am using some vector logic to calculate the point to draw but when I seem to go inside my if statement the line which is drawn in under 200 distance just disappears.
ShapeRenderer sr = new ShapeRenderer();
sr.setColor(Color.WHITE);
sr.begin(ShapeRenderer.ShapeType.Filled);
if (ballPosition.dst(mousePos) > 200) {
System.out.println("Entered If!");
//Calculate point a distance away from ballPosition
Vector2 cloneMousePos = new Vector2(mousePos);
Vector2 dir = cloneMousePos.sub(ballPosition);
dir = dir.nor().scl(100);
Vector2 test = ballPosition.add(dir);
mousePos = test;
}
System.out.println("MousePos: " + mousePos.x + ", " + mousePos.y);
sr.rectLine(ballPosition, mousePos, 4f);
sr.end();
This is inside a Screen class I find it strange since when the distance is less than 200 the line draws perfectly, though from printing the x,y coordinates of the vectors it seems to be checking out.
Prints of the x,y coordinates of mousepos before moving a distance 200 out of body and after
MousePos: 213.0, 325.0
Entered If!
MousePos: 305.3836, 357.63123
EDIT:
On suggestion in the comments I have added some pictures.
Here a line between the ball and mouse is being drawn since the distance is under 200.
while here the distance becomes over 200 and we enter the if statement no line is drawn anymore unless we return to under 200.
Thanks!

Vector2 has a limit method to limit the length if greater than a certain value.
Vector2 dir = new Vector(mousePos).sub(ballPosition)
dir.limit(200f)
sr.rectLine(ballPosition, dir.add(ballPosition), 4f);

Related

Snake game, increasing length in processing

I am trying to recreate the snake game, right now i am stuck on adding a new section to the snake everything it collides with an apple
I tried to tell the program to draw a new rectangle but with the x axis slightly shifted and this "shifting" would slowly increase every time my snake eats an apple. My snake starts off with 2 sections, and when i move the snake towards the green apple, it only moves the second section instead of drawing a new one, I know i didn't tell my draw method to draw a new rectangle every time my snake eats an apple since i have no clue on how to do that
public void draw(PApplet p) {
// clear area
p.fill(255, 0, 0);
// draw snake head
p.rect(x, y, length, width);
// draw snake body ?
if (upIsDown == true ) {
p.rect(x, y - section, length, width);
} else if(downIsDown == true) {
p.rect(x, y + section, length, width);
} else if(RightIsDown == true) {
p.rect(x - section, y, length, width);
} else if(LeftIsDown == true) {
RightIsDown = false;
p.rect(x + section, y, length, width);
}
}
the section variable increases by 10 in my checkCollision method
The snake gets longer, but my program only draws the head and the tail of the snake
I added comments to your code.
You code in draw clears the whole game area, then draws 2 rectangles. If you want to see 3 rectanges, you will need to call p.rect() 3 times in that method. If you want to see 10 rectanges, you will need to call it 10 times (so maybe a loop would be good). Else reconsider the call to p.fill() in the beginning.
For a loop, you would need to store the coordinates for each body segment in a structure like a LinkedList, with the coordinates for each segment, and in the draw method draw all segments.

How to center a hitbox inside rotating triangle sprite?

I'm having problems plotting hitboxes in the center of rotating triangle sprites. When I spawn the triangles, I set the collision rectangle like this:
bullet.collisionRect.width = flashingTriangleSprite.getWidth() - 20;
bullet.collisionRect.height = flashingTriangleSprite.getHeight() - 14;
bullet.scale = 0.287f;
Updating is done as follows:
bullet.position.y += bullet.velocity.y;
// center collision rect over triangle sprite
bullet.collisionRect.x =
bullet.position.x + ((flashingTriangleSprite.getWidth() / 2) - bullet.collisionRect.getWidth() / 2);
bullet.collisionRect.y =
bullet.position.y + ((flashingTriangleSprite.getHeight() / 2) - bullet.collisionRect.getHeight() / 2);
if (bullet.scale < 1)
{
bullet.scale += 0.011f;
}
if (bullet.driftDirection == Globals.Direction.LEFT)
{
bullet.rotation -= 3.804f;
bullet.position.x -= bullet.velocity.x;
}
else // drift right
{
bullet.rotation += 3.804f;
bullet.position.x += bullet.velocity.x;
}
This is the result: http://imgur.com/rIvIT8K
As you can see, the hitboxes are not centered. In fact, the hitboxes seem to change position within the triangle sprites depending on the rotation of the triangle sprite. Any ideas what I'm doing wrong?
When determining your hitbox centre position you are targeting the centre of the triangle sprite (a square), but that is not the perfect centre of the drawn triangle.
Therefore your hitbox is always closer to one of the vertices of the triangle (depending on the rotation). Also, your hitboxes are never rotated with the triangle, instead they always appear to be standing vertically.
To place the hitbox in the middle of the triangle you should aim for 1/3 of the height of the sprite (if the triangle has one side flat at the bottom in the base sprite image) and when you are updating the sprite, attempt to update the hitbox rotation to match the sprite rotation.
You could also try making a more accurate triangle hitbox using the PolygonShape, but that's up to you.

Can't detect collision properly

i am writing a game using Libgdx and i need to detect when the user touches a sprite.
I tried to do so with this following code:
this code set the rect's position
for(int i = 0;i<circlesArray.length;i++)
{
rect[i] = new Rectangle(circles.getPosition(i).x,circles.getPosition(i).y,height/8,height/8);
}
and this code set the click as rectangle and checks if it overlaps the sprite
if(Gdx.input.isTouched())
{
click = new Rectangle(Gdx.input.getX(),Gdx.input.getY(),Gdx.input.getX(),Gdx.input.getY());
if(Intersector.overlaps(click,rect[1]));
{
System.out.println("clicked");
x[1] = 0;
}
}
From some reason that i cant understand the program detects a collision even when it is not happened, when i tap anywhere on the screen it says that i pressed the sprite.
What should i do to fix it?
This is your issue:
click = new Rectangle(Gdx.input.getX(), Gdx.input.getY(), Gdx.input.getX(), Gdx.input.getY());
Should be:
click = new Rectangle(Gdx.input.getX(), Gdx.input.getY(), 1, 1);
The last two parameters of a Rectangle are width and height. Here we give the rectangle a width and a height of 1 pixel but you can set it to whatever you like. You were setting those parameters as the inputs x and y which are different every time giving you varying results.
Edit:
To translate the input coordinates to your game world's coordinates based on the camera you have to do this:
Vector3 clickPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(clickPos);
click = new Rectangle(clickPos.x, clickPos.y, 1, 1);
When you use camera.unproject(Vector) it translates your inputs coordinates to work based off of where your camera is positioned in the game world. So now we're using a vector clickPos.
The reason we use a Vector3 is because this is what is required by the unproject function. We supply this vector with the inputs x and y but give it a 0 for the third parameter z since this is a 2d world.

AndEngine - Getting Center Coordinates of a Sprite

I have a sprite in my game and I want to get it's center coordinates. The sprite can be rotated though so I can't just get it's x/y coordinates then add half of the sprite's width/height because the getWidth and getHeight methods return the dimensions of the original, unrotated sprite.
I tried getSceneCenterCoordinates() but that for some reason returns the same coordinates for all sprites even if they are nowhere near each other.
Here's a graphic to describe what I want, the red dot is the coordinate I want, and the width/height labels on the right side figure respresent what I WANT the getWidth/Height methods to return (but they don't):
You can use coordinates transformer
final float[] spriteCoordinates = sprite.convertLocalToSceneCoordinates(x,y);
final float canonX = spriteCoordinates[VERTEX_INDEX_X];
final float canonY = spriteCoordinates[VERTEX_INDEX_Y];
Sprite sprite_in_fixedpoint_of_the_first_sprite=new Sprite(canonX,canonY,textureregion)
Get the minimum and maximum value of all the corners (for both - x and y components).
Then take average from max and min to get middle:
middleX = (maxX + minX) / 2
Repeat the same for y component.
Consider something like this
Rectangle test = new Rectangle(100, 100, 50, 100, vboManager);
mainScene.attachChild(test);
System.out.println("Before RotCtrX = " + test.getRotationCenterX());
System.out.println("Before RotCtrY = " + test.getRotationCenterY());
test.setRotation(45);
System.out.println("After RotCtrX = " + test.getRotationCenterX());
System.out.println("After RotCtrY = " + test.getRotationCenterY());
and the result are
System.out(4526): Before RotCtrX = 25.0
System.out(4526): Before RotCtrY = 50.0
System.out(4526): After RotCtrX = 25.0
System.out(4526): After RotCtrY = 50.0
AndEngine Entities rotate around the center (unless you change the RotationCenter values), so applying setRotate() will not affect the "center" point location
those "center" points are relative to the Entity, so if you need the actual screen coordinates, you will need to add those to the getX() and getY() values - which BTW also won't change based solely on applying a setRotate()
I figured out how to use getSceneCenterCoordinates() properly, which is to hand it a float[]. Here is my solution:
float[] objCenterPos = new float[2];
obj.sprite.getSceneCenterCoordinates(objCenterPos);
Log.d(this.toString(), "Coordinates: ("+objCenterPos[0]+","+objCenterPos[1]+")");

Rotate a Image to MousePos?

I want to rotate an Image in java, initialized with
playerimage = Toolkit.getDefaultToolkit().getImage("C:/Game/player.png"); //Load Player Image
drawed with:
Graphics2D g = buffer.createGraphics();
g.drawImage(playerimage, player.getX(), player.getY(), null); // Draw Player
Now, I want my playerimage, to rotate to my mouse, so it's basically looking to my mouse. How would I do this?
The first thing you'll need to do is get both the mouse pos and the player pos in the same coord system. When you get our mouse pos it will normally be in Screen Coords while your player maybe in your own 'World Coords' space. If the players position is tied directly to pixels then you can skip ahead.
Convert the Mouse Position to World coords..
mouseWorld.X = (mouseScreen.X / screenWidth) * worldWidth;
Once you are in the same coord system you need to find the angle required to rotate. This equation will change based on which way your Player art is facing, lets assume it is facing up the position X axis. Then you can just use the dot product to find the angle between where your player is facing and where the point is pointing.
The dot product is A(dot)B = mag(A) * mag(B) * cos (theta)
mag = magnitude of the vector
theta = angle between the two vectors
So if you normalize the vectors (make them length 1) then..
A(dot)B = 1 * 1 * cos(theta)
A(dot)B = cos(theta)
acos(A(dot)B) = theta
So lets do code...
Vector mouseVec(mouseWorld.X, mouseWorld.Y);
Vector playerVec(playerWorld.X, playerWorld.Y);
//You want to find the angle the player must turn, so pretend the player pos it the origin
mouseVec -= playerVec;
//Create a vector that represents which way your player art is facing
Vector facingVec(1, 0);
mouseVec.Normalize(); //Make their length 1
facingVec.Normalize();
double dotProd = mouseVec.dot(facing);
double angBetween = acos(dotProd);
then call 'rotate' and pass in the angBetween!
Double check that the units are correct, often acos will return 'radians' and the rotate function will take 'degrees' so you need to convert.
More vector info:
Vector Info

Categories

Resources