Java编程经典小游戏设计-打砖块小游戏源码

时间:2022-04-03 10:05:30

[程序中使用的数据结构和符号说明]

HitBrick类

GreenBallThread控制小球路线

xUp,yUp,bouncing定义变量存储16位数值形式

x,y小球坐标

xDx,yDy坐标增量

MAX_X,MAX_Y坐标最大值

renew初始化

label标签

Rx,Ry横板坐标

Brick[]砖块

ball小球

HitBrick()定义小球横板及砖块位置坐标

keyPressd(keyEent)定义小球启动键(按空格键启动)

keyReleased(keyEvent)接收键盘事件侦听器接口)

keyTyped(keyEvent)键入空格键时调用keyEvent

paint(Graphics)对砖块填充颜色

move定义小球的运动轨迹和砖块的消失

main主函数

BallThread类

通过继承Thread类使Ball类线程化,并把小球的弹跳动作放进Run()中执行

Brick类

定义砖块坐标位置和砖块按钮

Ball类

定义小球坐标位置

[程序设计流程]

程序中使用的部分方法解释

开始命令:空格键

privateJLabellabel;定义一个标签,label=newJLabel("按空格键开始");内容为空格键开始,addKeyListener(this);定义一个键盘监听器,

?
1
2
3
4
5
6
7
8
9
if (e.getKeyCode() ==e.VK_SPACE) {
   if(renew){
    greenBallThread=new BallThread(this);
    bouncing = true;
    greenBallThread.start();
    label.setVisible(false);
   }
   renew=false;
  }

重置并开始游戏

移动命令:方向键左键和右键

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if(e.getKeyCode()==e.VK_LEFT){
   Rx=Rx-20;
   if(bouncing){
    if(Rx<0){
     Rx=0;
    }
   }
   else{
    if(Rx<0){
     Rx=0;
    }
    else{
     x=x-20;
     ball.ball_x=x;
    }
   }
   repaint();
  }

同开始命令原理,如果键入左键,横版向左移动20个单位(Rx为横板坐标),如果小球还在运动,当横板移到最左侧(Rx=0),不能再向左移动,则横板靠在最左侧(Rx=0),

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if(e.getKeyCode()==e.VK_RIGHT){
   Rx=Rx+20;
   if(bouncing){
    if(Rx+80>300){
     Rx=220;
    }
   }
   else{
    if(Rx+80>300){
     Rx=220;
    }
    else{
     x=x+20;
     ball.ball_x=x;
    }
   }
   repaint();
  }
 }

向右移动同向左移动原理,因为定义界面横坐标最大值为300,横板长度80,故Rx=220时碰最右侧

砖块设定:

?
1
2
3
4
5
6
7
brick[0]=new Brick(0,60,50,20);
  brick[1]=new Brick(50,60,50,20);
  brick[2]=new Brick(100,60,50,20);
……
brick[16]=new Brick(200,160,50,20);
  brick[17]=new Brick(250,160,50,20);
  ball=new Ball(150,450,10,10); 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void paint(Graphics g){
  super.paint(g);
  ball.rect.setLocation(x,y);
  if(bouncing){
   for(int i=0;i<=17;i++){
    if(brick[i].visible==true){
     switch(i){
      case 0 :g.setColor(Color.blue);
          break;
      case 1 :g.setColor(Color.cyan);
          break;
      case 2 :g.setColor(Color.gray);
          break;
       ……
case 17 :g.setColor(Color.yellow);
          break;
      }
    g.fill3DRect(brick[i].brick_x,brick[i].brick_y,brick[i].brick_width,brick[i].brick_height,true);
    }
   }
   g.setColor(Color.red);
   g.fillOval(x, y, 10, 10);
   g.setColor(Color.blue);
   g.fillRect(Rx,Ry,80,20);

brick[0]=newBrick(0,60,50,20);设置砖块坐标,ball=newBall(150,450,10,10);和小球的坐标

if(brick[i].visible==true)判断砖块存在,用switch语句,逐个对砖块填充颜色,最后四行代码是分别对小球和横板颜色坐标的定义

小球的移动:

?
1
2
3
4
5
6
try{
    Thread.currentThread().sleep(25);
   }
   catch(InterruptedException exception){
    System.err.println(exception.toString());
   }

定义小球的速度,若发生错误,则执行catch语句,打印错误

?
1
2
3
4
5
6
for(int i=0;i<=17;i++){
    if(ball.rect.intersects(brick[i].rect)&&brick[i].visible){
     brick[i].visible=false;
     yUp=!yUp;/
    }
   }

当小球接触到砖块时,砖块不可见(消失)

?
1
2
3
4
5
if(x+5>Rx&&x+5<Rx+80&&y+10>=Ry){
    yUp=false;
    xDx=(int)(Math.random()*5+2);
    yDy=(int)(Math.random()*5+2);
   }

判断小球坐标和横板坐标,当小球落在横板坐标之内,小球反弹,小球横坐标和纵坐标都以一个随机值改变后运动

?
1
2
3
4
5
6
7
8
9
10
11
12
if(xUp==true){
    x+=xDx;
   }
   else{
    x-=xDx;
   }
   if(yUp==true){
    y+=yDy;
   }
   else{
    y-=yDy;
   }

判断小球横坐标如果在增加,小球横坐标=小球原横坐标+小球横坐标增量,否则小球横坐标=小球原横坐标-小球横坐标增量;纵坐标同理

?
1
2
3
4
5
6
7
8
9
10
11
12
if(y<=0){
    y=0;
    ball.ball_y=y;
    yUp=true;
    xDx=(int)(Math.random()*5+2);
    yDy=(int)(Math.random()*5+2);
   }
   else if(y>=MAX_Y-15){
    yDy=(int)(Math.random()*5+2);
    //yUp=false;
    break;
   }

判断小球到画面顶部(定义顶部的纵坐标为0),小球向下反弹,原理同小球和横板接触的反弹规则,否则,判断小球纵坐标是否大于MAX_Y-15(纵坐标最大值-15),反弹规则改变为横坐标不变,纵坐标随机改变

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(x<=0){
    x=0;
    ball.ball_x=x;
    xUp=true;
    xDx=(int)(Math.random()*5+2);
    yDy=(int)(Math.random()*5+2);
   }
   else if(x>=MAX_X-10){
    x=MAX_X-10;
    ball.ball_x=x;
    xDx=(int)(Math.random()*5+2);
    yDy=(int)(Math.random()*5+2);
    xUp=false;
   }

判断小球到画面最左侧(定义最左侧横坐标为0),向右侧反弹,反弹规则同小球和横板接触的反弹规则,或者小球到画面最右侧,向左反弹,反弹规则同上,(if(x>=MAX_X-10)判断小球是否到右边侧,小球的直径为10)

?
1
2
3
4
5
6
int i;                    
   for(i=0;i<=17&&brick[i].visible==false;i++){ 
   }
   if(i==18){
    break;
   }

如果所有砖块都不可见,则重新玩

?
1
2
3
4
5
6
7
8
9
10
11
12
13
renew=true;     //初始化
  bouncing=false;
  for(int i=0;i<=17;i++){
   brick[i].visible=true;
  }
  xUp=true;
  yUp=false;
  xDx=1;
  yDy=1;
  x=150;
  y=450;
  Rx=120;
  Ry=460;       //

重新开始,初始化,小球静止,所有砖块可见,小球在横坐标方向,可随横板移动而移动,纵坐标在未开时游戏前不能改变,定义小球横坐标和纵坐标增量都为1,小球初始位置坐标(150,450)横板初始位置坐标(120,460)

[源程序]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class HitBrick extends JFrame implements KeyListener{
    private BallThread greenBallThread;
    //控制小球的线程
    private Boolean xUp,yUp,bouncing;
    private int x,y,xDx,yDy;
    //小球坐标,增量
    private final int MAX_X=300,MAX_Y=500;
    private Boolean renew;
    private JLabel label;
    private int Rx,Ry;
    //横板坐标
    private Brick brick[]=new Brick[18];
    //砖块
    private Ball ball;
    //小球
    public HitBrick(){
        super("打砖块");
        Container pane=getContentPane();
        //设置空白面板容器
        label=new JLabel("按空格键开始");
        //标签
        label.setHorizontalAlignment(JLabel.CENTER);
        //水平
        label.setVerticalAlignment(JLabel.BOTTOM);
        //垂直
        pane.add(label);
        //向面板里添加标签
        xUp=true;
        //横坐标可以移动
        yUp=false;
        //纵坐标不可以移动
        xDx=1;
        yDy=1;
        x=150;
        //小球坐标
        y=450;
        Rx=120;
        //横板坐标
        Ry=460;
        renew=true;
        bouncing=false;
        addKeyListener(this);
        //键盘监听器
        brick[0]=new Brick(0,60,50,20);
        //砖块坐标
        brick[1]=new Brick(50,60,50,20);
        brick[2]=new Brick(100,60,50,20);
        brick[3]=new Brick(150,60,50,20);
        brick[4]=new Brick(200,60,50,20);
        brick[5]=new Brick(250,60,50,20);
        brick[6]=new Brick(0,90,50,20);
        brick[7]=new Brick(50,110,50,20);
        brick[8]=new Brick(100,130,50,20);
        brick[9]=new Brick(150,130,50,20);
        brick[10]=new Brick(200,110,50,20);
        brick[11]=new Brick(250,90,50,20);
        brick[12]=new Brick(0,160,50,20);
        brick[13]=new Brick(50,160,50,20);
        brick[14]=new Brick(100,160,50,20);
        brick[15]=new Brick(150,160,50,20);
        brick[16]=new Brick(200,160,50,20);
        brick[17]=new Brick(250,160,50,20);
        ball=new Ball(150,450,10,10);
        //球的坐标
        setSize(MAX_X,MAX_Y);
        //窗口大小
        setResizable(false);
        setVisible( true );
        //可视化
    }
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() ==e.VK_SPACE) {
            if(renew){
                greenBallThread=new BallThread(this);
                bouncing = true;
                greenBallThread.start();
                label.setVisible(false);
            }
            renew=false;
        }
        if(e.getKeyCode()==e.VK_LEFT){
            Rx=Rx-20;
            if(bouncing){
                if(Rx<0){
                    Rx=0;
                }
            } else{
                if(Rx<0){
                    Rx=0;
                } else{
                    x=x-20;
                    ball.ball_x=x;
                }
            }
            repaint();
        }
        if(e.getKeyCode()==e.VK_RIGHT){
            Rx=Rx+20;
            if(bouncing){
                if(Rx+80>300){
                    Rx=220;
                }
            } else{
                if(Rx+80>300){
                    Rx=220;
                } else{
                    x=x+20;
                    ball.ball_x=x;
                }
            }
            repaint();
        }
    }
    public void keyReleased (KeyEvent e) {
    }
    public void keyTyped (KeyEvent e){
    }
    public void paint(Graphics g){
        super.paint(g);
        ball.rect.setLocation(x,y);
        if(bouncing){
            for (int i=0;i<=17;i++){
                if(brick[i].visible==true){
                    switch(i){
                        case 0 :g.setColor(Color.blue);
                        break;
                        case 1 :g.setColor(Color.cyan);
                        break;
                        case 2 :g.setColor(Color.gray);
                        break;
                        case 3 :g.setColor(Color.green);
                        break;
                        case 4 :g.setColor(Color.magenta);
                        break;
                        case 5 :g.setColor(Color.yellow);
                        break;
                        case 6 :g.setColor(Color.white);
                        break;
                        case 7 :g.setColor(Color.black);
                        break;
                        case 8 :g.setColor(Color.orange);
                        break;
                        case 9 :g.setColor(Color.pink);
                        break;
                        case 10 :g.setColor(Color.darkGray);
                        break;
                        case 11 :g.setColor(Color.red);
                        break;
                        case 12 :g.setColor(Color.blue);
                        break;
                        case 13 :g.setColor(Color.cyan);
                        break;
                        case 14 :g.setColor(Color.gray);
                        break;
                        case 15 :g.setColor(Color.green);
                        break;
                        case 16 :g.setColor(Color.magenta);
                        break;
                        case 17 :g.setColor(Color.yellow);
                        break;
                    }
                    g.fill3DRect(brick[i].brick_x,brick[i].brick_y,brick[i].brick_width,brick[i].brick_height,true);
                }
            }
            g.setColor(Color.red);
            g.fillOval(x, y, 10, 10);
            g.setColor(Color.blue);
            g.fillRect(Rx,Ry,80,20);
        } else{
            for (int i=0;i<=17;i++){
                switch(i){
                    case 0 :g.setColor(Color.blue);
                    break;
                    case 1 :g.setColor(Color.cyan);
                    break;
                    case 2 :g.setColor(Color.gray);
                    break;
                    case 3 :g.setColor(Color.green);
                    break;
                    case 4 :g.setColor(Color.magenta);
                    break;
                    case 5 :g.setColor(Color.yellow);
                    break;
                    case 6 :g.setColor(Color.white);
                    break;
                    case 7 :g.setColor(Color.black);
                    break;
                    case 8 :g.setColor(Color.orange);
                    break;
                    case 9 :g.setColor(Color.pink);
                    break;
                    case 10 :g.setColor(Color.darkGray);
                    break;
                    case 11 :g.setColor(Color.red);
                    break;
                    case 12 :g.setColor(Color.blue);
                    break;
                    case 13 :g.setColor(Color.cyan);
                    break;
                    case 14 :g.setColor(Color.gray);
                    break;
                    case 15 :g.setColor(Color.green);
                    break;
                    case 16 :g.setColor(Color.magenta);
                    break;
                    case 17 :g.setColor(Color.yellow);
                    break;
                }
                g.fill3DRect(brick[i].brick_x,brick[i].brick_y,brick[i].brick_width,brick[i].brick_height,true);
            }
            g.setColor(Color.red);
            g.fillOval(x, y, 10, 10);
            g.setColor(Color.blue);
            g.fillRect(Rx, Ry, 80, 20);
        }
    }
    public void move(){
        while(true){
            try{
                Thread.currentThread().sleep(25);
            }
            catch(InterruptedException exception){
                System.err.println(exception.toString());
            }
            for (int i=0;i<=17;i++){
                if(ball.rect.intersects(brick[i].rect)&&brick[i].visible){
                    brick[i].visible=false;
                    yUp=!yUp;
                    //打到球不可见
                }
            }
            if(x+5>Rx&&x+5<Rx+80&&y+10>=Ry){
                yUp=false;
                xDx=(int)(Math.random()*5+2);
                //小球坐标增量
                yDy=(int)(Math.random()*5+2);
            }
            if(xUp==true){
                x+=xDx;
                //小球左右移动坐标改变
            } else{
                x-=xDx;
            }
            if(yUp==true){
                y+=yDy;
            } else{
                y-=yDy;
            }
            if(y<=0){
                y=0;
                ball.ball_y=y;
                yUp=true;
                xDx=(int)(Math.random()*5+2);
                yDy=(int)(Math.random()*5+2);
            } else if(y>=MAX_Y-15){
                yDy=(int)(Math.random()*5+2);
                //yUp=false;
                break;
            }
            if(x<=0){
                x=0;
                ball.ball_x=x;
                xUp=true;
                xDx=(int)(Math.random()*5+2);
                yDy=(int)(Math.random()*5+2);
            } else if(x>=MAX_X-10){
                x=MAX_X-10;
                ball.ball_x=x;
                xDx=(int)(Math.random()*5+2);
                yDy=(int)(Math.random()*5+2);
                xUp=false;
            }
            ball.rect.setLocation(ball.ball_x,ball.ball_y);
            repaint();
            int i;
            //如果所有砖块都不可见
            for (i=0;i<=17&&brick[i].visible==false;i++){
                //则重新玩
            }
            if(i==18){
                break;
            }
            //
        }
        renew=true;
        //初始化
        bouncing=false;
        for (int i=0;i<=17;i++){
            brick[i].visible=true;
        }
        xUp=true;
        yUp=false;
        xDx=1;
        yDy=1;
        x=150;
        y=450;
        Rx=120;
        Ry=460;
        //
        repaint();
        repaint();
        label.setVisible(true);
    }
    public static void main(String[] args) {
        HitBrick mar=new HitBrick();
    }
}
class BallThread extends Thread{
    private HitBrick m;
    BallThread(HitBrick a){
        //super();
        m=a;
    }
    public void run(){
        m.move();
        m.repaint();
    }
}
class Brick{
    Rectangle rect=null;
    //长方形对象,砖块按钮的位置和宽高
    int brick_x,brick_y;
    //按扭的左上角坐标
    int brick_width,brick_height;
    //按扭的宽和高
    Boolean visible;
    public Brick(int x,int y,int w,int h)
       {
        brick_x=x;
        brick_y=y;
        brick_width=w;
        brick_height=h;
        visible=true;
        rect=new Rectangle(x,y,w,h);
        //创建长方形对象---砖块按钮的位置和宽高。
    }
}
class Ball{
    Rectangle rect=null;
    int ball_x,ball_y;
    int ball_width,ball_height;
    public Ball(int x,int y,int w,int h){
        ball_x=x;
        ball_y=y;
        ball_width=w;
        ball_height=h;
        rect=new Rectangle(x,y,w,h);
    }
}

运行结果:

Java编程经典小游戏设计-打砖块小游戏源码

空格键开始,方向键控制左右,死亡重新开始。

虽然系统的基本功能都已实现,但还是存在系统不稳定等多个bug尚待解决。在做系统的过程中遇到了很多问题,有的是知识存储不足,有的是考虑不够周全,所以学习之路永无止境。作为一个程序编程人员,要保持清醒的头脑,以现实为依据,让自己的每一行代码都能实现自己的意义。

总结

以上就是本文关于Java编程经典小游戏设计-打砖块小游戏源码的全部内容,希望对大家有所帮助。有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!

原文链接:http://blog.csdn.net/niaizhan/article/details/23104247