Java实现经典游戏打砖块游戏的示例代码

网友投稿 293 2022-08-26


Java实现经典游戏打砖块游戏的示例代码

目录前言主要设计功能截图代码实现游戏核心类小球类砖块类总结

前言

《java打砖块》游戏是自制的游戏。玩家操作一根萤幕上水平的“棒子”,让一颗不断弹来弹去的“球”在撞击作为过关目标消去的“砖块”的途中不会落到萤幕底下。

主要设计

设计游戏界面,用swing实现设计砖块,砖块类,设计小球,满屏乱跑的小球类,负责打碎砖块设计棒子,左右移动的木头板类球碰到砖块、棒子与底下以外的三边会反弹,落到底下会失去一颗球,把砖块全部消去就可以破关。小球碰到砖块的回调算法设计小球碰到棒子的回调算法设计设计碰撞特效,一个负责显示爆炸效果的类设计音效类,碰撞时发出音效。

功能截图

游戏开始:

碰撞效果:

代码实现

游戏核心类

public class BricksGame extends BaseGame {

private ArrayList 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.forpuobTPFmat("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;

puobTPF}

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打砖块游戏的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:1行Python代码,拿到周杰伦新歌的MP3文件,终于可以免费听周杰伦了
下一篇:python3异步编程的学习与实践(python异步编程实战)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~