java实现简单窗体小游戏----球球大作战
需求分析
1、分析小球的属性:

​ 坐标、大小、颜色、方向、速度

2、抽象类:Ball

​ 设计类:BallMain—创建窗体

​ BallJPanel—画小球

​ BallAndBall—处理小球之间的关系

3、流程:

​ 1)小球的绘制

​ 2)产生小球,让一个小球进行运动,多个小球的运动

​ 3)小球进行碰撞

​ 4)实现大球吃小球

源代码如下:
Ball.java

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

public class Ball {
/* 小球的基本属性 */
int x, y;//定义x, y坐标
int d;//直径
Color ballColor;//小球的颜色
int speed;//小球的运动速度
int position;//小球的运动方向

/*小球的运动方向*/
public static final int LEFT_UP = 0;//左上
public static final int RIGHT_UP = 1;//右上
public static final int LEFT_DOWN = 2;//左下
public static final int RIGHT_DOWN = 3;//右下

/*构造方法*/
public Ball(int x, int y, int position, int d, int speed, Color ballColor){
this.x = x;
this.y = y;
this.position = position;
this.d = d;
this.speed = speed;
this.ballColor = ballColor;
}
//构造玩家球
public Ball(int x, int y, int d, int speed, Color ballColor){
this.x = x;
this.y = y;
this.d = d;
this.speed = speed;
this.ballColor = ballColor;
}

//画小球
public void drawBall(Graphics g){
g.setColor(ballColor);
g.fillOval(x, y, d, d);
}
public void drawBall2(Graphics g){
g.setColor(ballColor);
g.fillOval(x, y, d, d);

//球加文字
g.setColor(Color.RED);
//设置字体大小
Font font = new Font(Font.DIALOG, Font.BOLD, 14);
g.setFont(font);
g.drawString("^_^", x+d/2, y+d/2);
}

//小球的运动方向
public void ballMove(){
switch (this.position) {
case LEFT_UP:
x -= speed;
y -= speed;
if (x <= 0) {
this.position = RIGHT_UP;
}else if (y <= 0) {
this.position = LEFT_DOWN;
}
break;
case RIGHT_UP:
x += speed;
y -= speed;
if (x >= BallMain.SCREEN_WIDTH - d) {
this.position = LEFT_UP;
}else if (y <= 0) {
this.position = RIGHT_DOWN;
}
break;
case LEFT_DOWN:
x -= speed;
y += speed;
if (x <= 0) {
this.position = RIGHT_DOWN;
}else if (y >= BallMain.SCREEN_HEIGHT - d) {
this.position = LEFT_UP;
}
break;
case RIGHT_DOWN:
x += speed;
y += speed;
if (x >= BallMain.SCREEN_WIDTH - d) {
this.position = LEFT_DOWN;
}else if (y >= BallMain.SCREEN_HEIGHT - d) {
this.position = RIGHT_UP;
}
break;
}
}
}
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
BallMain.java

import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.JFrame;

import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import sun.audio.ContinuousAudioDataStream;

/*创建窗体*/
public class BallMain extends JFrame{
//窗体的宽高
public static final int SCREEN_WIDTH = 1360;
public static final int SCREEN_HEIGHT = 760;

//全屏
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int)d.getWidth();
int height = (int)d.getHeight();

public BallMain(){
this.setTitle("V1.0");
//设置位置
this.setBounds(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);

//添加小球到窗体
BallJPanel bj = new BallJPanel();
this.add(bj);

//添加键盘的监听事件
this.addKeyListener(bj);

/*frame.addKeyListener(tj);
tj.addKeyListener(tj);
*/
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}

