我正在努力实现我的“元球”(或blob?)更有机的感觉。当它撞到墙壁时,我希望它更加“松散”,并且还能找到更好的移动方式。关于如何改进它的任何想法/建议?
例如:
我的实验基于paper.js
这是我现在的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script type="text/javascript" src="http://paperjs.org/assets/js/paper.js"></script>
<script type="text/paperscript" canvas="canvas">
function Ball(p, v) {
this.point = p;
this.vector = v;
this.maxVec = 15;
this.points = 8;
this.boundOffset = [];
this.boundOffsetBuff = [];
this.sidePoints = [];
this.hitPoint = null;
this.path = new Path({
fillColor: {
hue: Math.random() * 360,
saturation: 1,
brightness: 1
},
blendMode: 'lighter'
});
this.path.selected = true;
this.path.closed = true;
this.maxRadius = 8;
var center = 150;
for (var i = 0; i < this.points; i++) {
var delta = new Point({
length: (this.maxRadius * 0.5) + (Math.random() * this.maxRadius * 0.5),
angle: (360 / this.points) * i
});
this.path.add(center + delta);
this.boundOffset.push(this.maxRadius);
this.boundOffsetBuff.push(this.maxRadius);
this.sidePoints.push(delta);
}
this.path.smooth();
}
Ball.prototype = {
iterate: function() {
if (this.vector.length > this.maxVec)
this.vector.length = this.maxVec;
this.point += this.vector;
this.updateShape();
},
updateShape: function() {
var segments = this.path.segments;
for (var i = 0; i < this.points; i ++){
segments[i].point = this.getSidePoint(i);
}
for (var i = 0; i < this.points; i ++) {
var nextPointIndex = (i + 1) % this.points;
var prevPointIndex = (i > 0) ? i - 1 : this.points - 1;
var offset = this.boundOffset[i];
offset += (this.maxRadius - offset) / 15;
offset += ((this.boundOffset[nextPointIndex] + this.boundOffset[prevPointIndex]) / 2 - offset) / 15;
this.boundOffsetBuff[i] = this.boundOffset[i] = offset;
}
this.path.smooth();
},
generateRandomNumber : function(min, max) {
return Math.random() * (max - min) + min;
},
reactToBounds : function(){
var bounds = {
xMin: 0,
xMax: 300,
yMin: 0,
yMax: 150
}
for (var i = 0; i < this.points; i ++) {
var sidePoint = this.getSidePoint(i);
var pre = sidePoint + this.vector;
if(pre.x <= bounds.xMin){
this.hitPoint = new Point(bounds.xMin, sidePoint.y);
this.vector.x *= -this.generateRandomNumber(.9, 1);
break;
}
if(pre.x >= bounds.xMax){
this.hitPoint = new Point(bounds.xMax, sidePoint.y);
this.vector.x *= -this.generateRandomNumber(.9, 1);
break;
}
if(pre.y <= bounds.yMin){
this.hitPoint = new Point(sidePoint.x, bounds.yMin);
this.vector.y *= -this.generateRandomNumber(.9, 1);
break;
}
if(pre.y >= bounds.yMax){
this.hitPoint = new Point(sidePoint.x, bounds.yMax);
this.vector.y *= -this.generateRandomNumber(.9, 1);
break;
}
}
this.calcBounds();
this.updateBounds();
},
getBoundOffsetWall : function(){
var diff = this.point - this.hitPoint;
var angle = (diff.angle + 180) % 360;
return this.boundOffset[Math.floor(angle / 360 * this.boundOffset.length)];
},
calcBounds: function() {
for (var i = 0; i < this.points; i ++) {
var tp = this.getSidePoint(i);
var bLen = this.getBoundOffsetWall();
var td = tp.getDistance(this.hitPoint);
if (td < bLen) {
this.boundOffsetBuff[i] -= (bLen - td) / 15;
}
}
},
getSidePoint: function(index) {
return this.point + this.sidePoints[index] * this.boundOffset[index];
},
updateBounds: function() {
for (var i = 0; i < this.points; i ++)
this.boundOffset[i] = this.boundOffsetBuff[i];
}
};
var balls = [];
var numBalls = 1;
for (var i = 0; i < numBalls; i++) {
var position = new Point(150, 75);
var vector = new Point({
angle: 180 * Math.random(),
length: .5
});
balls.push(new Ball(position, vector));
}
function onFrame() {
for (var i = 0; i < balls.length; i++) {
var b = balls[i];
b.reactToBounds();
b.iterate();
}
}
</script>
</head>
<body>
<canvas id="canvas" resize hidpi="off" style="background:black"></canvas>
</body>
</html>
由于