基本上和 java 的语法一致,例如
class Car{
String name;
int price;
public Car(String name, int price){
this.name = name;
this.price = price;
}
public void printInfo(){
println("name:" + this.name);
println("price:" + this.price);
}
}
以上是一个非常简单的例子,接下来我门实现真实的例子
class MyCircle {
float x, y, r;
float vx, vy;
float H;
public MyCircle(float x, float y, float r) {
this.x = x;
this.y = y;
this.r = r;
this.vx = random(0.5);
this.vy = random(0.5);
this.H = random(255);
}
public void draw() {
fill(H, 255, 255, 10);
ellipse(this.x, this.y, 2 * this.r, 2 * this.r);
}
public void update() {
this.x += this.vx;
this.y += this.vy;
}
public void checkEdge(){
if(this.x <= r){
this.x = r;
this.vx = -this.vx;
}
if(this.x + r >= width){
this.x = width - r;
this.vx = -this.vx;
}
if(this.y <= r){
this.y = r;
this.vy = -this.vy;
}
if(this.y + r >= height){
this.y = height - r;
this.vy = -this.vy;
}
}
public void checkOther(MyCircle o){
float dis = dist(this.x, this.y, o.x, o.y);
if(dis <= r + o.r){
float dirx = o.x - this.x;
float diry = o.y - this.y;
float D = sqrt(sq(dirx) + sq(diry));
dirx /= D;
diry /= D;
float F = sqrt(sq(this.vx) + sq(this.vy));
this.vx = - F * dirx;
this.vy = - F * diry;
F = sqrt(sq(o.vx) + sq(o.vy));
o.vx = F * dirx;
o.vy = F * diry;
}
}
}
MyCircle 类主要有圆心坐标个和半径 x, y, r 速度vx, vy, 还有一个色度 H,表示圆的颜色。
在构造方法中,直接传入 x, y, r, 而 vx,vy, H 随机产生,所以产生的圆颜色和大小随机。
接下来两个方法
// 绘制自身, 注意用 HSB 模式绘制,不透明度设置较低,作出透明效果
public void draw() {
fill(H, 255, 255, 10); //
ellipse(this.x, this.y, 2 * this.r, 2 * this.r);
}
// 根据位置和速度更新自己的位置信息
public void update() {
this.x += this.vx;
this.y += this.vy;
}
这两个方法比较简单,主要是实现位置更新和绘制。但是球可能直接跑出屏幕范围,所以要检查一下:
public void checkEdge(){
// 检查左侧是否出界
if(this.x <= r){
this.x = r;
this.vx = -this.vx;
}
// 检查右侧是否出界
if(this.x + r >= width){
this.x = width - r;
this.vx = -this.vx;
}
// 检查上侧是否出界
if(this.y <= r){
this.y = r;
this.vy = -this.vy;
}
// 检查下侧是否出界
if(this.y + r >= height){
this.y = height - r;
this.vy = -this.vy;
}
}
检查四个边缘是否出界,如果出界,对应的速度方向相反,实现反弹效果。
接下来是检查球和其它球之间是否碰撞,碰撞之后的速度处理,这部分比较关键。
public void checkOther(MyCircle o){
// 获取两个球的球心之间的距离
float dis = dist(this.x, this.y, o.x, o.y);
// 如果距离小于半径和即相碰了
if(dis <= r + o.r){ // 处理碰撞结果
// 计算圆心连线方向
float dirx = o.x - this.x;
float diry = o.y - this.y;
// 归一化方向
float D = sqrt(sq(dirx) + sq(diry));
dirx /= D;
diry /= D;
//小球的位置大小不变、方向和位置圆心连线方向相反
float F = sqrt(sq(this.vx) + sq(this.vy));
this.vx = - F * dirx;
this.vy = - F * diry;
F = sqrt(sq(o.vx) + sq(o.vy));
o.vx = F * dirx;
o.vy = F * diry;
}
}
2.2 CircleManager 类
class CircleManager {
int N, Rmax, Rmin;
MyCircle[] circles;
public boolean generate(int n){
float x = random(width);
float y = random(height);
float r = random(Rmin, Rmax);
if(x - r < 0 || x + r > width || y - r < 0 || y + r > height)
return false;
for(int i = 0; i < n; i++){
if(dist(x, y, circles[i].x, circles[i].y) < r + circles[i].r)
return false;
}
circles[n] = new MyCircle(x, y, r);
return true;
}
public void init(){
circles = new MyCircle[this.N];
for(int i = 0;i < N;i++){
while(!generate(i));
}
}
public CircleManager(int N, int Rmin, int Rmax){
this.N = N;
this.Rmin = Rmin;
this.Rmax = Rmax;
this.init();
}
public void update(){
for(int i = 0;i < N;i++){
circles[i].update();
}
}
public void draw(){
for(int i = 0;i < N;i++){
circles[i].draw();
}
}
public void check(){
for(int i = 0;i < N;i++){
circles[i].checkEdge();
for(int j = 0; j < i; j++){
circles[i].checkOther(circles[j]);
}
}
}
}
MyCircle 类已经实现了单个小球的各种功能,接下来需要管理所有的小球了。
随机生成小球需要保证位置不冲突、主要包含两个方面。
一是不出界,二是不能与其它球冲突
// 随机生成小球,如果冲突, 返回 false,构造出该小球,并返回true
public boolean generate(int n){
float x = random(width);
float y = random(height);
float r = random(Rmin, Rmax);
if(x - r < 0 || x + r > width || y - r < 0 || y + r > height)
return false;
for(int i = 0; i < n; i++){
if(dist(x, y, circles[i].x, circles[i].y) < r + circles[i].r)
return false;
}
circles[n] = new MyCircle(x, y, r);
return true;
}
// 依次生成每一个小球
public void init(){
circles = new MyCircle[this.N];
for(int i = 0;i < N;i++){
while(!generate(i));
}
}
void setup() {
background(255);
size(680, 480);
stroke(200);
colorMode(HSB);
manager = new CircleManager(N, Rmin, Rmax);
}
void draw() {
background(255);
manager.check();
manager.update();
manager.draw();
}