public static void main(String[] args) {
BallMain b = new BallMain();
//添加音乐
try {
FileInputStream f =new FileInputStream("music/yyyy.wav");
AudioStream as = new AudioStream(f);
AudioPlayer.player.start(as);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
}
}
}
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
BallJPanel.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/*画小球*/
public class BallJPanel extends JPanel implements KeyListener{
//存储小球的集合
List<Ball> ballList = new ArrayList<Ball>();
int x1 = 450;
int y1 = 450;
int d1 = 40;
private Color white;
//玩家球
Ball game = new Ball(x1, y1, d1, 50, white);

//小球的数量
private int ballNumber = 100;

public BallJPanel(){
addBall();
startBalls();
}

//产生小球的方法
public void addBall(){
for (int i = 0; i < ballNumber; i++) {
//随机产生100个小球
int x = (int)(Math.random()*BallMain.SCREEN_WIDTH);
int y = (int)(Math.random()*BallMain.SCREEN_HEIGHT);
int position = (int)(Math.random()*4);
// int d = (int)(Math.random()*50 + 1);
int d = 20;
int speed = 1;

//颜色 三原色 R G B
int red = (int)(Math.random()*255 + 1);
int green = (int)(Math.random()*255 + 1);
int blue = (int)(Math.random()*255 + 1);
Color ballColor = new Color(red, green, blue);
Ball b = new Ball(x, y, position, d, speed, ballColor);

//将小球添加到集合中
ballList.add(b);
}
}

public void paint(Graphics g){
super.paint(g);

BufferedImage img =null;
//添加图片
try {
img = ImageIO.read(new File("music/timg.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.drawImage(img, 0, 0, 1360, 760, this);

this.setBackground(Color.CYAN);

for (int i = 0; i < ballList.size(); i++) {
Ball ball = ballList.get(i);
ball.drawBall(g);

}

//玩家
game.drawBall2(g);

}

public void startBalls(){
//启动线程-----匿名内部类
new Thread(){
public void run() {
while (true) {
//遍历小球集合
for (int i = 0; i < ballList.size(); i++) {
//取出小球
Ball b = ballList.get(i);
//让每一个小球进行移动
b.ballMove();
}
for (int i = 0; i < ballList.size(); i++) {
//先取第一个小球
Ball b1 = ballList.get(i);
for (int j = i+1; j < ballList.size(); j++) {
Ball b2 = ballList.get(j);
BallAndBall bad = new BallAndBall();
//bad.ballCrach(b1, b2);
if(bad.isBallCrach(b1, b2)){
if (b1.d >= b2.d) {
b1.d += b2.d/3;
ballList.remove(b2);
break;
}else if(b1.d < b2.d){
b2.d += b1.d/3;
ballList.remove(b1);
break;
}
}
if (bad.isBallCrach(b1, game)) {
if (bad.isBallCrach(b1, game)) {
if (b1.d > game.d) {
System.out.println("GAME OEVR");
JOptionPane.showMessageDialog(null, "GAME OVER");
return;
}else{
game.d += b1.d/3;
ballList.remove(b1);
break;
}
}
}
}
}
repaint();//重绘
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub

}

@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_UP) {
// System.out.println("点击了上方向键");
game.y -= 10;
}

if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// System.out.println("点击了下方向键");
game.y += 10;
}

if (e.getKeyCode() == KeyEvent.VK_LEFT ) {
// System.out.println("点击了左方向键");
game.x -= 15;
}

if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// System.out.println("点击了右方向键");
game.x += 15;
}
if (e.getKeyCode() == KeyEvent.VK_1) {
// System.out.println("点击了右方向键");
game.x += 10;
game.y -= 10;
}
if (e.getKeyCode() == KeyEvent.VK_2) {
// System.out.println("点击了右方向键");
game.x -= 10;
game.y -= 10;
}
if (e.getKeyCode() == KeyEvent.VK_3) {
// System.out.println("点击了右方向键");
game.x -= 10;
game.y += 10;
}
if (e.getKeyCode() == KeyEvent.VK_4) {
// System.out.println("点击了右方向键");
game.x += 10;
game.y += 10;
}
repaint();

}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub

}
}
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
BallAndBall.java

/*处理小球之间的关系*/
public class BallAndBall {

//两小球碰撞
public void ballCrach(Ball b1, Ball b2){
int x1 = b1.x + b1.d/2;
int y1 = b1.y + b1.d/2;
int x2 = b2.x + b2.d/2;
int y2 = b2.y + b2.d/2;

double e = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
//如果碰撞上
if (e <= b1.d/2 + b2.d/2) {
//b1小球
switch (b1.position) {
case Ball.LEFT_UP:
b1.position = Ball.RIGHT_DOWN;
break;
case Ball.RIGHT_UP:
b1.position = Ball.LEFT_DOWN;
break;
case Ball.LEFT_DOWN:
b1.position = Ball.RIGHT_UP;
break;
case Ball.RIGHT_DOWN:
b1.position = Ball.LEFT_UP;
break;
}
//b2小球
switch (b2.position) {
case Ball.LEFT_UP:
b2.position = Ball.RIGHT_DOWN;
break;
case Ball.RIGHT_UP:
b2.position = Ball.LEFT_DOWN;
break;
case Ball.LEFT_DOWN:
b2.position = Ball.RIGHT_UP;
break;
case Ball.RIGHT_DOWN:
b2.position = Ball.LEFT_UP;
break;
}
}
}

//检查是否碰撞上
public boolean isBallCrach(Ball b1, Ball b2){
boolean flag = false;
int x1 = b1.x + b1.d/2;
int y1 = b1.y + b1.d/2;
int x2 = b2.x + b2.d/2;
int y2 = b2.y + b2.d/2;
//计算圆心距
double e = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));

if (e <= b1.d/2 + b2.d/2) {
return true;
}

return false;
}
}

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
其中音乐和图片可自行修改,只需要修改路径即可,音乐格式为wav,我个人用的音乐是彩豆森林
---------------------

java实现简单窗体小游戏----球球大作战的更多相关文章

  1. Scratch 简单的小游戏 --- 碰碰球

    Scratch 简单的小游戏 --- 碰碰球 ================================ 积木脚本块的简要分类: 1. 角色 2. 背景 3. 角色和背景组成的场景 4. 挡板角 ...

  2. canvas写个简单的小游戏

    之前在HTML5 Canvas属性和方法汇总一文中,介绍过Canvas的各种属性以及方法的说明,并列举了自己写的一些Canvas demo,接下来开始写一个简单的小游戏吧,有多简单,这么说吧,代码不到 ...

  3. HTML5小游戏-简单抽奖小游戏

    换了新工作以后,专注前端开发,平常空闲时间也比较多,可以多钻研一下技术,写一下博客.最近在学习canvas,参考网上的slotmachine插件,用canvas实现了一个简单抽奖小游戏.       ...

  4. 用Java编写的猜拳小游戏

    学习目标: 熟练掌握各种循环语句 例题: 代码如下: // 综合案例分析,猜拳案例 // isContinue为是否开始游戏时你所输入的值 char isContinue; //y为开始,n为借宿 S ...

  5. hihoCoder 1114 小Hi小Ho的惊天大作战:扫雷·一 最详细的解题报告

    题目来源:小Hi小Ho的惊天大作战:扫雷·一 解题思路:因为只要确定了第一个是否有地雷就可以推算出后面是否有地雷(要么为0,要么为1,如果不是这两个值就说明这个方案行不通),如果两种可能中有一种成功, ...

  6. hiho #1114 : 小Hi小Ho的惊天大作战:扫雷·一

    #1114 : 小Hi小Ho的惊天大作战:扫雷·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 故事背景:密室.监视器与充满危机的广场 “我们还是循序渐进,先来考虑这 ...

  7. Java开发小游戏 用键盘控制精灵在游戏中上下左右跑动 窗体小游戏可打包下载,解压后双击start运行

    package com.swift; import java.awt.Point; import java.awt.event.KeyEvent; import com.rupeng.game.Gam ...

  8. 无聊的周末用Java写个扫雷小游戏

    周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ...

  9. 使用JavaScript实现简单的小游戏-贪吃蛇

    最近初学JavaScript,在这里分享贪吃蛇小游戏的实现过程, 希望能看到的前辈们能指出这个程序的不足之处. 大致思路 首先要解决的问题 随着蛇头的前进,尾巴也要前进. 用键盘控制蛇的运动方向. 初 ...

随机推荐

  1. 20180703mysql运维专题一:利用etl监控mysql日志

    参考地址: https://www.elastic.co/solutions/logging https://www.elastic.co/guide/en/beats/filebeat/curren ...

  2. MySql 格式化时间(包括正常时间格式与unix时间戳的互相转换)

    函数:FROM_UNIXTIME 作用:将MYSQL中以INT(11)存储的时间以"YYYY-MM-DD"格式来显示.语法:FROM_UNIXTIME(unix_timestamp ...

  3. PHP包管理工具composer简单总结

    前言 接触laravel之后,才知道有PSR,composer之类的东西,PHP已经不再是一门草根语言了.最近在尝试玩thrift,需要安装PHP thrift依赖库,使用composer insta ...

  4. Mac OSX:添加host地址

    Mac OSX的hosts文件位于/private/etc/hosts.记得用sudo权限编辑即可.在文件中添加如下内容: xxx.xxx.xxx.xxx (ip地址)     abc.com(你的h ...

  5. Supervisor-进程监控自动重启

    Supervisor是一个进程监控程序. 需求一:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了Sup ...

  6. SharePoint 2013 关闭 customErrors

    在SharePoint 2013上做开发时,如果不把customErrors 关掉,那调试起来那真叫一个费劲.在2013里,关闭customErrors 和2010一样,只要把文件路径改成15目录下即 ...

  7. 学习笔记——node.js

    node.js的作用在于,号称可以让服务器支持更多的连接.比如说,php + apche可以让服务器支持4000个并发连接,那么node.js + apche可以让服务器支持并发几万个. 为什么这么牛 ...

  8. Mac safari 下iframe的hash取不到BUG

    RT http://192.168.1.66/salaryl#abc 这样的链接是取不到hash的, 需要在最后加上斜杠,如下:http://192.168.1.66/salaryl/#abc fuc ...

  9. hdoj--5233--Gunner II(map+queue&&二分)

     Gunner II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  10. (Go)09.指针赋值修改示例

      答案: 1 package main 2 import ( 3 "fmt" 4 ) 5 6 7 func modify(p *int) { 8 fmt.Println(p) 9 ...