JAVA综合实验:滑板反射小球游戏专业:电子科学与技术(微电子方向)学号:20132116姓名:李瑞婷2014-2015第二学期源代码:ball.javapackageorg.crazyit.ball;importjava.awt.Image;importjava.io.File;importjavax.imageio.ImageIO;importjava.io.IOException;public class Ball extends BallComponent { // 定义球的竖向速度privateintspeedY = 10;// 定义弹球的横向速度privateintspeedX = 8;// 定义是否在运动privateboolean started = false;// 定义是否结束运动privateboolean stop = false;/*** m 有参数构造器** @parampanelWidth* int 画板宽度* @parampanelHeight* int 画板高度* @param offset* int 位移* @param path* String 图片路径*/public Ball(intpanelWidth, intpanelHeight, int offset, String path)throwsIOException {// 调用父构造器super(panelWidth, panelHeight, path);// 设置y坐标this.setY(panelHeight - super.getImage().getHeight(null) - offset);}/*** 设置横向速度** @param speed* int 速度* @return void*/public void setSpeedX(int speed) {this.speedX = speed;}/*** 设置竖向速度** @param speed* int 速度* @return void*/public void setSpeedY(int speed) { this.speedY = speed;}/*** 设置是否在运动** @param b* boolean* @return void*/public void setStarted(boolean b) { this.started = b;}/*** 设置是否结束运动** @param b* boolean* @return void*/public void setStop(boolean b) { this.stop = b;}/*** 返回横向速度** @return int 速度*/publicintgetSpeedX() {returnthis.speedX;}/*** 返回竖向速度** @return int 速度*/publicintgetSpeedY() {returnthis.speedY;}/*** 是否在运动** @return boolean 是否在运动*/publicbooleanisStarted() {returnthis.started;}/*** 是否已经结束运动** @return boolean 是否已经结束运动*/publicbooleanisStop() {returnthis.stop;}}BallComponentpackage org.crazyit.ball;import java.awt.Image;import java.io.File;import javax.imageio.ImageIO;import java.io.IOException;publicclass BallComponent {// 设置x坐标privateint x = -1;// 设置y坐标privateint y = -1;// 设置图片private Image image = null;// 设置图片速度privateint speed = 5;public BallComponent(String path) throws IOException {super();this.image = ImageIO.read(new File(path));}/*** 构造器** @param panelWidth* int画板宽度* @param panelHeight* int画板高度* @param path* String 图片路径*/public BallComponent(int panelWidth, int panelHeight, String path) throws IOException {super();// 读取图片this.image = ImageIO.read(new File(path));// 设置x坐标this.x = (int) ((panelWidth - image.getWidth(null)) / 2);}/*** 构造器** @param x* int图像的x坐标* @param y* int图像的y坐标* @param path* String 图片路径*/public BallComponent(String path, int x, int y) throws IOException { super();// 读取图片this.image = ImageIO.read(new File(path));this.x = x;this.y = y;}/*** 获取x坐标** @return int x坐标*/publicint getX() {returnthis.x;}/*** 获取y坐标** @return int y坐标*/publicint getY() {returnthis.y;}/*** 获取图片速度** @return int图片速度*/publicint getSpeed() {returnthis.speed;}/*** 设置x坐标** @param x* int x坐标* @return void*/publicvoid setX(int x) {this.x = x;}/*** 设置y坐标** @param y* int y坐标* @return void*/publicvoid setY(int y) {this.y = y;}/*** 返回图片** @return Image 图片*/public Image getImage() {returnthis.image;}}package org.crazyit.ball;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.Timer;import java.awt.Dimension;import java.awt.Image;import java.awt.Graphics;import java.awt.Color;import java.awt.event.KeyAdapter; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.io.IOException;publicclass BallFrame extends JFrame { // 定义JPanel的宽度privatefinalint BALLPANEL_WIDTH = 307;// 定义JPanel的高度privatefinalint BALLPANEL_HEIGHT = 400;// 定义画板private BallPanel ballPanel = null;// 定义档板// private Image stick = null;// 设置档板x坐标privateint stickX = -1;// 创建一个BallService实例private BallService service = null;// 定义一个timerTimer timer = null;/*** 默认构造器*/public BallFrame() throws IOException {super();// 初始化initialize();}/*** 初始化界面** @return void*/publicvoid initialize() throws IOException {// 设置窗口的标题this.setTitle("弹球");// 设置为不可改变大小this.setResizable(false);// 设置背景为黑色this.setBackground(Color.BLACK);// 获取画板ballPanel = getBallPanel();// 创建BallService实例service = new BallService(this, BALLPANEL_WIDTH, BALLPANEL_HEIGHT);// 定义每0.1秒执行一次监听器ActionListener task = new ActionListener() {publicvoid actionPerformed(ActionEvent e) {// 开始改变位置service.run();// 刷新画板ballPanel.repaint();}};// 如果timer不为空if (timer != null) {// 重新开始timertimer.restart();} else {// 新建一个timertimer = new Timer(100, task);// 开始timertimer.start();}this.add(ballPanel);// 增加事件监听器KeyListener[] klarr = this.getKeyListeners();if (klarr.length == 0) {// 定义键盘监听适配器KeyListenerkeyAdapter = new KeyAdapter() {publicvoid keyPressed(KeyEventke) {// 改变档板的坐标service.setStickPos(ke);}};this.addKeyListener(keyAdapter);}}/*** 获取画板** @return BallPanel返回BallPanle*/public BallPanelgetBallPanel() {if (ballPanel == null) {// 新建一个画板ballPanel = new BallPanel();// 设置画板的大小ballPanel.setPreferredSize(new Dimension(BALLPANEL_WIDTH,BALLPANEL_HEIGHT));}return ballPanel;}// 定义一个JPanel内部类来完成画图功能publicclass BallPanel extends JPanel {/*** 重写void paint( Graphics g )方法** @param g* Graphics* @return void*/publicvoid paint(Graphics g) {// 画图service.draw(g);}}BallGamepackage org.crazyit.ball;import java.io.IOException;import javax.swing.JFrame;publicclass BallGame {/*** 开始游戏** @return void*/publicstaticvoid main(String[] args) throws IOException { BallFrameballFrame = new BallFrame();ballFrame.pack();ballFrame.setVisible(true);ballFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}BallServicepackage org.crazyit.ball;import java.awt.event.KeyEvent;import java.awt.Image;import java.awt.Graphics;import java.io.IOException;publicclass BallService {// 定义一个Stick(档板)private Stick stick = null;// 定义一个弹球private Ball ball = null;// 定义一个游戏结束图片private BallComponent gameOver = null;// 定义一个赢了游戏的图片private BallComponent won = null;// 定义一个砖块图片数组private Brick[][] bricks = null;privateint width;privateint height;BallFrame ballFrame = null;/*** 私有空构造器*/private BallService() {super();}/**** @param frame* JFrameJFrame实例* @param width* int宽* @param height* int高* @return BallService*/public BallService(BallFrame frame, int width, int height) throws IOException {// 初始化变量this.width = width;this.height = height;this.ballFrame = frame;// 创建一个Stick(档板)实例stick = new Stick(width, height, "img/stick.jpg");// 创建一个弹球的实例ball= new Ball(width, height, stick.getImage().getHeight(null), "img/ball.gif");// 游戏结束图片gameOver = new BallComponent("img/over.gif");// 赢图片won = new BallComponent("img/win.gif");// 砖块图片数组bricks = createBrickArr("img/brick.gif", 11, 6);}/*** run** @return void*/publicvoid run() {// 弹球坐标改变setBallPos();// 道具坐标改改变setMagicPos();}/*** 设置档板图片的位置** @param ke* KeyEvent键盘事件* @return void*/publicvoid setStickPos(KeyEventke) {// 把弹球的运动状态设为trueball.setStarted(true);// 如果是左方向键if (ke.getKeyCode() == KeyEvent.VK_LEFT) {if (stick.getX() - stick.SPEED> 0) {// x坐标向左移动stick.setX(stick.getX() - stick.SPEED);}}// 如果是右方向键if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {if (stick.getX() + stick.SPEED<width - stick.getPreWidth()) {// x坐标向右移动stick.setX(stick.getX() + stick.SPEED);// ballFrame.getBallGame().reStart( ballFrame );}}// 如果是F2键if (ke.getKeyCode() == KeyEvent.VK_F2) {// 初始化ballFrametry {ballFrame.initialize();} catch (IOException e) {System.out.println(e.getMessage());}}}/*** 设置小球图片的位置** @return void*/publicvoid setBallPos() {// 正数的数度int absSpeedX = Math.abs(ball.getSpeedX());int absSpeedY = Math.abs(ball.getSpeedY());// 如果游戏已经开始而且没有结束if (ball.isStarted()) {// 如果小球碰到左边界if (ball.getX() - absSpeedX< 0) {// 重新设置x坐标ball.setX(ball.getImage().getWidth(null));// 把x方向的速度设为反方向ball.setSpeedX(-ball.getSpeedX());}// 如果小球碰到右边界if (ball.getX() + absSpeedX>width- ball.getImage().getWidth(null)) {// 重新设置x坐标ball.setX(width - ball.getImage().getWidth(null) * 2);// 把x方向的速度设为反方向ball.setSpeedX(-ball.getSpeedX());}// 如果小球碰到上边界if (ball.getY() - absSpeedY< 0) {// 重新设置y坐标ball.setY(ball.getImage().getWidth(null));// 把y方向的速度设为反方向ball.setSpeedY(-ball.getSpeedY());}// 如果小球碰到下边界if (ball.getY() + absSpeedY>height- stick.getImage().getHeight(null)) {// 如果小球与档板有碰撞if (isHitStick(ball)) {// 重新设置y坐标ball.setY(height- ball.getImage().getHeight(null) * 2);// 把y方向的速度设为反方向ball.setSpeedY(-ball.getSpeedY());}}// 与砖块碰撞后的运动for (int i = bricks.length - 1; i> -1; i--) {for (int j = bricks[i].length - 1; j > -1; j--) {// 如果小球与砖块有碰撞if (isHitBrick(bricks[i][j])) {if (ball.getSpeedY() > 0) {ball.setSpeedY(-ball.getSpeedY());}}}}// 结束游戏if (ball.getY() >height) {ball.setStop(true);}// 设置x坐标ball.setX(ball.getX() - (int) (Math.random() * 2)- ball.getSpeedX());// 设置y坐标ball.setY(ball.getY() - (int) (Math.random() * 2)- ball.getSpeedY());}}/*** 小球与砖块是否有碰撞** @return boolean*/publicboolean isHitBrick(Brick brick) {if (brick.isDisable()) {returnfalse;}// ball的圆心x坐标double ballX = ball.getX() + ball.getImage().getWidth(null) / 2;// ball的圆心y坐标double ballY = ball.getY() + ball.getImage().getHeight(null) / 2;// brick的中心x坐标double brickX = brick.getX() + brick.getImage().getWidth(null) / 2;// brick的中心y坐标double brickY = brick.getY() + brick.getImage().getHeight(null) / 2;// 两个坐标点的距离double distance = Math.sqrt(Math.pow(ballX - brickX, 2)+ Math.pow(ballY - brickY, 2));// 如果两个图形重叠,返回true;if (distance < (ball.getImage().getWidth(null) +brick.getImage().getWidth(null)) / 2) {// 使brick无效brick.setDisable(true);returntrue;}returnfalse;}/*** BallComponent是否与档板有碰撞** @param image* BallComponent图像* @return boolean*/publicboolean isHitStick(BallComponentbc) {// 获取图片对象Image tempImage = bc.getImage();// 如果与档板有碰撞if (bc.getX() + tempImage.getWidth(null) >stick.getX()&&bc.getX() <stick.getX() + stick.getPreWidth()&&bc.getY() + tempImage.getHeight(null) >stick.getY()) { returntrue;}returnfalse;}/*** 设置道具的位置** @return void*/publicvoid setMagicPos() {for (int i = 0; i<bricks.length; i++) {for (int j = 0; j <bricks[i].length; j++) {// 获取magicMagic magic = bricks[i][j].getMagic();if (magic != null) {// 如果这个brick的状态是无效的if(bricks[i][j].isDisable() &&magic.getY() <height) {// 设置magic的y坐标向下增加magic.setY(magic.getY() + magic.getSpeed());// 设置档板的宽度setStickWidth(magic);}}}}}/*** 设置档板的长度** @param magic* Magic 道具* @return void*/publicvoid setStickWidth(Magic magic) {if (isHitStick(magic)) {// 道具的作用magic.magicDo(stick);}}/*** 判断是否赢了** @return boolean*/publicboolean isWon() {// 如果消了全部砖块,则为赢for (int i = 0; i<bricks.length; i++) {for (int j = 0; j <bricks[i].length; j++) {if (!bricks[i][j].isDisable()) {returnfalse;}}}returntrue;}/*** 创建一个类型为Brick的数组** @param path* String 图像路径* @param xSize* int* @param ySize* int* @return Brick[][]*/public Brick[][] createBrickArr(String path, int xSize, int ySize) throws IOException {// 创建一个Brick[][]Brick[][] bricks = new Brick[xSize][ySize];int x = 0;int y = 0;int random = 0;int imageSize = 28;boolean isDisable = false;// 迭代初始化数组for (int i = 0; i<xSize; i++) {for (int j = 0; j <ySize; j++) {// 创建一个新的砖块random = (int) (Math.random() * 3);x = i * imageSize;y = j * imageSize;// 一定机率没有砖块isDisable = Math.random() > 0.8 ? true :false;if (isDisable) {random = 0;}Brick brick = new Brick(path, random, x, y);brick.setDisable(isDisable);// 设置x坐标brick.setX(x);// 设置y坐标brick.setY(y);bricks[i][j] = brick;}}return bricks;}/*** 画图** @param g* Graphics 用来画图的对象* @return void*/publicvoid draw(Graphics g) {// 如果赢了if (isWon()) {// 绘制赢的图片g.drawImage(won.getImage(), won.getX(), won.getY(), width,height - 10, null);} elseif (ball.isStop()) {// 绘制游戏结束图像g.drawImage(gameOver.getImage(), gameOver.getX(), gameOver.getY(),width, height - 10, null);} else {// 清除原来的图像g.clearRect(0, 0, width, height);// 绘制档板图像g.drawImage(stick.getImage(), stick.getX(), stick.getY(), stick.getPreWidth(), stick.getImage().getHeight(null), null);// 绘制弹球图像g.drawImage(ball.getImage(), ball.getX(), ball.getY(), null);// 迭代绘制砖块图像for (int i = 0; i<bricks.length; i++) {for (int j = 0; j <bricks[i].length; j++) {BallComponent magic = bricks[i][j].getMagic();// 如果这个砖块图像对像是有效的if (!bricks[i][j].isDisable()) {// 里面的数字1为砖块图像间的间隙g.drawImage(bricks[i][j].getImage(),bricks[i][j].getX(), bricks[i][j].getY(),bricks[i][j].getImage().getWidth(null) - 1,bricks[i][j].getImage().getHeight(null) - 1, null);} elseif (magic != null&&magic.getY() <height) {g.drawImage(magic.getImage(), magic.getX(), magic.getY(), null);}}}}}Magicpackage org.crazyit.ball;import java.io.IOException;publicabstractclass Magic extends BallComponent {/*** 提供给子类调用的构造器** @param path* String 文件路径* @param x* int x坐标* @param y* int y坐标*/public Magic(String path, int x, int y) throws IOException { super(path, x, y);}/*** 道具的功能** @param stitck* Stick* @return void*/publicabstractvoid magicDo(Stick stick);}Stickpackage org.crazyit.ball;import java.io.IOException;publicclass Stick extends BallComponent {// 定义档板移动的速度publicstaticfinalint SPEED = 20;// 定义档板初始的长度privateint preWidth = 0;/*** 有参数构造器** @param panelWidth* int画板宽度* @param panelHeight* int画板高度* @param path* String 图片路径*/public Stick(int panelWidth, int panelHeight, String path) throws IOException {// 调用父构造器super(panelWidth, panelHeight, path);// 设置y坐标this.setY(panelHeight - super.getImage().getHeight(null));// 设置原本的长度this.preWidth = super.getImage().getWidth(null);}/*** 获取初始长度** @return int初始长度*/publicint getPreWidth() {returnthis.preWidth;}/*** 设置初始长度** @return void*/publicvoid setPreWidth(int preWidth) {this.preWidth = preWidth;}}运行结果。