版本一:
功能点:
(1) 会动的球
(2) 有背景图
(3) 最大化时图能适配、覆盖整个屏幕
(4) 球在碰到边界时会反弹
版本二:
新增功能点:
(1)球能被键盘控制,W代表上,S代表下,A代表左,D代表右
版本三(当前版本):
新增功能点:
(1)多个不同大小、不同颜色、不同初始位置、不同运动轨迹、且球作布朗运动(无规则运动)。
(2)球每触一下边界就改变颜色
后期版本:
新增功能点:
(1)球球接触时会穿过彼此
(2)背景图隔一段时间就自动换一张图片
(3)能通过键盘将屏保最小化和关闭
// 窗体模板类
package MovingBall3;
import java.awt.LayoutManager;
import javax.swing.JFrame;
public abstract class UI extends JFrame {
// 默认窗体
public UI(LayoutManager layout) {
this(500, 600, null);
}
public UI(int width, int height) {
this(width, height, null);
}
// 窗体
public UI(int width, int height, LayoutManager layout) {
this.setSize(width, height);
this.setLocationRelativeTo(null);
this.setTitle("跳跳球");
this.setDefaultCloseOperation(3);
this.setLayout(layout);// 布局
this.setAlwaysOnTop(true);
}
public abstract void addViews();
public abstract void dealLogic();
}
/**
* 彩色球主窗体类
**/
package MovingBall3;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
public class BallUI extends UI {
Ball ball;
MyBall mb;
Color[] color = { Color.red, Color.cyan, Color.green, Color.blue, Color.LIGHT_GRAY, Color.orange, Color.pink,
Color.yellow, Color.white };
ArrayList<Ball> array;
Random random = new Random(); // 随机数生成器
int xStart;
int yStart;
public BallUI(int width, int height) {
super(width, height);
addViews();
// 添加监听器
this.setVisible(true);
dealLogic();
}
@Override
public void addViews() {
setUndecorated(true);
getGraphicsConfiguration().getDevice().setFullScreenWindow(this);
array = new ArrayList<>();
for (int i = 0; i < 50; i++) {
xStart = random.nextInt(this.getWidth()) / 2 + random.nextInt(this.getWidth()) / 4; // 起点坐标
yStart = random.nextInt(this.getHeight()) / 2 + random.nextInt(this.getHeight()) / 4;
int colorIndex = random.nextInt(color.length); // 颜色数组下标
int ballRadius = random.nextInt(50) + 30;
int speed = random.nextInt(10) - 5;
while (speed == 0) {
speed = random.nextInt(10) - 5;
}
ball = new Ball(xStart, yStart, ballRadius, this, speed);
ball.currentColor = color[random.nextInt(9)];
Thread thead = new Thread(ball);
System.out.println("执行了");
thead.start();
array.add(ball);
}
}
@Override
public void dealLogic() {
new Thread() {
public void run() {
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
// 添加退出监听
}
@Override
public void paint(Graphics g) {
// 二级缓存
System.out.println(this.getWidth());
Color background = getContentPane().getBackground();
Image bg = createImage(this.getWidth(), this.getHeight()); // 图板架
Graphics g_bg = bg.getGraphics();
ImageIcon imageIcon = new ImageIcon("images/25540-106.jpg"); // 图像图标=》画在图板架
Image image = imageIcon.getImage();
g_bg.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
// 自动球:
// Iterator<Ball> it = array.iterator();
for (int i = 0; i < array.size(); i++) {
Ball ba = array.get(i);
g_bg.setColor(ba.currentColor);
g_bg.fillOval(ba.x, ba.y, ba.r, ba.r);
}
// 贴上去
g.setColor(background);
g.drawImage(bg, 0, 0, null);
}
}
/**
*
**/
package MovingBall3;
public class MyBall implements Runnable {
int x, y; // 起始位置
int r; // 小球半径
BallUI b;
int speedX = 10; // 速度
int speedY = 10;
boolean isUp, isDown, isRight, isLeft;
public MyBall(int x, int y, int r, BallUI b) {
this.x = x;
this.y = y;
this.r = r;
this.b = b;
}
@Override
public void run() {
while (true) {
// System.out.println("hergr");
if (isUp) {
if (y <= 30) {
isUp = !isUp;
} else {
y -= speedY;
}
}
if (isDown) {
if (y >= b.getHeight() - 40) {
isDown = !isDown;
} else {
y += speedY;
}
}
if (isLeft) {
if (x <= 10) {
isLeft = !isLeft;
} else {
x -= speedX;
}
}
if (isRight) {
if (x >= b.getWidth() - 40) {
isRight = !isRight;
} else {
x += speedX;
}
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public String toString() {
return "MyBall [x=" + x + ", y=" + y + ", r=" + r + ", b=" + b + ", speedX=" + speedX + ", speedY=" + speedY
+ ", isUp=" + isUp + ", isDown=" + isDown + ", isRight=" + isRight + ", isLeft=" + isLeft + "]";
}
}
/**
* 球体类
**/
` ``
package MovingBall3;
import java.awt.Color;
import java.util.Random;
public class Ball implements Runnable {
int x = 0, y = 0; // 起始坐标
int r; // 大小
BallUI b;
Color currentColor;
int speed;
Random random = new Random();
public Ball(int x, int y, int r, BallUI b, int speed) {
this.x = x;
this.y = y;
this.r = r;
this.b = b;
this.speed = speed;
}
public void run() {
boolean isRight = true;
// boolean isLeft = true;
boolean isUp = true;
// boolean isDown = true;
while (true) {
int x2 = b.getWidth() - r;
int y2 = b.getHeight() - r;
if (isRight) {
x += speed;
if (x > x2 || x < r) {
isRight = false;
}
} else {
x -= speed;
if (x > x2 || x < r) {
isRight = true;
}
}
if (isUp) {
y -= speed;
if (y < r || y > y2) {
isUp = false;
}
} else {
y += speed;
if (y < r || y > y2) {
isUp = true;
}
}
b.repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 键盘监听器类
**/
package MovingBall3;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MyKeyListener implements KeyListener {
MyBall mb;
public MyKeyListener(MyBall mb) {
this.mb = mb;
}
@Override
public void keyPressed(KeyEvent e) {
int kc = e.getKeyCode();
if (kc == 87) { // 上
mb.isUp = true;
}
if (kc == 83) { // 下
mb.isDown = true;
}
if (kc == 65) { // 左
mb.isLeft = true;
}
if (kc == 68) { // 右
mb.isRight = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
int kc = e.getKeyCode();
if (kc == 87) { // 上
mb.isUp = false;
}
if (kc == 83) { // 下
mb.isDown = false;
}
if (kc == 65) { // 左
mb.isLeft = false;
}
if (kc == 68) { // 右
mb.isRight = false;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
}
/**
* 测试类
**/
package MovingBall3;
public class Test {
public static void main(String[] args) {
BallUI ballUI = new BallUI(1000, 500);
}
}
运行结果: