const DEFAULT_FRAMERATE = 60;
danmaku = new Danmaku("danmaku.json");
createCanvas(windowWidth, windowHeight);
BG_COLOR = color(70, 80, 90);
let areaX, areaY, areaScale;
windowWidth / windowHeight >
((danmaku.width * 1.1) / danmaku.height) * 1.05
areaY = windowHeight * 0.025;
areaScale = (windowHeight * 0.95) / danmaku.height;
areaX = (windowWidth - danmaku.width * areaScale) / 2;
areaX = windowWidth * 0.05;
areaScale = (windowWidth * 0.9) / danmaku.width;
areaY = (windowHeight - danmaku.height * areaScale) / 2;
if (startMs == -1) startMs = nowMs;
danmaku.draw(areaX, areaY, areaScale, nowMs - startMs);
rect(0, 0, windowWidth, areaY);
rect(0, 0, areaX, windowHeight);
areaY + danmaku.height * areaScale,
windowHeight - (areaY + danmaku.height * areaScale)
areaX + danmaku.width * areaScale,
windowWidth - (areaX + danmaku.width * areaScale),
if (danmaku.countActiveBullets() == 0) {
this.jsonData = loadJSON(jsonPath, () => this.load(this.jsonData));
if (!("width" in jsonData && "height" in jsonData)) return false;
this.width = jsonData["width"];
this.height = jsonData["height"];
this.bullets = jsonData.bullets.map((bullet) => {
return { bullet: new Bullet(bullet), active: true };
this.bullets.forEach((ele) => (ele.active = true));
rect(x, y, this.width * scale, this.height * scale);
this.bullets.forEach((element) => {
if (!element.active) return;
if (ms < element.bullet.startTime) return;
let pos = element.bullet.update(ms);
if (!this.isInside(pos)) {
fill(element.bullet.color);
translate(x + pos.x * scale, y + pos.y * scale);
rotate(element.bullet.rad - Math.PI / 2);
element.bullet.width * scale,
element.bullet.height * scale
return this.bullets.reduce((acc, ele) => {
if (ele.active) return acc + 1;
this.width + 100 < pos.x ||
this.height + 100 < pos.y
this.pos = new Position(0, 0);
let initX = "initX" in data ? data["initX"] : 0;
let initY = "initY" in data ? data["initY"] : 0;
this.initPos = new Position(initX, initY);
this.rad = "rad" in data ? data["rad"] : 0;
this.speed = "speed" in data ? data["speed"] : 0;
this.startMs = "startMs" in data ? data["startMs"] : 0;
this.color = "color" in data ? color(data["color"]) : color("#c8c8c8");
this.width = "width" in data ? data["width"] : 4;
this.height = "height" in data ? data["height"] : 4;
if (ms < this.startMs) return null;
this.initPos.x + Math.cos(this.rad) * this.speed * (ms - this.startMs);
this.initPos.y + Math.sin(this.rad) * this.speed * (ms - this.startMs);