最后一次更新于2019/07/08
修复问题:
错误输入未提醒问题
碰撞小球的图形重叠问题
高速小球越界问题
感谢
大一暑假拜读学姐的一篇文章:我说这是一篇很严肃的技术文章你信吗,本篇在她的基础上加以改进。
效果演示图
基本思路
要实现小球运动,可以从以下几点切入:
1. 小球都有那些具体特征?
涉及动能定理就需要考虑质量了,除此之外常规的几个变量也不能忘:方向、球的尺寸,所在位置以及当前速度。
2. 谁能初始小球的状态?
小球的状态无非两种:(随机)默认值、人工手动输入。
3. 谁能控制小球的运动?
我们控制小球是需要给予一定的指令的,就算是鼠标点击也是简单的指令之一,除此之外如果想要拥有稍微复杂一点的指令可以使用按钮来实现。
根据分析,我们大概能构造出大概的类,无非是一个专门描述小球状态的,一个控制所有命令的,一个构建出窗口和选项的。我们还可以在细化这三个类的功能:
球类
因为窗口也是二维的,构造方法仅需要包含:质量,沿x、y轴的分速度,二维坐标表示的位置,颜色,大小, 所在的画板。
小球的外在属性:颜色,尺寸。
小球的移动情况:
遇到边界直接反弹
移动距离利用公式:距离 = 当前距离 + 速度 × 时间(这边直接简化成1)
小球之间的完全弹性碰撞公式:
$$\frac{ { {\rm{(}}{ {\rm{m}}_1} - {m_2}){v_{10}} + 2{m_2}{v_{20}}}}{ { { {\rm{m}}_1} + {m_2}}}$$
$$\frac{ { {\rm{(}}{ {\rm{m}}_2} - {m_1}){v_{20}} + 2{m_1}{v_{10}}}}{ { { {\rm{m}}_1} + {m_2}}}$$
碰撞的两球形状尽量不要重叠,当程序检测到这种意外时要尽可能拉开两球之间的距离,直到两球距离恰好等于两球半径之和。
代码如下:
/**
* 这个类主要是用来设置小球的各种属性以及运动关系。
* @author Hephaest
* @version 2019/7/5
* @since jdk_1.8.202
*/
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
public class Ball{
/**
* 声明小球的各种变量。
*/
private int xPos, yPos, size, xSpeed, ySpeed,mass;
private Color color;
private BallFrame bf;
/**
* 球类的构造函数。
* @param xPos 小球在X轴上的位置。
* @param yPos 小球在Y轴上的位置。
* @param size 小球的直径长度。
* @param xSpeed 小球在X轴上的分速度。
* @param ySpeed 小球在Y轴上的分速度。
* @param color 小球的颜色。
* @param mass 小球的质量。
* @param bf 当前小球所在的画板。
*/
public Ball(int xPos, int yPos, int size, int xSpeed, int ySpeed, Color color, int mass, BallFrame bf) {
super();
this.xPos = xPos;
this.yPos = yPos;
this.size = size;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.color = color;
this.mass = mass;
this.bf = bf;
}
/**
* 在画板上绘制小球。
* @param g 当前小球。
*/
public void drawBall(Graphics g) {
if(xPos + size> bf.getWidth() - 4) xPos = bf.getWidth() - size - 4;
else if(xPos < 4) xPos = 4;
if(yPos < 4) yPos = 4;
else if(yPos > bf.getHeight()) yPos = bf.getHeight() - size - 4;
g.setColor(color);
g.fillOval(xPos, yPos, size, size);
}
/**
* 该方法是用来判断下一秒小球的移动方向并计算当前小球的位置。
* @param bf 当前小球所在的画板。
*/
public void moveBall(BallFrame bf) {
if (xPos + size + xSpeed > bf.getWidth() - 4 || xPos + xSpeed < 4)
{
xSpeed = -xSpeed;
}
if (yPos + ySpeed < 2 || yPos + size + ySpeed > bf.getHeight() - 163)
{
ySpeed = - ySpeed;
}<