Page 2 of 2 FirstFirst 12
Results 21 to 22 of 22
  1. #21
    sonny's Avatar
    sonny is offline Senior Member
    Join Date
    Feb 2010
    Location
    North West England
    Posts
    146
    Rep Power
    0

    Default The Ball disappeared ????????????

    what with decorating and gardening I have had so little time

    i refined my collision points arraylist in Ball and I now have (i think) a getcollisions arraylist of GPoints that surrounds every pixel of the ball.
    and i added some more Bounce methods which are effectivley setter methods.

    So next I wanted to introduce some more angles into the gameplay. but, i didnt want the angles to be totally random. I wanted the angles to be based on the position of the ball relative to the paddle

    my intentions were:
    1. that if ball hits the middle of the 1/3rd of the bat the ball just bounces up at the same angle (the same xVel).
    2. if it hits the very edge (vertical edge) of the bat the ball gets sliced,
    3. if it hits the corner of the bat it gets sent back the way it came
    4. if it hits nearside middle third of the bat it gets checked[ the xvel gets reduced] or the ball squares up some
    5. and if it hits the far-side third of the bat the ball runs away [xvel increases]


    Unfortunately when i was testing, this did not always work as intended I figured that maybe this was because of either the (Xvel or Yvel) velocity of the ball taking the ball through the paddle. IE after detecting a collision with the paddle and taking action the ball or collisions points were still in contact with the paddle meaning that another course of action would be determined.
    so i tried to introduce introduce error correction in order that once the ball meets the paddle, the action of the ball is determined and should the collision points of ball be still in contact with the paddle the ball is moved up (-yVel)

    The problem after adding the error correction however is that now the ball sometimes becomes invisible after making the contact with the paddle. It does not get removed because it bounces up and removes more bricks but it is invisible????
    How can this be????
    Here is is the hit the ball method from the game
    Java Code:
    private void hitTheBall() {
    		paddleHits++;
    		Ball.bounceUp();
    		/* if the centre of the ball is below the face of the paddle*/
    		if (Ball.getBallCY() > paddle.getY()) {
    			Ball.sliceX();
    			
    		/* if the leading (x)edge of ball hits the near-side last third of the paddle*/
    		} else if ((Ball.getXVel() > 1 && (Ball.getX() + Ball.getWidth()) < xPaddle
    				- (PADDLE_WIDTH / 3))
    				|| (Ball.getXVel() < 1 && Ball.getX() > xPaddle
    						+ (PADDLE_WIDTH / 3))) {
    			Ball.bounceX();
    		/*if the leading edge of ball hits the nearside middle third of the paddle*/
    		} else if ((Ball.getXVel() > 1 && Ball.getBallCX() < xPaddle
    				- (PADDLE_WIDTH / 6))
    				|| (Ball.getXVel() < 1 && (Ball.getBallCX()) > xPaddle
    						+ (PADDLE_WIDTH / 6))) {
    			Ball.checkX();
    		/*if the leading edge of ball hits the farside middle third of the paddle*/
    		} else if ((Ball.getXVel() > 1 && Ball.getBallCX() > xPaddle
    				+ (PADDLE_WIDTH / 6))
    				|| (Ball.getXVel() < 1 && (Ball.getBallCX()) < xPaddle
    						- (PADDLE_WIDTH / 6))){
    			Ball.runningX();
    		}
    		/*Error correction*/
    		double diff = Ball.getHeight()-(paddle.getY()- Ball.getY())+1;
    		Ball.move(0, -diff);
    		Ball.sendToFront();
    
    	}
    and here is the Ball class

    Java Code:
    public class Ball extends GOval {
    	private double radius;
    		
    	private double xVel;
    	private double yVel;
    	private double maxVel;
    	
    	public Ball(double x, double y, double radius) {
    		super(x - radius, y - radius, radius * 2, radius * 2);
    		this.setFilled(true);
    		this.setColor(Color.WHITE);
    		this.setFillColor(Color.WHITE);
    		this.radius = radius;
    		maxVel = 5;
    		xVel = 3;
    		yVel = -3;
    	}
    	
    //	(x - cx)^2 + (y - cy)^2 = rad^2 	
    //	(y - cy)^2 = rad^2 - (x - cx)^2
    //	y - cy = sqrt(rad^2 - (x - cx)^2) or -sqrt(rad^2 - (x - cx)^2)
    //	y = cy + sqrt(rad^2 - (x - cx)^2) or cy - sqrt(rad^2 - (x - cx)^2)
    //	This gives the two values for y at any x
    	
    	public ArrayList<GPoint> getCollisions() {
    		ArrayList<GPoint> collisionPoints = new ArrayList<GPoint>(); 
    		int collisionRadius = (int) radius + 1;
    		int leftCollisionPoint = (int) this.getX() - 1;
    		int rightCollisionPoint = leftCollisionPoint + (2 * collisionRadius);
    		for (int x = leftCollisionPoint; x <= rightCollisionPoint; x++) {
    			double y = Math.sqrt((collisionRadius * collisionRadius)
    					- ((x - this.getBallCX()) * (x - this.getBallCX())));
    			collisionPoints.add(new GPoint(x, this.getBallCY() + y));
    			collisionPoints.add(new GPoint(x, this.getBallCY() - y));
    		}
    		return collisionPoints;
    		
    	} 
    	
    	public double getXVel() {
    		return xVel;
    	}
    
    	public void setXVel(double xVel) {
    		this.xVel = xVel;
    	}
    
    	public double getYVel() {
    		return yVel;
    	}
    	
    	public void setYVel(double yVel) {
    		this.yVel = yVel;
    	}
    	
    	
    	public double getMaxVel() {
    		return maxVel;
    	}
    
    	
    	public void setMaxVel(double maxVel) {
    		this.maxVel = maxVel;
    	}
    
    
    	
    	public void setRadius(double radius) {
    		this.radius = radius;
    	}
    
    	public double getBallCX(){
    		return this.getX() + radius;
    	}
    	
    	public double getBallCY(){
    		return this.getY() + radius;
    	}
    	
    	public GPoint getBallCenter(){
    		return new GPoint(this.getBallCX(), this.getBallCY());
    		
    	}
    	public void bounceX(){
    		xVel = -xVel;
    	}
    	public void bounceY(){
    		yVel = -yVel;
    	}
    	public void bounceUp(){
    		yVel = Math.abs(yVel);
    		bounceY();		
    	}
    	
    	public void bounceDown(){
    		yVel = Math.abs(yVel);
    	}
    	
    	public void bounceRight(){
    		xVel = Math.abs(xVel);
    		bounceX();
    	}
    	
    	public void bounceLeft(){
    		xVel = Math.abs(xVel);
    	}
    	
    	[B]public void sliceX() {
    		if (xVel > 1) {
    			xVel = maxVel;
    		} else if (xVel < -1) {
    			xVel = -maxVel;
    		}
    	}
    
    	public void checkX() {
    		if (xVel > 1) {
    			xVel--;
    		} else if (xVel < -1) {
    			xVel++;
    		}
    	}
    
    	public void runningX() {
    		if (xVel > 1 && xVel < maxVel) {
    			xVel++;
    		} else if (xVel < -1 && xVel > -maxVel) {
    			xVel--;
    		}
    		
    	}[/B]
    }
    Last edited by sonny; 05-04-2010 at 09:36 PM.
    :p I still have my "L" plates on...... directions and explanations are far more help than blaring your Horn! :p Watching:CS106a on YouTube \Reading The Art & Science of Java by Eric S Roberts

  2. #22
    sonny's Avatar
    sonny is offline Senior Member
    Join Date
    Feb 2010
    Location
    North West England
    Posts
    146
    Rep Power
    0

    Thumbs up Have Got the Ball Back!!!!!!

    It finally occurred to me that although the ball appeared to have become invisible I had in fact removed it. at least I think so, ball is an instance variable in the main game so although it had been removed the instance variable was still being moved in the main method and checking for collisions around it,, at least i think thats what happened??
    I added if (gobj != ball) into the else condition in the checkforcollisions() method and hey presto no more disappearing ball.:D

    Java Code:
    else if (gobj != ball){
    			remove(gobj);
    			bricksLeft--;
    			ball.bounceY();
    		}
    I got my sliceX() checkX() and runningX() bounce methods to work... sort of...
    i couldnt work out why when I had set the Xvel to increase or decrease by one; when testing the game, the xVel was changing by two or three and sometimes as much as five when the ball hit the paddle!!
    I figured this was because the ball edge had passed the paddle edge before the collision was detected and effectivley the ball was colliding with the paddle on its way back up so i re-wrote the error correction

    Java Code:
    /*Error correction*/
    		while(ball.getY()+ball.getHeight() > paddle.getY()-1){
    		ball.move(ball.getXVel(),ball.getYVel());
    		pause(delay);
    		}
    i figured this would move the ball up beyond the face of the paddle plus, an extra pixel to allow for the collision points, meaning i should then only get one collision and the xVel would increase or decrease by one.
    No Such Luck!!!!

    After a lot of altering variables and testing I could'nt figure it out:mad: so i thought i would mess about with the BrickFormation class and ArrayLists for a bit instead.. and whilst so doing it hit me!

    the reason for xVel increasing by so many is to do with the for each loop getCollisions() method. a ball with radius five pixels, checks a radius of 6 pixels around the ball thats a diameter 0f 13 pixels inclusive, with 2 GPoints for every pixel is 26 GPoints around the ball. when the ball hits the paddle more than one of these points is in contact with the paddle. and for each GPoint xVel increases or decreases because of the hit the ball method.
    The error corection wont solve the problem, in fact thats what caused the ball to be removed,, the ball was moved before the for each loop had completed meaning that the ball was now an element at one of the points in the loop so it was removed.... At least I think so......

    So what i need to do next is work out how to stop the for each loop once an element once the paddle appears as a getElementAt in the Gpoint ArrayList...
    sonny is thinking....

    or perhaps just add a local variable to the method and increase it whenever theres a hit on the paddle.


    now in addition to implementing the BrickFormation class
    I have smartend up the code somewhat, so much easier to follow
    my sliceX bounceX and runningX all work perfectly
    and also I added a method which alters the points on the paddle which determines the the angle at which the ball is hit back. making a bit easier to straighten up the ball after a sliceX hit.

    TA DA!
    Java Code:
    	private void checkForCollision() {
    		int paddleCollision = 0;
    		for (GPoint points : ball.getCollisions()) {
    			gobj = getElementAt(points);
    			if (gobj != null && gobj != ball) {
    				if (gobj == paddle) {
    					paddleCollision++;
    				} else {
    					remove(gobj);
    					bricksLeft--;
    					ball.bounceY();
    				}
    			}
    		}
    		if (paddleCollision > 0) {
    			hitTheBall();
    
    		}
    	}
    
    	private void hitTheBall() {
    		paddleHits++;
    		ball.bounceUp();
    		paddleDivision();
    		/* if the centre of the ball is below the face of the paddle */
    		if (ball.getBallCY() > paddle.getY()) {
    			ball.sliceX();
    		} else if (nearSideEdgeHit()) {
    			ball.bounceX();
    		} else if (nearSideMidHit()) {
    			ball.checkX();
    		} else if (farSideMidHit()) {
    			ball.runningX();
    		}
    		postHitErrorCorrection();
    
    	}
    
    // this needs doing better without the numbers
    	private void paddleDivision() { 
    		if (ball.getXVel() > ball.getYVel()) {
    			padAngDiv = PADDLE_WIDTH / 10;
    			padRetDiv = PADDLE_WIDTH / 2.5;
    		} else {
    			padAngDiv = PADDLE_WIDTH / 6;
    			padRetDiv = PADDLE_WIDTH / 3;
    		}
    	}
    
    	/**
    	 * @return returns true if the leading edge of ball hits the near-side edge
    	 *         of the paddle
    	 */
    	private boolean nearSideEdgeHit() {
    		return (ballGoingLeft() && (ball.getBallCX()) < xPaddle - padRetDiv)
    				|| (ballGoingRight() && ball.getBallCX() > xPaddle + padRetDiv);
    	}
    
    	/**
    	 * @return returns true if if the leading edge of ball hits the near-side
    	 *         middle section of the paddle
    	 */
    	private boolean nearSideMidHit() {
    		return (ballGoingLeft() && ball.getBallCX() < xPaddle - padAngDiv)
    				|| (ballGoingRight() && (ball.getBallCX()) > xPaddle
    						+ padAngDiv);
    	}
    
    	/**
    	 * @return returns true if if the leading edge of ball hits the far-side
    	 *         middle section of the paddle
    	 */
    	private boolean farSideMidHit() {
    		return (ballGoingLeft() && ball.getBallCX() > xPaddle + padAngDiv)
    				|| (ballGoingRight() && (ball.getBallCX()) < xPaddle
    						- padAngDiv);
    	}
    
    	private boolean ballGoingRight() {
    		return ball.getXVel() < 0;
    	}
    
    	private boolean ballGoingLeft() {
    		return ball.getXVel() > 0;
    	}
    
    	private void postHitErrorCorrection() {
    		while (ball.getY() + ball.getHeight() > paddle.getY() - 1) {
    			ball.move(ball.getXVel(), ball.getYVel());
    			pause(delay);
    		}
    	}
    :p I still have my "L" plates on...... directions and explanations are far more help than blaring your Horn! :p Watching:CS106a on YouTube \Reading The Art & Science of Java by Eric S Roberts

Page 2 of 2 FirstFirst 12

Similar Threads

  1. Need help with Breakout game
    By tfitz666 in forum New To Java
    Replies: 9
    Last Post: 03-22-2010, 06:26 AM
  2. Replies: 1
    Last Post: 08-11-2009, 03:00 PM
  3. Another Breakout question
    By jumpstart in forum New To Java
    Replies: 3
    Last Post: 07-29-2009, 05:48 AM
  4. Making A Set Of Classes "Importable"
    By JDCAce in forum Advanced Java
    Replies: 4
    Last Post: 12-05-2008, 10:11 AM
  5. Need help with Java classes for making a program.
    By TheDarkReverend in forum Advanced Java
    Replies: 2
    Last Post: 11-28-2008, 05:50 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •