Ok, so I have tried many different approaches and I have landed with one that works some of the time. The idea is to get a bee sprite to move toward a flower sprite, here are the things I have accomplished with this so far:
- Bee can rotate to the left or right based on a movement speed
- Bee can move in the direction that it is rotated (by using the sin and cos of angle)
- Bee is sometimes able to make it to the flower and sometimes not (usually the flower is very close when this happens)
This is the working example:
The bee turns to the right and eventually hits the angle it is looking for in the condition and makes a beeline (no pun intended), for the flower.
On the other hand, when the flower is closer to the bees starting point (the middle of the screen):
It goes around the right side of the flower and down into the bottom of the window.
Here is the code for the bee class:
public class Bee {
public Vector2 position;
public Sprite sprite;
public float topSpeed = 300f;
public float xSpeed = 0f;
public float ySpeed = 500f;
public float rotationSpeed = 200f;
public float rotationAngle = 360f;
public float moveAngle;
public Vector2 flowerPosition;
public boolean collided = false;
public Bee(Texture img, Vector2 flowerVector) {
sprite = new Sprite(img);
sprite.setScale(2);
position = new Vector2(Gdx.graphics.getWidth()/2f - sprite.getWidth(),
Gdx.graphics.getHeight()/2f - sprite.getHeight());
flowerPosition = flowerVector;
}
public Rectangle getBoundingBox() {
return sprite.getBoundingRectangle();
}
public void updateCollided(boolean collidedBool) {
collided = collidedBool;
}
public boolean beeHittingRightWall() {
return position.x + sprite.getWidth() > Gdx.graphics.getWidth();
}
public boolean beeHittingLeftWall() {
return position.x < 0;
}
public boolean beeHittingTopWall() {
return position.y + sprite.getHeight() > Gdx.graphics.getHeight();
}
public boolean beeHittingBottomWall() {
return position.y < 0;
}
public void updateBeeCoordinates(float deltaTime) {
position.x += deltaTime * xSpeed;
position.y += deltaTime * ySpeed;
}
public void checkBeeHittingBorders() {
if(beeHittingRightWall()) {
position.x -= sprite.getWidth();
}
if(beeHittingLeftWall()) {
position.x += sprite.getWidth();
}
// Check if bee is hitting top and bottom walls
if(beeHittingTopWall()) {
position.y -= sprite.getHeight();
}
if(beeHittingBottomWall()) {
position.y += sprite.getHeight();
}
}
// gets quadrant of coordinate
public float getCoordinateQuadrantMinuend(float x, float y) {
float yAxis = Gdx.graphics.getWidth() / 2f;
float xAxis = Gdx.graphics.getHeight() / 2f;
if(x > yAxis && y > xAxis) {
return 90f;
}
else if(x > yAxis && y < xAxis) {
return 180f;
}
else if(x < yAxis && y < xAxis) {
return 270f;
}
else {
return 360f;
}
}
// gets the angle bee needs to be rotated to, to move to a certain coordinate
public float getPathfindingRotationAngle(float x1, float y1, float x2, float y2) {
float c = (y2 - y1) / (x2 - x1);
float minuend = getCoordinateQuadrantMinuend(x1, y1);
return minuend - MathUtils.atanDeg(c);
}
public float targetAngle() {
return 360 - getPathfindingRotationAngle(flowerPosition.x, flowerPosition.y, position.x, position.y);
}
public void moveForward(float deltaTime) {
if(!collided) {
moveAngle = targetAngle();
updateBeeCoordinates(deltaTime);
checkBeeHittingBorders();
}
}
public void rotateLeft(float deltaTime) {
rotationAngle += deltaTime*rotationSpeed;
if(rotationAngle > 360) {
rotationAngle -= 360;
}
}
public void rotateRight(float deltaTime) {
rotationAngle += 360 - deltaTime*rotationSpeed;
if(rotationAngle > 360) {
rotationAngle -= 360;
}
}
public void updateRotationAngle(float deltaTime) {
float myAngle = targetAngle();
if(rotationAngle > myAngle) {
rotateRight(deltaTime);
}
if(rotationAngle < myAngle) {
rotateLeft(deltaTime);
}
}
// This is called update velocity
// because velocity implies a speed and direction
// since it is a vector (this function does both of these)
public void updateVelocity() {
// Adjust X and Y speeds based on angle
/*
looks like this:
0
360
|
90____|____270
|
|
180
*/
float xSpeedMultiplier;
float ySpeedMultiplier;
if(rotationAngle < 360 && rotationAngle > 180) {
xSpeedMultiplier = Math.abs(MathUtils.sinDeg(rotationAngle));
}
else{
xSpeedMultiplier = -1 * (MathUtils.sinDeg(rotationAngle));
}
ySpeedMultiplier = MathUtils.cosDeg(rotationAngle);
xSpeed = topSpeed * xSpeedMultiplier;
ySpeed = topSpeed * ySpeedMultiplier;
}
public void Update(float deltaTime) {
moveForward(deltaTime);
updateRotationAngle(deltaTime);
updateVelocity();
}
public void Draw(SpriteBatch batch) {
Update(Gdx.graphics.getDeltaTime());
sprite.setPosition(position.x, position.y);
sprite.setRotation(rotationAngle);
sprite.draw(batch);
}
}
The main function I have been trying to debug is updateRotationAngle(float deltaTime).
Thank you in advance for any help.


Problematic scenario I can see in yours code is the angle comparison. In the scenario when current angle is 1° and target is 359°, then the bee would have to perform almost whole circle rotation. You should be calcuating the direction by this formula or similar way:
((myAngle-rotationAngle)%360+360+179)%360-179and then based on the fact if number is positive or negative change your direction.The other thing I see the use of atan function and I am not sure if you perform the quadrant correction right. The simplest thing you can do is to use
atan2Degfunction instead which doesn't require quadrant correction. The arguments will bey2 - y1, x2 - x1. Also I can see you are trying to perform some angle correction inupdateVelocity, which I am also not sure if is correct.