• 0

Logic problem in lingdx game development java


Question

public class Ball {
    private boolean ballIsUp=false;
    public float angle;

    private static float radius;

    private static Circle ball;

    private static float calculationX;
    private static float calculationY;

    private static final int MAX_X_VELOCITY=20;
    private static final int MAX_Y_VELOCITY=20;


    public static float InnerInnerCircleRadius;

    private static final float DEFAULT_RADIUS=20f;

    boolean isJumping=false;
    public final static float MAX_JUMP_RADIUS=GameScreen.INNER_CIRCLE_RADIUS-100f;
    public final static int JUMP_SPEED=4;
    public final static float MIN_JUMP_RADIUS=GameScreen.INNER_CIRCLE_RADIUS-DEFAULT_RADIUS;
    public final static int GRAVITY_SPEED=2;

    public Ball(){
        InnerInnerCircleRadius =GameScreen.INNER_CIRCLE_RADIUS-DEFAULT_RADIUS;
        float x= GameScreen.SCREEN_WIDTH/2;
        float y= GameScreen.SCREEN_HEIGHT/2-GameScreen.INNER_CIRCLE_RADIUS+DEFAULT_RADIUS-InnerInnerCircleRadius;
        radius= DEFAULT_RADIUS;

        ball=new Circle(x, y, radius);
    }

    public void gravity(){
        if(InnerInnerCircleRadius<MIN_JUMP_RADIUS){
            InnerInnerCircleRadius+=GRAVITY_SPEED;
        }else{
            isJumping=false;
        }
    }

   public void jump(){
       if(!isJumping){
           if(InnerInnerCircleRadius>=MAX_JUMP_RADIUS){
               InnerInnerCircleRadius-=JUMP_SPEED;
           }
       }
   }

    public Ball(float x, float y, float radius){
        ball.x=x;
        ball.y=y;
        this.radius=(radius!=0)?radius:DEFAULT_RADIUS;

        ball=new Circle(x, y, radius);


        InnerInnerCircleRadius =GameScreen.INNER_CIRCLE_RADIUS-ball.radius;
    }

    public void drawDebug(ShapeRenderer shapeRenderer){
        shapeRenderer.setColor(Color.WHITE);
        shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.circle(ball.x, ball.y, ball.radius);
        shapeRenderer.set(ShapeRenderer.ShapeType.Line);
        shapeRenderer.line(GameScreen.mainCircle.x, GameScreen.mainCircle.y, 0,
                ball.x, ball.y, 0);

    }

    public void setXPosition(float dx){

        if(!isJumping) {
            if (ballIsUp) {
                ball.x += dx;
            } else {
                ball.x -= dx;
            }
        }

        

    }

    public void setYPosition(){

        if(!isJumping) {
            if (ball.x - GameScreen.mainCircle.x >= InnerInnerCircleRadius ||
                    GameScreen.mainCircle.x - ball.x >= InnerInnerCircleRadius) {
                ballIsUp = !ballIsUp;
            }
            ball.y = ((float) Math.sqrt((InnerInnerCircleRadius * InnerInnerCircleRadius) - ((ball.x - GameScreen.mainCircle.x)
                    * (ball.x - GameScreen.mainCircle.x))) + GameScreen.mainCircle.y);

            if (!ballIsUp) ball.y = 2 * GameScreen.mainCircle.y - ball.y;
        }
    }

    public void update(float delta){
        setYPosition();
        findAngle();
        printDebugMessages();
        gravity();
    }

    public void findAngle(){
        Vector2 center=new Vector2(GameScreen.mainCircle.x, GameScreen.mainCircle.y);
        Vector2 controlPoints=new Vector2(GameScreen.mainCircle.x+InnerInnerCircleRadius, GameScreen.mainCircle.y);
        Vector2 newPoint=new Vector2(ball.x, ball.y);
        float m1=(controlPoints.y-center.y)/(controlPoints.x-center.x);
        float m2=(newPoint.y-center.y)/(newPoint.x-center.x);
        angle=((float)(Math.atan(m1)-Math.atan(m2)))*630/11;
        Gdx.app.log("findAngle()", ""+angle);
    }
}

I have been stuck on this problem for days now. This is a simple ball game. The problem is that I want to make the ball jump. The ball is inside a much bigger circle. This is the screenshot https://postimg.org/image/ru0os2jer/  or Untitled.png

 

I will try to explain my code as much as possible. Firstly whenever the user inputs data, the setXPosition() is called, now this method just sets the X Position without considering the angle etc. Then setYPosition() is called through the update() which automatically sets the Y position based on the X position. now, this is a little bad way of doing this, because X position doesnt change relative to the angle, which it should. it makes the ball's Y position faster at sides and slower in the middle. Now, when it jumps, the jump() method is called. and the gravity() method is called whenever update() is called. the *630/11 is a little wrong, i have fixed it since then and it is being used to convert radians into degrees, now i am using Math.toRadians. the GameScreen.mainCircle is the bigger circle in the screenshot (the white one) .Then InnerInnerCircleRadius is just the radius at which the ball is drawn(basically, it is GameScreen.mainCircle-ball.radius)., I have used a different radius (GameScreen.INNER_CIRCLE_RADIUS), but that is just the GameScreen.mainCircle again. I hope the Game Screen code is not necessary so I have not posted it. if yout think it is, please tell me and I will post it. There are a few idiotic variables. please dont pay attention to them, I created them in desperation. I am still a very beginner programmer. and though, I have made games in libgdx before, nothing this complicated. I have tried everything, and couldn't solve it. according to me, the ball's X position should change when it jumps but it doesnt. The Y position changes perfectly. In setting the X position, the code should take in account either the angle or the InnerInnerCircleRadius. any help is appreciated. 

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Well this code doesn't make much sense to me, so I couldn't pinpoint exactly what needs to be changed to "fix" it. I'll point out what's wrong with it and hopefully that'll help you write something that works.

 

General coding issues:

 

1) The class has too many public members; it is unclear how it is intended to be used. Do you really expect outside code to call findAngle, gravity? Should outside code modify InnerInnerCircleRadius?

2) It makes no sense to have static non-final fields; this creates global mutable state which is probably a mistake.

3) The angle variable is set but never used.

4) isJumping is used in several conditional statements, but it's always false.

5) The code is written using shared mutable state spread across many functions, which makes it easy to commit mistakes like the ones just mentioned, and hard to understand. 

 

Ideas on how to write this in a simple, robust way:

 

1) This is a physical problem. Model it using the least possible amount of physical properties and nothing else. Only the ball's position and speed change; everything else is a constant. Jumping means giving vertical speed. Applying gravity means reducing it. At each step simply apply speed to the current position. If the outer circle can move (unclear from your problem description), then you need that circle's position too. Get rid of all booleans and other variables.

2) Favor writing functions that don't modify any fields; use their return value instead. For example, your findAngle() function could return the angle rather than set a variable that contains the angle. This will greatly clarify code flow and make it easier to reason about what's going on at any point in time.

Link to comment
Share on other sites

This topic is now closed to further replies.