This site requires JavaScript, please enable it in your browser!
Greenfoot back
JasonZhu
JasonZhu wrote ...

2013/12/2

Rounding Error

1
2
JasonZhu JasonZhu

2013/12/2

#
I was coding a physics based platform game when came to notice that my player is not behaving accordingly in relation to my code. I explored every possibility in debugging based off my own code and I came with the conclusion that it's greenfoot's rounding. Anyone know how greenfoot rounds numbers?
erdelf erdelf

2013/12/2

#
Greenfoot rounds numbers`? that would be new for me
davmac davmac

2013/12/2

#
Could you make the question a bit more specific? What exactly are you seeing that you didn't expect?
JasonZhu JasonZhu

2013/12/2

#
It appears so... If I post my code, hopefully you might find a code issue, but I feel as if I exhausted every possibility...
JasonZhu JasonZhu

2013/12/2

#
    private void movement()
    {
        Object platformVertical1 = getOneObjectAtOffset(getImage().getWidth()*-1,0,Platform.class);     
        Object platformVertical2 = getOneObjectAtOffset(getImage().getWidth(),0,Platform.class);     
        Object nearestPlatform = getOneObjectAtOffset(0,getImage().getHeight()/2,Platform.class);
        if(ignoreSpaceBarInterval>0)ignoreSpaceBarInterval--;
        if(nearestPlatform == null || feetGhostingInterval > 0){
            addForce(GRAVITY);
            if(feetGhostingInterval>0)feetGhostingInterval--;
            tactileResponse(true);
        }else if(((Platform)nearestPlatform).across&&ignoreSpaceBarInterval==0){
            setLocation(getX(),((Platform)nearestPlatform).getY()-((Platform)nearestPlatform).getImage().getHeight()-getImage().getHeight()/2+4);
            feetGhostingInterval = 0;
            if(getMovement().getDirection() < 90 && getMovement().getDirection() > 0){
                getMovement().setDirection(0);
            }else if(getMovement().getDirection() > 90 && getMovement().getDirection() < 180){
                getMovement().setDirection(180);
            }
            tactileResponse(false);
            if(uncontrolled)getMovement().scale(FRICTION);
        }
        if(platformVertical1!=null||platformVertical2!=null){
            getMovement().revertHorizontal();
        }
        getMovement().setLength(Math.max(Math.min(getMovement().getLength(),2.0),-2.0)); //Terminal Velocity
        move();     
    }

    private void tactileResponse(boolean inAir)
    {
        uncontrolled = true;
        if(inAir)return;
        if(Greenfoot.isKeyDown("a")){
            if(inAir){
                addForce(AIRLEFT); 
            }else{
                addForce(LEFT);
            }
            uncontrolled = false;
            walkState++;    
            if(walkState>15){
                walkState=0;
            }
        }
        if(Greenfoot.isKeyDown("d")){
            if(inAir){
                addForce(AIRRIGHT); 
            }else{
                addForce(RIGHT);   
            }
            uncontrolled = false;
            walkState++;
            if(walkState>15){
                walkState=0;
            }
        }
        if(Greenfoot.isKeyDown("s") && !inAir){
            uncontrolled = false;
            feetGhostingInterval += 10;
        }
        if(!inAir && Greenfoot.isKeyDown("space") && ignoreSpaceBarInterval == 0){
            uncontrolled = false;
            addForce(JUMP);
            ignoreSpaceBarInterval += 5;
        } 
        walkFrame(walkState);          
    }    
When I hold the space bar without touching either the "a" or "d" key, my player jumps to the right by itself.
danpost danpost

2013/12/2

#
Looks like a lot of excessive code, here. Line 32 should eliminate the need to check the value of 'inAir' throughout the rest of the method (for sure on line 34 and if the method 'addForce' does not change its value then also on lines 46, 57 and 61). I wonder if the value of 'walkState' needs tweaked when jumping or if the 'addForce' method is wrongfully used in the 'jumping' section of the code.
JasonZhu JasonZhu

2013/12/2

#
walkState is purely to change the image of the player. The inAir was only for debugging and I forgot to remove it (thanks for the reminder). The problem is still persistent.
danpost danpost

2013/12/2

#
Please show the code for the 'addForce' method and explain what you use it for.
JasonZhu JasonZhu

2013/12/2

#
    public void addForce(Vector force) 
    {
        movement.add(force);
    }
Used to add a Vector(parameter angle, parameter velocity) to the current. And this is from the Vector class:
    public void add(Vector other) 
    {
        dx += other.dx;
        dy += other.dy;
        updatePolar();
    }
    private void updatePolar() 
    {
        this.direction = (int) Math.toDegrees(Math.atan2(dy, dx));
        this.length = Math.sqrt(dx*dx+dy*dy);
    }   
danpost danpost

2013/12/2

#
What are the values of 'JUMP', 'LEFT', and 'RIGHT'? (both dx and dy of all three)
JasonZhu JasonZhu

2013/12/3

#
private static final Vector LEFT = new Vector(180,0.075); private static final Vector RIGHT = new Vector(0,0.075); private static final Vector JUMP = new Vector(270,5);
JasonZhu JasonZhu

2013/12/3

#
I guess this is an unfixable error...
danpost danpost

2013/12/3

#
I cannot, with what is given, determine why it is behaving in the manner you explained. Maybe if you uploaded the scenario (checking the 'Publish source code' checkbox), someone can figure out what is going on.
JasonZhu JasonZhu

2013/12/3

#
Sure dan, thanks for all your help. By the way, I was agonizing over making an image mirrorHorizontally only once in an act method. Is this possible?
JasonZhu JasonZhu

2013/12/3

#
Righty, I have it uploaded : http://www.greenfoot.org/scenarios/10258
There are more replies on the next page.
1
2