今回は自機の当たり判定を作ります。
正直、敵の当たり判定とほぼ同じですが、今のままのコードでは不都合な部分があるので、大分書き換えます。
sprite.js
class Mine {
constructor(x, y, gridSize) {
this.x = x;
this.y = y;
this.w = gridSize;
this.h = gridSize;
this.isAlive = true;
}
show() {
fill(255, 0, 0);
rect(this.x, this.y, this.w, this.h);
}
move(xdir, ydir) {
this.x += xdir;
this.y += ydir;
}
}
自機のクラスを作りました。
これで初期化や表示、少し違いますが、動く動作をここで設定します。
sketch.js
let player; //今回書き加えたところです
// プレイヤーの座標
let gridSize = 40;
let bullets = [];
let enemy_bullets = [];
let enemies = [];
let rows = 5;
let cols = 10;
let enemyWidth = 40;
let enemyHeight = 20;
let spacing = 10;
let enemySpeed = 0.5;
let direction = 1;
let score = 0;
function setup() {
createCanvas(800, 400);
// Mineクラスのインスタンスを1回だけ生成
player = new Mine(width / 2, height - 40, gridSize);//今回書き加えたところです
player.isAlive = true;//今回書き加えたところです
// 敵を初期化
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
let x = col * (enemyWidth + spacing) + 50;
let y = row * (enemyHeight + spacing) + 50;
enemies.push(new Enemy(x, y, enemyWidth, enemyHeight, enemySpeed));
}
}
}
function draw() {
background(220);
let shouldReverse = false;
// 弾の表示と移動
for (let i = bullets.length - 1; i >= 0; i--) {
bullets[i].display();
bullets[i].move();
if (!bullets[i].isVisible) {
bullets.splice(i, 1);
}
}
// 敵の弾の表示と移動
for (let i = enemy_bullets.length - 1; i >= 0; i--) {
enemy_bullets[i].display();
enemy_bullets[i].move();
if (!enemy_bullets[i].isVisible) {
enemy_bullets.splice(i, 1);
}
}
// プレイヤーキャラクターを描画
if (player.isAlive) {//今回書き加えたところです
player.show();
}
//今回書き加えたところです
for (let j = enemy_bullets.length - 1; j >= 0; j--) {
if (hitTest(enemy_bullets[j], player)) {
console.log('Player hit by enemy bullet');
// 当たったら両方とも削除
enemy_bullets.splice(j, 1);
player.isAlive = false;
break; // 敵が消えたのでループから抜ける
}
}
// 敵の表示と移動
for (let i = enemies.length - 1; i >= 0; i--) {
enemies[i].show();
enemies[i].move(direction);
enemies[i].tryShoot();
if (enemies[i].x > width - enemies[i].w || enemies[i].x < 0) {
shouldReverse = true;
}
// 弾と敵の当たり判定
for (let j = bullets.length - 1; j >= 0; j--) {
if (hitTest(bullets[j], enemies[i])) {
bullets.splice(j, 1);
enemies.splice(i, 1);
score += 10;
break;
}
}
}
if (shouldReverse) {
direction *= -1;
for (let i = 0; i < enemies.length; i++) {
enemies[i].shiftDown();
}
}
// スコア表示
fill(0);
textSize(24);
text("Score: " + score, 10, 30);
}
// 弾と敵の当たり判定
function hitTest(bullet, enemy) {
return (
bullet.x > enemy.x &&
bullet.x < enemy.x + enemy.w &&
bullet.y > enemy.y &&
bullet.y < enemy.y + enemy.h
);
}
//今回書き加えたところです
// キーボードイベントを処理する関数
function keyPressed() {
switch (keyCode) {
case LEFT_ARROW:
player.move(-gridSize, 0); // 左に移動
break;
case RIGHT_ARROW:
player.move(gridSize, 0); // 右に移動
break;
case UP_ARROW:
player.move(0, -gridSize); // 上に移動
break;
case DOWN_ARROW:
player.move(0, gridSize); // 下に移動
break;
}
if (key == ' ') {
let bullet = new Bullet(player.x + 20, player.y);
bullets.push(bullet);
}
}
hitTestを流用しています。
keyPressedが大分書き換えられて戸惑うと思いますが、クラスで管理するため、書き換えることになりました。
表示はtrue,falseを変数に入れて管理して表示非表示します。
コメント