let gameState = 'start'; // 'start', 'playing', 'gameover'
for (let i = 0; i < 80; i++) {
if (gameState === 'start') {
} else if (gameState === 'playing') {
} else if (gameState === 'gameover') {
fill(255, 255, 255, 180);
ellipse(s.x, s.y, s.size);
function drawTitleScreen() {
textAlign(CENTER, CENTER);
text('炫酷射击游戏', width/2, height/2 - 100);
text('玩法说明:', width/2, height/2 - 30);
text('1. 鼠标左右移动飞船', width/2, height/2);
text('2. 鼠标点击或空格发射子弹', width/2, height/2 + 30);
text('3. 击中敌人得分,漏掉敌人扣血', width/2, height/2 + 60);
text('4. 血量为0游戏结束', width/2, height/2 + 90);
text('点击鼠标或按空格开始', width/2, height/2 + 160);
for (let b of bullets) b.update();
for (let b of bullets) b.show();
bullets = bullets.filter(b => !b.offscreen && !b.hit);
for (let e of enemies) e.update();
for (let e of enemies) e.show();
enemies = enemies.filter(e => !e.offscreen && !e.hit);
for (let p of particles) p.update();
for (let p of particles) p.show();
particles = particles.filter(p => !p.finished());
if (!e.hit && !b.hit && dist(b.x, b.y, e.x, e.y) < e.size/2 + b.size/2) {
for (let i = 0; i < 25; i++) {
particles.push(new Particle(e.x, e.y, e.col));
if (!e.hit && e.y > height - 50) {
for (let i = 0; i < 15; i++) {
particles.push(new Particle(e.x, height-50, color(255,0,0)));
if (enemySpawnTimer <= 0) {
enemies.push(new Enemy());
enemySpawnTimer = int(random(25, 50));
text('分数: ' + score, 20, 20);
text('血量: ' + health, 20, 50);
function drawGameOver() {
textAlign(CENTER, CENTER);
text('游戏结束', width/2, height/2 - 60);
text('你的分数: ' + score, width/2, height/2);
text('点击鼠标或按空格重新开始', width/2, height/2 + 80);
function mousePressed() {
if (gameState === 'start' || gameState === 'gameover') {
} else if (gameState === 'playing') {
if (gameState === 'start' || gameState === 'gameover') {
if (key === ' ' || key === 'Spacebar') restartGame();
} else if (gameState === 'playing') {
if (key === ' ' || key === 'Spacebar') player.shoot();
this.x = constrain(mouseX, this.size/2, width-this.size/2);
if (this.cooldown > 0) this.cooldown--;
translate(this.x, this.y);
ellipse(0, 0, this.size, this.size/2);
fill(255, 255, 255, 200);
ellipse(0, 0, this.size*0.5, this.size*0.18);
if (this.cooldown <= 0) {
bullets.push(new Bullet(this.x, this.y - this.size/2));
if (this.y < -this.size) this.offscreen = true;
ellipse(this.x, this.y, this.size, this.size*1.5);
fill(255, 255, 255, 120);
ellipse(this.x, this.y, this.size*0.4, this.size*0.8);
this.size = random(32, 48);
this.x = random(this.size/2, width-this.size/2);
this.speed = random(2, 4) + score/20;
this.col = color(random(120,255), random(60,180), random(60,255));
if (this.y > height + this.size) this.offscreen = true;
translate(this.x, this.y);
ellipse(0, 0, this.size, this.size);
ellipse(0, 0, this.size*0.5, this.size*0.5);
fill(red(this.col), green(this.col), blue(this.col), this.alpha);
ellipse(this.x, this.y, 8, 8);