/** * Moves the paddle left by the movement offset field within the picture window's bounds avoiding * the given ball * * @param pict is the Picture object with the boundary to keep the paddle within * @param ball is a ball that causes the paddle to move back if it's in the way */ public void moveLeft(JFrame pict, Ball ball) { this.x -= this.offset; // Move x left by the offset // Test to see if the paddle moved into the ball if (ball.distance(this.x, this.y) < ball.getRadius() || ball.distance(this.x, this.y + this.height / 2) < ball.getRadius() || ball.distance(this.x, this.y + this.height) < ball.getRadius()) this.x += this.offset; // If so, move it out of the ball // Test to see if the boundary was in the way to the left if (this.x < 0) this.x = 0; // If so, set left of paddle to zero }
public boolean collidesWith(Ball ball) { boolean hasEnteredIf = false; if (ball.getX() - ball.getRadius() <= this.x1 || ball.getX() + ball.getRadius() >= this.x2) { ball.reflectHorizontal(); hasEnteredIf = true; } if (ball.getY() - ball.getRadius() <= this.y1 || ball.getY() + ball.getRadius() >= this.y2) { ball.reflectVertical(); hasEnteredIf = true; } return hasEnteredIf; }
/** * Moves the paddle up by the movement offset field within the picture window's bounds avoiding * the given ball * * @param pict is the Picture object with the boundary to keep the paddle within * @param ball is a ball that causes the paddle to move back if it's in the way */ public void moveUp(JFrame pict, Ball ball) { this.y -= this.offset; // Move y up by the offset // Test to see if the paddle moved into the ball if (ball.distance(this.x, this.y) < ball.getRadius() || ball.distance(this.x + this.width / 2, this.y) < ball.getRadius() || ball.distance(this.x + this.width, this.y) < ball.getRadius()) this.y += this.offset; // If so, move it out of the ball // Test to see if the boundary was in the way above if (this.y < 0) this.y = 0; // If so, set top of paddle to zero }
/** * Moves the paddle right by the movement offset field within the picture window's bounds avoiding * the given ball * * @param pict is the Picture object with the boundary to keep the paddle within * @param ball is a ball that causes the paddle to move back if it's in the way */ public void moveRight(JFrame pict, Ball ball) { this.x += this.offset; // Move x right by the offset // Test to see if the paddle moved into the ball if (ball.distance(this.x + this.width, this.y) < ball.getRadius() || ball.distance(this.x + this.width, this.y + this.height / 2) < ball.getRadius() || ball.distance(this.x + this.width, this.y + this.height) < ball.getRadius()) this.x -= this.offset; // If so, move it out of the ball // Test to see if the boundary was in the way on the right if (this.x + this.width > pict.getWidth()) this.x = pict.getWidth() - this.width; // If so, set right to right edge }
/** * Moves the paddle down by the movement offset field within the picture window's bounds avoiding * the given ball * * @param pict is the Picture object with the boundary to keep the paddle within * @param ball is a ball that causes the paddle to move back if it's in the way */ public void moveDown(JFrame pict, Ball ball) { this.y += this.offset; // Move y down by the offset // Test to see if the paddle moved into the ball if (ball.distance(this.x, this.y + this.height) < ball.getRadius() || ball.distance(this.x + this.width / 2, this.y + this.height) < ball.getRadius() || ball.distance(this.x + this.width, this.y + this.height) < ball.getRadius()) this.y -= this.offset; // If so, move it out of the ball // Test to see if the boundary was in the way below if (this.y + this.height > pict.getHeight()) this.y = pict.getHeight() - this.height; // If so, set bottom to picture bottom }
/** Internal routine for generating the List of particles on collision. */ public static ArrayList<Particle> generateParticles(Ball ball, Body body) { double centerX = ball.getCenter().x(); double centerY = ball.getCenter().y(); double speed = ball.getVelocity().magnitude() * ((body != null) ? (body.getRadius() / 100.0) : 1); if (speed < .50) speed = .50; if (speed > 2.50) speed = 2.50; if (body != null) { double max = Math.pow(body.getRadius() + ball.getRadius(), 2); while (body.getCenter().distanceSquared(new Point2d(centerX, centerY)) < max) { centerX -= ball.getVelocity().xComponent(); centerY -= ball.getVelocity().yComponent(); } } ArrayList<Particle> particles = new ArrayList<Particle>(); int num = (int) (300 * speed); if (num < 150) num = 150; else if (num > 400) num = 400; for (int i = 0; i < num; i++) { double angle = (Math.random() * 2 * Math.PI); double xSpeed = 0.75 * (Math.random() * speed * Math.cos(angle)); double ySpeed = 0.75 * (Math.random() * speed * Math.sin(angle)); Color c; double rand = Math.random(); if (body == null) c = CalcHelp.getShiftedColor(ball.getColor(), 100); else if (rand < 0.3) c = CalcHelp.getShiftedColor(body.getColor(), 100); else if (rand < 0.40) c = CalcHelp.getShiftedColor(new Color(230, 130, 70), 100); else c = CalcHelp.getShiftedColor(ball.getColor(), 100); Particle newParticle = new Particle(centerX, centerY, xSpeed, ySpeed, c); particles.add(newParticle); } return particles; }
/* * Zeichenmethode zum Zeichnen der Bälle, etc. */ @Override public void paint(Graphics g) { /* * FPS-Zäler (Ausgabe findet erst am Ende von <code>paint(Graphics g)</code>) */ if (frames == 1) { time = System.currentTimeMillis(); } if (System.currentTimeMillis() - time != 0) { fps = (int) ((1000 * frames) / ((System.currentTimeMillis() - time))); } if (frames > 1000) { frames = 0; } frames++; /* * Bild für Doublebuffering erstellen */ dbImage = createImage(phys.getSize().getX().intValue() + 2, phys.getSize().getY().intValue() + 2); dbGraphics = dbImage.getGraphics(); /* * <code>phys.tick()</code> gehört nicht in die <code>paint(Graphics g)</code>-Methode * in Draw-Panel, es ist jedoch nicht sehr sinvoll diesen Abschnitt auszulagern, * da man sonst die Synchronisation der Threads (diese werden von Swing (GUI-Bibliothek) * automatisch erstellt) selbst schreiben müsste. Dies geschieht durch den Aufruf in * <code>paint(Graphics g)</code> automatisch. */ if (this.isPaused() == false) { phys.tick(); } /* * Bälle zeichnen */ Stack<Ball> baelle = phys.getBaelle(); int anzBaelle = baelle.size(); for (int i = 0; i < anzBaelle; i++) { dbGraphics.setColor(baelle.elementAt(i).getColor()); int x = baelle.elementAt(i).getPosition().getX().intValue() - baelle.elementAt(i).getRadius().intValue(); int y = baelle.elementAt(i).getPosition().getY().intValue() - baelle.elementAt(i).getRadius().intValue(); int d = baelle.elementAt(i).getRadius().intValue() * 2; dbGraphics.drawOval(x, y, d, d); /* * Pfad des Balls zeichnen, falls aktiviert */ if (history == true) { Stack<Coordinate> hist = baelle.elementAt(i).getHistory(); int oldX = baelle.elementAt(i).getPosition().getX().intValue(); int oldY = baelle.elementAt(i).getPosition().getY().intValue(); for (int h = hist.size() - 1; h != 0; h--) { Color c = new Color( baelle.elementAt(i).getColor().getRed(), baelle.elementAt(i).getColor().getGreen(), baelle.elementAt(i).getColor().getBlue(), (255 * h / hist.size())); dbGraphics.setColor(c); dbGraphics.drawLine( oldX, oldY, hist.get(h).getX().intValue(), hist.get(h).getY().intValue()); oldX = hist.get(h).getX().intValue(); oldY = hist.get(h).getY().intValue(); } } /* * Richtungspfeil zeichnen, falls aktiviert */ if (directionArrow == true) { dbGraphics.setColor(baelle.elementAt(i).getColor()); drawArrow( (Graphics2D) dbGraphics, baelle.elementAt(i).getPosition().getX().intValue(), baelle.elementAt(i).getPosition().getY().intValue(), baelle.elementAt(i).getPosition().getX() + (baelle.elementAt(i).getSpeed().getX() * 50), baelle.elementAt(i).getPosition().getY() + (baelle.elementAt(i).getSpeed().getY() * 50)); } } /* * Erfassen der Mausposition und Zeichnen der Vorlage für den nächsten * zu erzeugenden Ball */ int x = newBall.getPosition().getX().intValue() - newBall.getRadius().intValue(); int y = newBall.getPosition().getY().intValue() - newBall.getRadius().intValue(); int d = newBall.getRadius().intValue() * 2; if (mousePressed == false) { dbGraphics.setColor(Color.red); } else { dbGraphics.setColor(Color.green); } dbGraphics.drawOval(x, y, d, d); if (mousePressed == true) { dbGraphics.drawLine( newBall.getPosition().getX().intValue(), newBall.getPosition().getY().intValue(), secondMouseCoordinate.getX().intValue(), secondMouseCoordinate.getY().intValue()); } dbGraphics.setColor(Color.black); dbGraphics.drawRect(0, 0, phys.getSize().getX().intValue(), phys.getSize().getY().intValue()); Point mousePos = getMousePosition(); if (mousePos != null && mousePressed == false) { newBall.setPosition(new Coordinate(new Double(mousePos.x), new Double(mousePos.y))); } if (mousePos != null && mousePressed == true) { secondMouseCoordinate = new Coordinate(new Double(mousePos.x), new Double(mousePos.y)); } /* * Ausgeben der FPS-Zahl */ dbGraphics.drawString("FPS: " + String.valueOf(fps), 10, 20); g.drawImage(dbImage, 0, 0, this); }
/** * Determines if the given ball has collided with the paddle and returns true if it has and false * if it has not. If the ball has collided with the paddle the balls movement vectors are modified * so the ball will bounce back at the proper angle. * * @param ball is the ball to examine to see if it has collided with the paddle * @return Returns true if ball collides with paddle and if so updates vectors */ public boolean collision(Ball ball) { // Temp variables for paddle corner coordinates; int pX1 = this.x; int pX2 = pX1 + this.width - 1; int pY1 = this.y; int pY2 = pY1 + this.height - 1; // Temp variables for ball coordinates, movement vectors, and radius int bX = ball.getX(); int bY = ball.getY(); int vX = ball.getXVector(); int vY = ball.getYVector(); int bRad = ball.getRadius(); // Testing for collisions with the paddle edges and the Ball if (bX < pX1 && bY >= pY1 && bY <= pY2 && vX > 0) // left edge { if (bX + bRad > pX1) // will collide with edge { ball.setX(pX1 - bRad); ball.setXVector(-Math.abs(vX)); // Change x direction return true; } } else if (bX > pX2 && bY >= pY1 && bY <= pY2 && vX < 0) // right edge { if (bX - bRad < pX2) // will collide with edge { ball.setX(pX2 + bRad); ball.setXVector(Math.abs(vX)); // Change x direction return true; } } else if (bY < pY1 && bX >= pX1 && bX <= pX2 && vY > 0) // top edge { if (bY + bRad > pY1) // will collide with edge { ball.setY(pY1 - bRad); ball.setYVector(-Math.abs(vY)); // Change y direction return true; } } else if (bY > pY2 && bX >= pX1 && bX <= pX2 && vY < 0) // bottom edge { if (bY - bRad < pY2) // will collide with edge { ball.setY(pY2 + bRad); ball.setYVector(Math.abs(vY)); // Change y direction return true; } } else // Otherwise test to see if the ball hits a corner of the paddle { if (ball.distance(pX1, pY1) <= bRad && ball.distance(pX1, pY1) <= ball.distance(pX2, pY1)) { // top-left corner collision if (Math.abs(pX1 - bX) >= Math.abs(pY1 - bY)) if (vX > 0) ball.setXVector(-vX); if (Math.abs(pX1 - bX) <= Math.abs(pY1 - bY)) if (vY > 0) ball.setYVector(-vY); return true; } else if (ball.distance(pX2, pY1) <= bRad) { // top-right corner collision if (Math.abs(pX2 - bX) >= Math.abs(pY1 - bY)) if (vX < 0) ball.setXVector(-vX); if (Math.abs(pX2 - bX) <= Math.abs(pY1 - bY)) if (vY > 0) ball.setYVector(-vY); return true; } else if (ball.distance(pX2, pY2) <= bRad && ball.distance(pX2, pY2) <= ball.distance(pX1, pY2)) { // bottom-right corner collision if (Math.abs(pX2 - bX) >= Math.abs(pY2 - bY)) if (vX < 0) ball.setXVector(-vX); if (Math.abs(pX2 - bX) <= Math.abs(pY2 - bY)) if (vY < 0) ball.setYVector(-vY); return true; } else if (ball.distance(pX1, pY2) <= bRad) { // bottom-left corner collision if (Math.abs(pX1 - bX) >= Math.abs(pY2 - bY)) if (vX > 0) ball.setXVector(-vX); if (Math.abs(pX1 - bX) <= Math.abs(pY2 - bY)) if (vY < 0) ball.setYVector(-vY); return true; } } return false; }