You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.3 KiB
183 lines
5.3 KiB
import createjs from "./createjs-2015.11.26.combined";
|
|
import Matter from "matter-js";
|
|
function rule(t, e) {
|
|
return !!(
|
|
[0, 1, 2, 3, 4, 5, 6].includes(t) &&
|
|
((e %= 180),
|
|
e < 0 && (e += 180),
|
|
(e >= 0 && e <= 65) || (e >= 115 && e <= 180))
|
|
);
|
|
}
|
|
function segmentsIntr(t, e, i, r) {
|
|
var n = (t.x - i.x) * (e.y - i.y) - (t.y - i.y) * (e.x - i.x),
|
|
s = (t.x - r.x) * (e.y - r.y) - (t.y - r.y) * (e.x - r.x);
|
|
if (n * s >= 0) return !1;
|
|
var a = (i.x - t.x) * (r.y - t.y) - (i.y - t.y) * (r.x - t.x),
|
|
o = a + n - s;
|
|
return !(a * o >= 0);
|
|
}
|
|
function stopUnusual(t, e, i, r) {
|
|
var n = 1e-4;
|
|
return Math.abs(t) <= n && Math.abs(e) <= n;
|
|
}
|
|
export default class Ring {
|
|
constructor(x, y, r, id, waterful) {
|
|
this.active = true;
|
|
this.color = id.replace("ring_", "");
|
|
this.r = r;
|
|
const sprite = new createjs.SpriteSheet({
|
|
images: [waterful._queue.getResult(id)],
|
|
frames: { width: 62, height: 62 },
|
|
animations: {
|
|
normal: {
|
|
frames: [
|
|
0,
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9,
|
|
10,
|
|
11,
|
|
10,
|
|
9,
|
|
8,
|
|
7,
|
|
6,
|
|
5,
|
|
4,
|
|
3,
|
|
2,
|
|
1,
|
|
0,
|
|
],
|
|
speed: 0.3,
|
|
},
|
|
prepare: {
|
|
frames: [0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0],
|
|
speed: 0.1,
|
|
},
|
|
},
|
|
});
|
|
this.texture = new createjs.Sprite(sprite, "normal");
|
|
const bounds = this.texture.getBounds();
|
|
this.texture.regX = bounds.width / 2;
|
|
this.texture.regY = bounds.height / 2;
|
|
this.texture.stop();
|
|
this.texture.x = x;
|
|
this.texture.y = y;
|
|
this.texture.scaleX = (r * 2) / bounds.width;
|
|
this.texture.scaleY = (r * 2) / bounds.height;
|
|
this.texture.on("animationend", function (e) {
|
|
var target = e.currentTarget;
|
|
target.y < 528
|
|
? e.target.gotoAndPlay("prepare")
|
|
: e.target.gotoAndPlay("normal");
|
|
});
|
|
this.body = Matter.Bodies.circle(this.texture.x, this.texture.y, r, {
|
|
frictionAir: 0.02,
|
|
restitution: 0.15,
|
|
});
|
|
}
|
|
update(waterful) {
|
|
const { texture, body, r } = this;
|
|
const { x, y, rotation } = texture;
|
|
const { position, angle, velocity } = body;
|
|
const innerRadius = texture.scaleX * 16;
|
|
const startPoint = {
|
|
x: x - innerRadius * Math.cos(rotation * (Math.PI / 180)),
|
|
y: y - innerRadius * Math.sin(rotation * (Math.PI / 180)),
|
|
};
|
|
const endPoint = {
|
|
x: x + innerRadius * Math.cos(-rotation * (Math.PI / 180)),
|
|
y: y + innerRadius * Math.sin(rotation * (Math.PI / 180)),
|
|
};
|
|
const m = { x: 616, y: 264 };
|
|
const n = { x: 616, y: 700 };
|
|
const u = { x: 1196, y: 264 };
|
|
const v = { x: 1196, y: 700 };
|
|
if (
|
|
segmentsIntr(startPoint, endPoint, m, n) &&
|
|
this.afterCollision(waterful, "left")
|
|
)
|
|
return;
|
|
if (
|
|
segmentsIntr(startPoint, endPoint, u, v) &&
|
|
this.afterCollision(waterful, "right")
|
|
)
|
|
return;
|
|
const x1 = Math.round(x);
|
|
const x2 = Math.round(position.x);
|
|
const y1 = Math.round(y);
|
|
const y2 = Math.round(position.y);
|
|
if (x1 !== x2 || y1 !== y2) {
|
|
texture.paused && texture.play();
|
|
texture.rotation = (180 * angle) / Math.PI;
|
|
} else {
|
|
!texture.paused && texture.stop();
|
|
}
|
|
if (stopUnusual(velocity.x, velocity.y, x1, y1)) {
|
|
var factor = 1;
|
|
if (x1 < 206 || (x1 > 400 && x1 < 455)) {
|
|
factor = -1;
|
|
}
|
|
Matter.Body.applyForce(
|
|
body,
|
|
{ x: position.x, y: position.y },
|
|
{ x: 0.05 * factor, y: 0 }
|
|
);
|
|
}
|
|
texture.x = body.position.x;
|
|
texture.y = body.position.y;
|
|
}
|
|
afterCollision(waterful, dir) {
|
|
const { texture } = this;
|
|
const { currentFrame, rotation } = texture;
|
|
const followRule = rule(currentFrame, rotation);
|
|
if (
|
|
!followRule ||
|
|
waterful._score[dir].length > 8 ||
|
|
this.body.velocity.y <= 0
|
|
)
|
|
return false;
|
|
const scores = waterful._score[dir].length;
|
|
createjs.Tween.get(this.texture)
|
|
.to({ y: 666 - 30 * scores }, (666 - 30 * scores) / 0.21)
|
|
.call(function () {
|
|
waterful._staticRings.push(this);
|
|
});
|
|
Matter.World.remove(waterful._engine.world, this.body);
|
|
this.body = null;
|
|
this.active = false;
|
|
this.update = () => {
|
|
const { texture } = this;
|
|
const { currentFrame } = texture;
|
|
var t = this.texture,
|
|
e = t.currentFrame;
|
|
if (0 === currentFrame) texture.gotoAndStop(0);
|
|
else {
|
|
if (!this.frameCounter) this.frameCounter = 5;
|
|
texture.gotoAndStop(--texture.currentFrame);
|
|
this.frameCounter--;
|
|
if (texture.x < 582) ++texture.x;
|
|
if (texture.x > 660 && texture.x < 660 + 80) --texture.x;
|
|
if (texture.x > 1242) --texture.x;
|
|
if (texture.x > 1162 && texture.x < 1206) ++texture.x;
|
|
}
|
|
|
|
let angle = Math.round(texture.rotation) % 180;
|
|
angle < 0 && (angle += 180);
|
|
angle > 0 && angle <= 90
|
|
? (texture.rotation = angle - 1)
|
|
: angle > 90 && angle < 180
|
|
? (texture.rotation = angle + 1)
|
|
: 0 === currentFrame && (this.update = function () {});
|
|
};
|
|
waterful.score(dir, this.color);
|
|
return true;
|
|
}
|
|
}
|
|
|