<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
《JAVA打磚塊》遊戲是自制的遊戲。玩家操作一根螢幕上水平的“棒子”,讓一顆不斷彈來彈去的“球”在撞擊作為過關目標消去的“磚塊”的途中不會落到螢幕底下。
遊戲開始:
碰撞效果:
public class BricksGame extends BaseGame { private ArrayList<GameObject> list = new ArrayList<>(); private RenderTask render; private Random random = new Random(); private boolean over; private Image memImage; private Graphics memG;// 雙緩衝的畫布 public BricksGame(int width, int height, String title) throws HeadlessException { super(width, height, title); super.setBgColor(new Color(0x23,0x30,0x41)); initGame(width, height); } private void initGame(int width, int height) { setFps(60); over=false; // 獲取視窗的內外大小 Container contentPane = this.getContentPane(); Dimension size = contentPane.getSize(); int contentWidth = size.width; int contentHeight = size.height; this.setContentWidth(contentWidth); this.setContentHeight(contentHeight); //System.out.println(contentPane instanceof JPanel);// true //System.out.println(size.width);//582 //System.out.println(size.height);//403 // 視窗四個方向的邊界值 Insets insets = getInsets(); //System.out.println(insets.top); //System.out.println(insets.bottom); //System.out.println(insets.left); //System.out.println(insets.right); Scene env = new Scene(width, height, new Margin(insets.left, insets.right, insets.top, insets.bottom)); ImageIcon woodIcon = new ImageIcon("image/wood.png"); int w = woodIcon.getIconWidth(); int h = woodIcon.getIconHeight(); Wood wood = new Wood(w, h, new Color(0x97, 0x5B, 0x12)); wood.setScene(env); wood.setX(getWidth()/2 - w/2); wood.setY(getHeight()-50); wood.setImage(woodIcon.getImage()); list.add(wood); Ball ball = new Ball(10, Color.WHITE); ImageIcon iconBall = new ImageIcon("image/ball2.png"); ball.setImage(iconBall.getImage()); ball.setScene(env); ball.setCoordinator(width / 2 - ball.getRadius(), wood.getY()-ball.getRadius()*2); ball.setWoodBar(wood); list.add(ball); Color[] colors = new Color[]{ new Color(0xAA, 0xCF, 0x51), new Color(0xFC, 0xA9, 0x4B), new Color(0x73, 0xC7, 0xFF), Color.PINK, Color.GRAY }; //ImageIcon brickIcon = new ImageIcon("image/brick_1.png"); int brW = 60; int brH = 30; int start = 25; int brickX = start; int brickY = 100; int brickAreaWidth = getWidth() - start *2; int count = brickAreaWidth / brW - 1; int remainWidth = brickAreaWidth - count * brW; int intervalHort = brW + 3; start = brickX = (getWidth() - intervalHort * (count)) / 2; int intervalVert = brH + 3; HitBrick hitBrick = new HitBrick(); for (int j = 0; j < 3; j++) {// brick line for(int i = 0; i< count; i++){// brick columns Brick brick = new Brick(); brick.setColor(colors[i % colors.length]); //brick.setImage(brickIcon.getImage()); brick.setWidth(brW); brick.setHeight(brH); brick.setX(brickX); brick.setY(brickY); brick.setBall(ball); brick.setHitListener(hitBrick); brickX += intervalHort; list.add(brick); } brickX = start; brickY += intervalVert; } // 雙緩衝,在記憶體裡面建立一個和視窗JFrame一樣大小的Image memImage = createImage(getWidth(), getHeight()); memG = memImage.getGraphics(); GameOver gameOver = new GameOver(memG); ball.setGameOverListener(gameOver); // 鍵盤事件的監聽 Input input = new Input(); input.init(); addKeyListener(input); // 重新渲染畫面任務 render = new RenderTask(this); render.start(); addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { //super.mousePressed(e); System.out.println(String.format("x:%d, y:%d", e.getX(), e.getY())); //x:218,y:305,w:164,h:45 if ((e.getX() >= 218 && e.getX() <=(218+164)) && (e.getY() >= 305 && e.getY() <= (305+45)) ){ render.setExitd(true); render = null; memImage = null; memG = null; removeKeyListener(input); removeMouseListener(this); list.clear(); initGame(width, height); } } }); } @Override public void paint(Graphics g) { clear(memG);// 將畫布清空為背景色 for (int i = 0; i < list.size(); i++) { list.get(i).onTick(); list.get(i).draw(memG); } if (list.size() == 2){// 只剩下小球和擋板,則通關成功! Wood wood = (Wood) list.get(0); wood.setX(getWidth()/2 - wood.getWidth()/2); wood.setY(getHeight()-50); Ball ball = (Ball) list.get(1); ball.setCoordinator(getWidth() / 2 - ball.getRadius(), /*bottom*/wood.getY()-ball.getRadius()*2); ball.setMoving(false); String gameOver = "恭喜通關!"; memG.setFont(new Font("Serif", Font.BOLD, 35)); int stringWidth = memG.getFontMetrics().stringWidth(gameOver); memG.setColor(Color.RED); memG.drawString(gameOver, getWidth()/2 - stringWidth/2, getHeight()/2); stopRenderTask(); } if (over) { String gameOver = "Game Over"; memG.setFont(new Font("Serif", Font.BOLD, 35)); int stringWidth = memG.getFontMetrics().stringWidth(gameOver); memG.setColor(Color.WHITE); memG.drawString(gameOver, getWidth()/2 - stringWidth/2, getHeight()/2); String playAgain = "重新開始"; stringWidth = memG.getFontMetrics().stringWidth(playAgain); int increase = 16; int fontSize = memG.getFont().getSize(); int rectH = (int) (fontSize * 1.3); int rx=getWidth()/2 - stringWidth/2 - increase /2; int ry=getHeight() - fontSize * 4-(rectH-fontSize)/2; int rw = stringWidth + increase; int rh = rectH; //System.out.println(String.format("x:%d,y:%d,w:%d,h:%d", rx, ry, rw, rh)); memG.drawRect(rx, ry, rw, rh); memG.setColor(new Color(33, 165, 230)); memG.drawString(playAgain, getWidth()/2 - stringWidth/2, getHeight() - fontSize * 3 - 5); } // 將記憶體Image的內容複製到視窗上 g.drawImage(memImage, 0, 0, null); // 耗效能的輪詢判斷,一個物件是否要消失 for (int i = 2; i < list.size(); i++) {// 0,1位置是擋板和小球,不能消失 GameObject gameObject = list.get(i); if (gameObject.isGone()) { list.remove(i); --i; } } } private void stopRenderTask() { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } render.setExitd(true); } }).start(); } public void exit(){ //System.exit(1); } public void clear(Graphics g){ if (g!=null) { g.setColor(getBgColor()); g.fillRect(0, 0, getWidth(), getHeight()); } } // 小球碰到磚塊的回撥 class HitBrick implements Brick.HitListener{ private ExecutorService executorService = Executors.newFixedThreadPool(3); private File file = new File("audio/brick2.wav"); private AudioClip audio; public HitBrick() { try { audio = Applet.newAudioClip(file.toURI().toURL()); } catch (MalformedURLException e) { e.printStackTrace(); } } @Override public void hit(Brick brick) { executorService.execute(new PlayHitAudioTask(audio)); ExplodeObject eo = new ExplodeObject(); eo.x = brick.x; eo.y = brick.y; eo.width = brick.width; eo.height = brick.height; eo.color = brick.color; list.add(eo); } } // 遊戲結束內容的繪製 class GameOver implements Ball.GameOverListener{ private Graphics memG; public GameOver(Graphics g) { this.memG = g; } @Override public void over() { over = true; } } }
public class Ball extends RectGameObject{ private int radius; private int speed = 4;// 小球移動速度 private boolean moving;// 是否在移動 private boolean gameOver;// 是否over private boolean postv;// 初始水平方向的移動左右方向 private int horiMove;// 水平移動距離(正負號代表移動方向) private int vertMove;// 垂直移動距離(正負號代表移動方向) private Wood woodBar;//木頭板 private Image image; private Point center = new Point(); private GameOverListener l; public Ball(int radius, Color color){ this.radius = radius; this.color = color; } @Override public void draw(Graphics g) { g.setColor(color); //g.drawImage(image, x, y, null); g.fillOval(x, y, radius * 2, radius * 2); } @Override public void onTick() { if (!moving){ if(Input.getKeyDown(KeyEvent.VK_UP)){ postv = (Math.random() * 10) <= 4 ? true : false; moving = true; gameOver = false; horiMove = postv ? speed : -speed; vertMove = -speed; } /*else if(Input.getKeyDown(KeyEvent.VK_LEFT)){ Wood wb = woodBar; if (!wb.isReachEdge()) { transferBy(-wb.getSpeed(), 0); } } else if(Input.getKeyDown(KeyEvent.VK_RIGHT)){ Wood wb = woodBar; if (!wb.isReachEdge()) { transferBy(wb.getSpeed(), 0); } }*/ } if (moving){ // arrive at left and right edge Scene scene = getScene(); Margin margin = scene.in; if (x <= margin.left || x >= scene.width - margin.right - radius * 2){ horiMove = -horiMove; } // arrive at top edge if (y <= margin.top && vertMove < 0){ vertMove = -vertMove; } // 小球落在了擋板上 if(getCenter().x >= woodBar.getX() && getCenter().x <= woodBar.getX() + woodBar.getWidth() && Math.abs(getCenter().y - woodBar.y) <= radius && vertMove > 0 ){ vertMove = -vertMove; } // arrive at bottom edge // 小球落在了視窗的底部,停住小球 GAME OVER if (y >= scene.height - margin.bottom - radius * 2){ moving = false; gameOver = true; if (l != null) l.over(); return; } this.transferBy(horiMove, vertMove); } } public int getRadius() { return radius; } public void setRadius(int radius) { this.radius = radius; } public Wood getWoodBar() { return woodBar; } public void setWoodBar(Wood woodBar) { this.woodBar = woodBar; } public Image getImage() { return image; } public void setImage(Image image) { this.image = image; } public boolean isMoving() { return moving; } public void setMoving(boolean moving) { this.moving = moving; } public int getHoriMove() { return horiMove; } public void setHoriMove(int horiMove) { this.horiMove = horiMove; } public int getVertMove() { return vertMove; } public void setVertMove(int vertMove) { this.vertMove = vertMove; } @Override public int getWidth() { return 2 * radius; } @Override public int getHeight() { return getWidth(); } public Point getCenter(){ center.x = x + radius; center.y = y + radius; return center; } public boolean isGameOver() { return gameOver; } public void setGameOver(boolean gameOver) { this.gameOver = gameOver; } public GameOverListener getGameOverListener() { return l; } public void setGameOverListener(GameOverListener l) { this.l = l; } public interface GameOverListener{ void over(); } }
package game; import java.awt.*; public class Brick extends RectGameObject { private Ball ball; private Point leftTop = new Point(); private Point leftBottom = new Point(); private Point rightTop = new Point(); private Point rightBottom = new Point(); public Brick(){} @Override public void draw(Graphics g) { g.setColor(getColor()); g.fillRect(x, y, getWidth(), getHeight()); } @Override public void onTick() { if (ball.isMoving()) { //start 碰撞檢測///////////////////////////////////////////// boolean is = isSameQuadrant(ball.getCenter(), getLeftTop(), getRightBottom()); if (is) { int r = ball.getRadius(); Point lt = getLeftTop(); Point lb = getLeftBottom(); Point rt = getRightTop(); Point rb = getRightBottom(); Point c = ball.getCenter(); int dx1 = Math.abs(c.x - lt.x), dy1 = Math.abs(c.y - lt.y); int dx2 = Math.abs(c.x - lb.x), dy2 = Math.abs(c.y - lb.y); int dx3 = Math.abs(c.x - rt.x), dy3 = Math.abs(c.y - rt.y); int dx4 = Math.abs(c.x - rb.x), dy4 = Math.abs(c.y - rb.y); if(((dx1*dx1) + (dy1*dy1) <= r*r) ||((dx2*dx2) + (dy2*dy2) <= r*r) ||((dx3*dx3) + (dy3*dy3) <= r*r) ||((dx4*dx4) + (dy4*dy4) <= r*r)){ System.out.println("發生了碰撞"); if (hitListener != null) { hitListener.hit(this); } setGone(true); } } else { Point c = ball.getCenter(); int squareW = ball.getRadius() * 2; int squareH = squareW; int brcx = x + getWidth() / 2; int brcy = y + getHeight() / 2; if((Math.abs(c.x - brcx) <= (squareW + getWidth())*0.5) &&(Math.abs(c.y - brcy) <= (squareH + getHeight())*0.5) ){ System.out.println("......發生碰撞"); if (hitListener != null) { hitListener.hit(this); } setGone(true); /* 擊中磚塊,改變小球的方向 */ // 判斷小球首先撞擊的是磚塊的左右還是上下側,非常重要,否則出現不合理的移動方向。 double horizontal = (squareW + getWidth())*0.5 - Math.abs(c.x - brcx); double vertical = (squareH + getHeight())*0.5 - Math.abs(c.y - brcy); if (horizontal < vertical) ball.setHoriMove(-ball.getHoriMove()); else ball.setVertMove(-ball.getVertMove()); } } //end碰撞檢測////////////////////////////////////////////// } } public Ball getBall() { return ball; } public void setBall(Ball ball) { this.ball = ball; } public Point getLeftTop(){ leftTop.x = x; leftTop.y = y; return leftTop; } public Point getRightTop(){ rightTop.x = x+getWidth(); rightTop.y = y; return rightTop; } public Point getLeftBottom(){ leftBottom.x = x; leftBottom.y = y + getHeight(); return leftBottom; } public Point getRightBottom(){ rightBottom.x = x + getWidth(); rightBottom.y = y + getHeight(); return rightBottom; } private HitListener hitListener; public void setHitListener(HitListener hitListener){ this.hitListener = hitListener; } public interface HitListener { void hit(Brick brick); } }
通過此次的《JAVA打磚塊》實現,讓我對JAVA的相關知識有了進一步的瞭解,對java這門語言也有了比以前更深刻的認識。
java的一些基本語法,比如資料型別、運運算元、程式流程控制和陣列等,理解更加透徹。java最核心的核心就是物件導向思想,對於這一個概念,終於悟到了一些。
以上就是Java實現經典遊戲打磚塊遊戲的範例程式碼的詳細內容,更多關於Java打磚塊遊戲的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45