Java Pong游戏球与Paddle/墙体多次碰撞滑行问题排查与解决
Pong游戏碰撞滑行问题的解决方法
我和同学开发Pong游戏时遇到一个问题:当球与墙体或玩家Paddle发生碰撞时,有时会出现多次碰撞的情况,导致球看起来像是在Paddle上滑行。我们最终通过在球碰撞物体(墙体或Paddle)后添加冷却机制解决了该异常滑行问题。
import greenfoot.*; import java.awt.*; /** * A Ball is a thing that bounces of walls and paddles (or at least i should). * * @author The teachers * @version 1 */ public class Ball extends Actor { private static final int BALL_SIZE = 50; private static final int BOUNCE_DEVIANCE_MAX = 5; private static final int STARTING_ANGLE_WIDTH = 90; private static final int DELAY_TIME = 200; private int speed; private boolean hasBouncedHorizontally; private boolean hasBouncedVertically; private int delay; private int touchCounter; /** * Contructs the ball and sets it in motion! */ public Ball() { // createImage(); init(); } /** * Creates and sets an image of a black ball to this actor. */ /* private void createImage() { GreenfootImage ballImage = new GreenfootImage(BALL_SIZE,BALL_SIZE); ballImage.setColor(Color.RED); ballImage.fillOval(0, 0, BALL_SIZE, BALL_SIZE); setImage(ballImage); } */ /** * 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() { if (delay > 0) { delay--; } else { move(speed); checkBounceOffWalls(); checkBounceOffCeiling(); checkRestart(); bounceOffPaddles(); } } /** * Returns true if the ball is touching one of the side walls. */ private boolean isTouchingSides() { return getX() <= BALL_SIZE/2 || getX() >= getWorld().getWidth() - BALL_SIZE/2; } /** * Returns true if the ball is touching the ceiling. */ private boolean isTouchingCeiling() { return (getY() <= BALL_SIZE/2); } /** * Returns true if the ball is touching the floor. */ private boolean isTouchingFloor() { return (getY() >= getWorld().getHeight() - BALL_SIZE/2); } /** * Check to see if the ball should bounce off one of the walls. * If touching one of the walls, the ball is bouncing off. */ private void checkBounceOffWalls() { if (isTouchingSides()) { if (! hasBouncedHorizontally) { revertHorizontally(); } } else { hasBouncedHorizontally = false; } } /** * Check to see if the ball should bounce off the ceiling. * If touching the ceiling the ball is bouncing off. */ private void checkBounceOffCeiling() { if (isTouchingCeiling()) { if (! hasBouncedVertically) { revertVertically(); } } // Removed for purpose of solving Task 3 /* else { hasBouncedVertically = false; } */ } /** * Check to see if the ball should be restarted. * If touching the floor the ball is restarted in initial position and speed. */ private void checkRestart() { if (isTouchingFloor()) { PingWorld theWorld = (PingWorld) getWorld(); theWorld.resetGameLevel(); init(); setLocation(getWorld().getWidth() / 2, getWorld().getHeight() / 2); } } /** * Bounces the ball back from a vertical surface. */ private void revertHorizontally() { int randomness = Greenfoot.getRandomNumber(BOUNCE_DEVIANCE_MAX)- BOUNCE_DEVIANCE_MAX / 2; setRotation((180 - getRotation()+ randomness + 360) % 360); Greenfoot.playSound("pewsoundeffect.mp3"); hasBouncedHorizontally = true; } /** * Bounces the bal back from a horizontal surface. */ private void revertVertically() { int randomness = Greenfoot.getRandomNumber(BOUNCE_DEVIANCE_MAX)- BOUNCE_DEVIANCE_MAX / 2; setRotation((360 - getRotation()+ randomness + 360) % 360); Greenfoot.playSound("pewsoundeffect.mp3"); hasBouncedVertically = true; } // Checking for the paddles if they intersect with the ball, if touching, revert vertically. public void bounceOffPaddles() { Actor paddle = getOneIntersectingObject(Paddle.class); Actor enemyPaddle = getOneIntersectingObject(EnemyPaddle.class); if (paddle != null) { revertVertically(); hasBouncedVertically = false; speedIncreaser(); } if (hasBouncedVertically == false && enemyPaddle != null) { revertVertically(); } } // Increases speed public void speedIncreaser() { touchCounter++; if (touchCounter == 10) { speed++; PingWorld theWorld = (PingWorld) getWorld(); theWorld.increaseGameLevel(); touchCounter = 0; } } /** * Initialize the ball settings. */ private void init() { speed = 2; delay = DELAY_TIME; hasBouncedHorizontally = false; hasBouncedVertically = false; setRotation(Greenfoot.getRandomNumber(STARTING_ANGLE_WIDTH)+STARTING_ANGLE_WIDTH/2); } }
内容的提问来源于stack exchange,提问作者D R O P
相关产品推荐
相关产品推荐

