在这里先说一下,本篇里做的两张动态图形,分别用了processing和p5.js,两者之前差异不大,所以明白了一种之后另一种也就比较好掌握了,但是p5.js相对来说可能更为简单一点。
图片的主要构成就是长方形,但是如果把每个长方形都做出来,工作量就实在是太大了,所以就先计算图形四周主要顶点的坐标,然后用直线来进行图片的分割,至于说带有颜色的部分,就直接运用长方形的的函数来进行添加就好了。
相关代码如下:(这里用的processing)
void setup() {
size(640, 640);
}
void draw(){
strokeWeight(5);
fill(255);
rect(10,20,620,580);
fill(255);
rect(30,20,20,580);
rect(590,20,20,580);
drawline();
colorrect();
activerect();
smallrect();
}
void drawline(){//画直线分割界面
stroke(0);
line(10,20,630,20);
line(10,40,630,40);
line(10,580,630,580);
line(10,600,630,600);
line(50,280,630,280);
line(50,310,630,310);
line(50,340,210,340);
line(210,20,210,600);
line(230,20,230,600);
line(420,20,420,600);
line(360,20,360,600);
line(420,480,590,480);
line(10,20,10,600);
line(630,20,630,600);
}
void colorrect(){//添加带颜色的长方形到指定位置
fill(255,0,0);
rect(210,20,20,20);
rect(50,40,160,240);
rect(230,580,130,20);
rect(360,580,60,20);
rect(610,40,20,20);
rect(10,230,20,210);
fill(0,0,255);
rect(10,580,20,20);
rect(420,20,170,20);
fill(255,255,0);
rect(360,20,60,20);
rect(360,40,60,260);
rect(360,280,60,30);
rect(210,580,20,20);
rect(610,480,20,100);
rect(420,480,170,100);
}
对于图中几个运动的长方形,观察其运动规律,可发现三者在y轴上均符合正弦变化,中间的小长方形可以看做在x轴上做正弦变化,并且其在y轴上的运动也是和两侧的运动长方形处于相对静止的关系,所以代码如下:
void activerect(){
float m=millis()/200;
fill(0,0,255);
rect(30,260+220*sin(m),20,100);
rect(590,260+220*sin(m),20,100);
}
void smallrect(){
float t=millis()/200;
float x=310+270*sin(t),y=260+220*sin(t);
fill(0);
rect(x,y,20,20);
}
(请忽略图中鼠标的存在!!!录屏的时候没有注意到!!!抱歉!!!)
原版的动态图实现了一种“打方块”游戏的感觉,而我写的则是使用代码强行感觉像是在碰撞,所以关于拓展我便想实现小方块之间碰撞的问题。
关于碰撞的问题就涉及到一个物理模型的问题,即碰撞之后小方块角度的变化和运动方向的变化,主要函数就是 SmallRect函数(这里我是做了一些参考,原本写出来的碰撞效果很不自然):
colide中,对两个方块之间的距离和边长50做比较,如果距离小于边长就代表发生了碰撞,然后求出加速度,对两方块速度进行改变。
函数move中,就是在物体发生碰撞之后改变物体的速度方向,
函数display则是调用画矩形的函数。
主要函数参考: https://blog.csdn.net/qq_40346122/article/details/83832420
所以根据案例的方法,我做了些碰撞的参考然后做了一些修改,使其满足我需要的碰撞规律,整体代码如下:(这里用的p5.js)
var numRects = 20;
var gravity = 0.03;
var friction = -0.9;
var smallrect=[];
function setup() {
createCanvas(630, 600);
strokeWeight(5);
for(var i=0;i<numRects;i++){
smallrect[i]=new SmallRect(
random(width),
random(height),
random(50),
i,
smallrect
);
}
}
function draw(){
colorrect();
drawline();
activerect();
fill(0);
smallrect.forEach(rect=>{
rect.collide();
rect.move();
rect.display();
})
}
function drawline(){
stroke(0);
line(10,20,630,20);
line(10,40,630,40);
line(10,580,630,580);
line(10,600,630,600);
line(50,280,630,280);
line(50,310,630,310);
line(50,340,210,340);
line(210,20,210,600);
line(230,20,230,600);
line(420,20,420,600);
line(360,20,360,600);
line(420,480,590,480);
line(10,20,10,600);
line(630,20,630,600);
}
function colorrect(){
fill(255);
rect(10,20,620,580);
fill(255);
rect(30,20,20,580);
rect(590,20,20,580);
fill(255,0,0);
rect(210,20,20,20);
rect(50,40,160,240);
rect(230,580,130,20);
rect(360,580,60,20);
rect(610,40,20,20);
rect(10,230,20,210);
fill(0,0,255);
rect(10,580,20,20);
rect(420,20,170,20);
fill(255,255,0);
rect(360,20,60,20);
rect(360,40,60,260);
rect(360,280,60,30);
rect(210,580,20,20);
rect(610,480,20,100);
rect(420,480,170,100);
}
function activerect(){
var m=millis()/150;
fill(0,0,255);
rect(30,260+220*sin(m),20,100);
rect(590,260+220*sin(m),20,100);
}
function SmallRect(x,y,dis,id,other){
this.x = x;
this.y = y;
var vx = 0;
var vy = 0;
this.long = dis;
this.id = id;
this.others =other;
this.collide=function(){
for (var i = this.id + 1; i < numRects; i++) {
// console.log(others[i]);
var dx = this.others[i].x - this.x;
var dy = this.others[i].y - this.y;
var distance = sqrt(dx * dx + dy * dy);
if (distance <50) {
var angle = atan2(dy, dx);
var targetX = this.x + cos(angle) *50;
var targetY = this.y + sin(angle) *50;
var ax = (targetX - this.others[i].x) *0.05;
var ay = (targetY - this.others[i].y) * 0.05;
vx -= ax;
vy -= ay;
this.others[i].vx += ax;
this.others[i].vy += ay;
}
}
};
this.move = function() {
vy += gravity;
this.x += vx;
this.y += vy;
if (this.x + this.long/ 2 > width) {
this.x = width - this.long/ 2;
vx *= friction;
} else if (this.x - this.long/ 2 < 0) {
this.x = this.long/ 2;
vx *= friction;
}
if (this.y + this.long/ 2 > height) {
this.y = height - this.long/ 2;
vy *= friction;
} else if (this.y - this.long/ 2 < 0) {
this.y = this.long/ 2;
vy *= friction;
}
};
this.display = function() {
rect(this.x, this.y, 50,50);
};
}