diff --git a/README.md b/README.md index d820c13..796a179 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ class Game { } checkCollision() { - for (let obstacle of this.entityList.list) { + for (let obstacle of this.entityManager.list) { const marioRect = this.mario.element.getBoundingClientRect(); const obstacleRect = obstacle.element.getBoundingClientRect(); diff --git a/src/entity.js b/src/entity.js index dd75771..34b6ef9 100644 --- a/src/entity.js +++ b/src/entity.js @@ -86,6 +86,7 @@ class Entity { speed; point = 0; frameId = null; + touched = false; constructor({ bottom, speed, type, point = 0, className = 'obstacle' }) { this.type = type; @@ -110,6 +111,10 @@ class Entity { return parseInt(this.element.style.right, 10); // parseInt('10.5px') => 10 } + hide(entity) { + entity.element.style.visibility = 'hidden'; // 리플로우 방지를 위해 visibility 사용 + } + animate() { this.element.classList.add('spin'); } diff --git a/src/game.js b/src/game.js index 51d6bc1..28770ea 100644 --- a/src/game.js +++ b/src/game.js @@ -21,7 +21,7 @@ class Game { score; mario; background; - entityList; + entityManager; eventHandler; constructor({ @@ -31,7 +31,7 @@ class Game { this.audio = new AudioManager(); this.score = new Score(); this.background = new Background({ speed }); - this.entityList = new EntityManager({ speed, bottom }); + this.entityManager = new EntityManager({ speed, bottom }); this.mario = new Mario({ bottom, audio: this.audio }); this.eventHandler = new EventHandler(this); @@ -58,7 +58,7 @@ class Game { } reset() { - this.entityList.reset(); + this.entityManager.reset(); this.background.reset(); this.score.reset(); } @@ -74,7 +74,7 @@ class Game { this.isPlaying = true; this.mario.run(); - this.entityList.moveAll(); + this.entityManager.moveAll(); this.background.move(); this.eventHandler.setupEventListeners(); this.checkCollision(); @@ -86,7 +86,7 @@ class Game { this.isPlaying = false; this.mario.stop(); - this.entityList.stopAll(); + this.entityManager.stopAll(); this.background.stop(); this.eventHandler.removeEventListeners(); cancelAnimationFrame(this.collisionFrameId); @@ -108,10 +108,10 @@ class Game { const entityType = EntityManager.ENTITY_TYPES[idx]; if (entityType === 'both') { - this.entityList.add('coin', true); - this.entityList.add('obstacle'); + this.entityManager.add('coin', true); + this.entityManager.add('obstacle'); } else { - this.entityList.add(entityType); + this.entityManager.add(entityType); } if (this.isPlaying) this.scheduleAddEntity(); @@ -119,18 +119,24 @@ class Game { } checkCollision() { - for (let entity of this.entityList.list) { + for (let entity of this.entityManager.list) { const marioRect = this.mario.element.getBoundingClientRect(); const entityRect = entity.element.getBoundingClientRect(); - if (this.isColliding(marioRect, entityRect)) { - if (entity.type === 'obstacle') { - this.toggleButtonActive(true); - return this.failed(); - } else if (entity.type === 'coin') { - this.audio.playEffect('coin'); - this.score.add(entity.point); - this.entityList.remove(entity); + if (!entity.touched && this.isColliding(marioRect, entityRect)) { + switch (entity.type) { + case 'obstacle': { + this.toggleButtonActive(true); + this.failed(); + break; + } + case 'coin': { + this.audio.playEffect('coin'); + this.score.add(entity.point); + entity.touched = true; + entity.hide(entity); + break; + } } } }