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

2013/3/15

Question about pinball game

1
2
3
maartendrift maartendrift

2013/3/15

#
I'm new with Greenfoot. I'm trying to make a pinball game for school. But now I got a problem. To make the ball move more fluently I want to use a float to set the new Location. But now I got stuck: When I use the following code I get an error: setLocation(int, int) in greenfoot.Actor can not be applied to (int, float).
float newY = Math.round(yPosition + motionY);
               
setLocation(xPosition,(float)(newY));
I know I get this error because there's a float in the parameter of setLocation. I have to cast (is that the right word) the newY, so that the setLocation does accept it. But I forget how to do that. Who can help me?
Gevater_Tod4711 Gevater_Tod4711

2013/3/15

#
You have to cast (it is the right word) the value to an int not to float. If you change your code like this:
float newY = Math.round(yPosition + motionY);
setLocation(xPosition, (ínt) newY);  
It will work but probably not the way you want it to. If you cast the float down to an integer the movement will be not fluently because after casting it the value is an integer again. If you want to make your movement more fluently you have to use new values for the location:
private double exactX;
private double exactY;


public void setLocation(int x, int y) {
    exactX = x;
    exactY = y;
    super.setLocation(x, y);
}
    
public void setLocation(double x, double y) {
    exactX = x;
    exactY = y;
    super.setLocation((int) x, (int) y);
}

public double getX() {
    return exactX;
}
public double getY() {
    return exactY;
}
If you overwrite the setLocation method of Actor with this methods you can use the setLocation method with a double or float value. Also now the getX() and getY() methods will return double values. The actor will still be moved the way it was before but the values of the coordinates are now double what means if you make your object move 0.5 cells in a direction two times it will now not move 2 cells (like it would be without the double values) but only one cell.
maartendrift maartendrift

2013/3/15

#
Wow! It works! Thank you!
maartendrift maartendrift

2013/3/16

#
And now another question. When the Ball comes down on a line or a Paddle, I want that the Ball bounces like this: http://i1045.photobucket.com/albums/b453/maartendri/hoek_zps2be655f8.png So: corner i = corner t. Which way is the easiest way to do this?
Gevater_Tod4711 Gevater_Tod4711

2013/3/16

#
That depends on how your movement works. Do you use the move method and the rotation of the ball to let him move or do you use movement in x and y direction?
maartendrift maartendrift

2013/3/16

#
I use the method in x and y direction.
Gevater_Tod4711 Gevater_Tod4711

2013/3/16

#
Then it's easy. You just have to set the values of movement to the negative values. So if your ball hits the right or left wall you have to set the x value to the negative values and if you hit the other walls you do the same with the y values.
maartendrift maartendrift

2013/3/16

#
Thank you. Does it also work when there's a slanting line?
Gevater_Tod4711 Gevater_Tod4711

2013/3/16

#
No then it'll not work. But I'm not shure how you can do this. Maybe google can help you there.
maartendrift maartendrift

2013/3/16

#
I will try! Thank you!
maartendrift maartendrift

2013/3/16

#
Then I got a next question, and maybe it is the hardest one! When my Ball bounces on the Paddle and I push the key too long down, then I got a Null Pointer Exception. How can I solve this? This is my code of the right Paddle, when I know the right one. I know the left one.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Right here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Right extends Flippers
{
    private boolean isDown;
    /**
     * Act - do whatever the Right wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    public Right()
    {
        this(30);
    }
    
    public Right(int rotation)
    {
        setRotation(getRotation()-rotation);
    }
    
    public void act()
    {
        rotatePaddle();
    }    
    
    public void rotatePaddle()
    {
        if (!isDown && Greenfoot.isKeyDown("right"))
        {
            isDown = true;
            int xPosition = this.getX();
            int yPosition = this.getY();
            for(int i = 0; i <=60; i++)
            {
                setRotation(getRotation()+1);
            }
                
            int newX = xPosition + 10;
            int newY = yPosition - 50;
            
            setLocation(newX, newY);
        }
        if (isDown && !Greenfoot.isKeyDown("right"))
        {
            isDown = false;
            
            for(int i = 0; i <=60; i++)
            {
                setRotation(getRotation()-1);
            }
           
            int xPosition = this.getX();
            int yPosition = this.getY();
       
            int newX = xPosition - 10;
            int newY = yPosition + 50;
           
            setLocation(newX, newY);
        }
    }
}
Who can help me?
Gevater_Tod4711 Gevater_Tod4711

2013/3/16

#
Where exactly is the NullPointerException? That would be very helpfull. And a suggestion for improvement:
for(int i = 0; i <=60; i++) {  
    setRotation(getRotation()-1);  
}  
This code will probably not work like you want it to. The paddle will rotate 60 times but in one act cycle so you can't see that it's rotating 60. You just can see that it rotates 60 degrees one time. To make the paddle move 60 times you have to add a counter that counts the acts and set's the rotation only a fiew degrees per act.
maartendrift maartendrift

2013/3/16

#
The Null Pointer Exception error occurs when I push the key (in this case "right") too long in when the ball is at the Paddle. Thank you for the code. I will use it!
Gevater_Tod4711 Gevater_Tod4711

2013/3/16

#
Are you shure the NullPointerException occurs in this class? I can't see anything that could throw such an exception. When the NullPointerException occurs in the terminal window it is a link. If you click this link you can exactly see where the NullPointerException comes from.
maartendrift maartendrift

2013/3/16

#
Now the Null Pointer Exception doesn't occur. And I don't know I did to fix it. Now there occurs an Illegal State Exception.
java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. at greenfoot.Actor.failIfNotInWorld(Actor.java:656) at greenfoot.Actor.getX(Actor.java:157) at Ball.checkSide(Ball.java:198) at Ball.moveBall(Ball.java:59) at Ball.act(Ball.java:44) at greenfoot.core.Simulation.actActor(Simulation.java:507) at greenfoot.core.Simulation.runOneLoop(Simulation.java:470) at greenfoot.core.Simulation.runContent(Simulation.java:204) at greenfoot.core.Simulation.run(Simulation.java:194)
The code of the Ball is the following:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.lang.Math;

/**
 * Write a description of class Ball here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Ball extends Actor
{
    private double motionY;
    private double fired;
    private int motionX;
    public int removed;
    private double rightDown;
    private double leftDown;
    private boolean hitFlipper;
    private int changeMotionX;
    
    public Ball()
    {
        this(0.0);
    }
    
    public Ball(double speed)
    {
        motionY = -speed;
        motionX = 0;
        fired = 0;
        removed = 0;
        rightDown = 0;
        leftDown = 0;
        hitFlipper = true;
    }

    /**
     * Act - do whatever the Ball wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
       
    public void act() 
    {
        moveBall();      
    }
    
    public void moveBall()
    {
        int xPosition = this.getX();
        double yPosition = this.getY();
        
        simulateGravity();
        checkForSpringle();
        fire();
        checkForLine();
        checkForCirkel();
        checkForBlock();
        checkForFlipper();
        checkSide();
        checkEnd();
        
        float newY = Math.round(yPosition + motionY);
        int newX = xPosition + motionX;
               
        setLocation(newX,(int)newY);
        
        if (fired != 0)
        {
            ATM myATM = (ATM) getWorld();
            myATM.addScore();
        }
        
        changeMotionX++;
        changeMotionX();
    }
    
    private void changeMotionX()
    {
        if(changeMotionX == 50 && getX() != 460)
        {
            motionX = -(1 + Greenfoot.getRandomNumber(5));
        }
    }
    
    private void fire()
    {
        if (getX()==460 && Greenfoot.isKeyDown("space"))
        {
            fired++;
        }
        
        if (fired == 500)
        {
            fired = 500;
        }
    }
    
    private void checkForSpringle()
    {
        Actor actor = getOneIntersectingObject(Springle.class);
        if (actor != null)
        {
            motionY = (-0.3 * fired);
        }
    }
    
    private void simulateGravity()
    {
        if (fired >= 1)
        {
            if (motionY < 0)
            {
                motionY = motionY - (motionY * 0.005);
            }
        
            if (motionY > -0.5 && motionY <= 0)
            {
                motionY = 0.48;
            }
            
            if (motionY > 0)
            {
                motionY = motionY + (motionY * 0.005);
            }
        }  
    }
    
    private void checkForLine()
    {
        Actor line = getOneIntersectingObject(Line.class);
        if (getX() <= 500 && getX() >=430)
        {
            if (line != null)
            {
                motionX = -(1 + Greenfoot.getRandomNumber(3));
                motionY = -motionY;
                ATM myATM = (ATM) getWorld();
                myATM.addFiveScore();
            }
        }
        else
        {
            if (line != null)
            {
                motionX = -motionX;
            }
        }
        if (line != null && getY() >=420)
        {
            motionY = -motionY;
        }
    }
    
    private void checkForCirkel()
    {
         Actor cirkel = getOneIntersectingObject(Cirkel.class);
         if (cirkel != null)
         {
             motionX = -motionX;
             motionY = -motionY;
             ATM myATM = (ATM) getWorld();
             myATM.addFiveScore();
         }
    }
    
    private void checkForBlock()
    {
         Actor block = getOneIntersectingObject(Block.class);
         if (block != null)
         {
             motionX = -motionX;
             ATM myATM = (ATM) getWorld();
             myATM.addFiveScore();
         }
    }
    
    private void checkSide()    
    {
        World world = getWorld();
        Ball ball = new Ball();
        Springle springle = new Springle();
        
        if (getY() == 7)
        {
            motionY = -motionY;
            ATM myATM = (ATM) getWorld();
            myATM.addFiveScore();
        }
        
        if (getY() >= (world.getHeight() - 10))
        {
            world.removeObject(this);
            world.addObject(ball, 460, 530);
            removed++;                 
        }
        
        if (getX() <= 7 || getX() >= (getWorld().getWidth()-7))
        {
            motionX = -motionX;
        }
    }
    
    private void checkForFlipper()
    {
        Actor right = getOneIntersectingObject(Right.class);
        if (right != null && hitFlipper)
        {
            motionY = -motionY;
            motionX = -motionX;
            hitFlipper = false;
                        
            if(Greenfoot.isKeyDown("right"))
            {
                rightDown = rightDown + 0.3;
            }
            else
            {
                rightDown = 1;
            }
            
            if (rightDown == 2)
            {
                rightDown = 1.9;
            }
            
            motionY = (2-rightDown) * motionY;
            ATM myATM = (ATM) getWorld();
            myATM.addTenScore();
        }
        
        Actor left = getOneIntersectingObject(Left.class);
        if (left != null && hitFlipper)
        {
            motionY = -motionY;
            motionX = -motionX;
            hitFlipper = false;
            
            if(Greenfoot.isKeyDown("left"))
            {
                leftDown = leftDown + 0.3;
            }
            else
            {
                leftDown = 1;
            }
            
            if (rightDown == 2)
            {
                leftDown = 1.9;
            }
            
            motionY = (2-leftDown)*motionY;
            ATM myATM = (ATM) getWorld();
            myATM.addTenScore();
        }
        
        if (getY() <=530)
        {
            hitFlipper = true;
        }
    }
    
    private void checkEnd()
    {
        if(removed == 3)
        {
            
        }
    }
}
There are more replies on the next page.
1
2
3