diff --git a/docs/public/assets/background/menu_start.png b/docs/public/assets/background/menu_start.png
new file mode 100644
index 0000000..ad1d003
Binary files /dev/null and b/docs/public/assets/background/menu_start.png differ
diff --git a/docs/public/assets/background/room_tutorial.png b/docs/public/assets/background/room_tutorial.png
new file mode 100644
index 0000000..6790d41
Binary files /dev/null and b/docs/public/assets/background/room_tutorial.png differ
diff --git a/docs/public/assets/door/door_close.jpg b/docs/public/assets/door/door_close.jpg
deleted file mode 100644
index f4e0325..0000000
Binary files a/docs/public/assets/door/door_close.jpg and /dev/null differ
diff --git a/docs/public/assets/door/door_close.png b/docs/public/assets/door/door_close.png
new file mode 100644
index 0000000..60f0a02
Binary files /dev/null and b/docs/public/assets/door/door_close.png differ
diff --git a/docs/public/assets/door/door_open.jpg b/docs/public/assets/door/door_open.jpg
deleted file mode 100644
index ae747cb..0000000
Binary files a/docs/public/assets/door/door_open.jpg and /dev/null differ
diff --git a/docs/public/assets/door/door_open.png b/docs/public/assets/door/door_open.png
new file mode 100644
index 0000000..a315469
Binary files /dev/null and b/docs/public/assets/door/door_open.png differ
diff --git a/docs/public/assets/fonts/PressStart2P.ttf b/docs/public/assets/fonts/PressStart2P.ttf
new file mode 100644
index 0000000..2442aff
Binary files /dev/null and b/docs/public/assets/fonts/PressStart2P.ttf differ
diff --git a/docs/public/index.html b/docs/public/index.html
index 74613f6..6ae27a0 100644
--- a/docs/public/index.html
+++ b/docs/public/index.html
@@ -21,6 +21,8 @@
+
+
diff --git a/docs/src/controllers/CollisionDetector.js b/docs/src/controllers/CollisionDetector.js
index 47d6fbb..64fcae1 100644
--- a/docs/src/controllers/CollisionDetector.js
+++ b/docs/src/controllers/CollisionDetector.js
@@ -1,28 +1,26 @@
class CollisionDetector {
- detectPlayerCollision(playerObj, objArray) {
+ detectPlayerCollision(playerObj, objArr) {
// Check the collision between the player and other objects. If there is a collision,
// the player bounces back.
- return objArray.some(obj => this.detectCollision(playerObj, obj));
+ return objArr.some(obj => this.detectCollision(playerObj, obj));
}
- detectBulletEnemyCollision(bulletArray, enemyArray) {
+ detectBulletEnemyCollision(bulletArr, enemyArr) {
// Check the collision between bullets and enemies. If there is a collision,
// the bullet vanishes and causes damage to the enemy.
- enemyArray.forEach((enemyObj, enemyIndex) => {
- bulletArray.forEach((bulletObj, bulletIndex) => {
+ enemyArr.forEach((enemyObj, enemyIndex) => {
+ bulletArr.forEach((bulletObj, bulletIndex) => {
if (this.detectCollision(bulletObj, enemyObj)) {
- enemyArray[enemyIndex].hp = max(0, enemyObj.hp - bulletObj.damage);
+ enemyArr[enemyIndex].hp = max(0, enemyObj.hp - bulletObj.damage);
hitSound.currentTime=0; //music 让音效从头播放
hitSound.play();
- if(enemyArray[enemyIndex].hp === 0){
+ if(enemyArr[enemyIndex].hp === 0){
deathSound.currentTime = 0;
deathSound.play();
}
-
-
- bulletArray.splice(bulletIndex, 1);
+ bulletArr.splice(bulletIndex, 1);
}
});
});
@@ -40,7 +38,7 @@ class CollisionDetector {
hitBoundary(obj) {
let x = obj.position.x + obj.velocity.x;
let y = obj.position.y + obj.velocity.y;
- return x < 0 || x > widthInPixel - obj.size.x || y < 0 || y > heightInPixel - obj.size.y;
+ return x < leftBoundary || x > rightBoundary - obj.size.x || y < topBoundary || y > bottomBoundary - obj.size.y;
}
}
diff --git a/docs/src/controllers/InputHandler.js b/docs/src/controllers/InputHandler.js
index 1a41e59..e6d4f3e 100644
--- a/docs/src/controllers/InputHandler.js
+++ b/docs/src/controllers/InputHandler.js
@@ -1,16 +1,17 @@
class InputHandler {
- constructor(cooldownTime = 2000, bulletDmg = 50) {
+ constructor(roomObj, cooldownTime = 2000) {
+ this.currentRoom = roomObj;
this.collisionDetector = new CollisionDetector();
this.collisionCoolDownTime = cooldownTime;
- this.bulletDamage = bulletDmg;
this.lastCollisionTime = millis();
}
update() {
+ this.currentRoom.update();
player.updateVelocity();
player.updatePosition();
- const collideWithEnemies = this.collisionDetector.detectPlayerCollision(player, enemies);
- const collideWithObstacles = this.collisionDetector.detectPlayerCollision(player, obstacles);
+ const collideWithEnemies = this.collisionDetector.detectPlayerCollision(player, this.currentRoom.enemies);
+ const collideWithObstacles = this.collisionDetector.detectPlayerCollision(player, this.currentRoom.obstacles);
const playerHitBoundary = this.collisionDetector.hitBoundary(player);
if (collideWithEnemies || collideWithObstacles || playerHitBoundary) {
player.revertPosition();
@@ -26,8 +27,9 @@ class InputHandler {
// player.shoot(direction);
// }
this.updateBullets();
- this.collisionDetector.detectBulletEnemyCollision(player.bullets, enemies);
- this.removeEnemies(enemies);
+ this.collisionDetector.detectBulletEnemyCollision(player.bullets, this.currentRoom.enemies);
+ this.removeEnemies(this.currentRoom.enemies);
+ this.moveToNextRoom();
}
handlePlayerShooting() {
@@ -53,7 +55,6 @@ class InputHandler {
});
}
-
decreasePlayerHp() {
// The player will not receive any damage in the future 2 seconds.
if (millis() - this.lastCollisionTime < this.collisionCoolDownTime) {
@@ -65,4 +66,18 @@ class InputHandler {
hurtSound.currentTime = 0;
hurtSound.play();
}
+
+ moveToNextRoom(tolerance=player.size.x) {
+ if (!this.currentRoom.checkClearCondition()) return;
+
+ const playerMidX = player.position.x + player.size.x / 2;
+ const playerMidY = player.position.y + player.size.y / 2;
+ const doorX = this.currentRoom.door.position.x;
+ const doorY = this.currentRoom.door.position.y + this.currentRoom.door.size.y / 2;
+
+ if (dist(playerMidX, playerMidY, doorX, doorY) < tolerance) {
+ console.log("Move to the next room!");
+ loadRoom();
+ }
+ }
}
\ No newline at end of file
diff --git a/docs/src/core/controller.js b/docs/src/core/controller.js
index 2629ff5..311ad4a 100644
--- a/docs/src/core/controller.js
+++ b/docs/src/core/controller.js
@@ -1,7 +1,7 @@
function checkSavePoint() {
// Save when player crosses the target position
- const distanceX = abs(player.position.x - savePoint.position.x);
- const distanceY = abs(player.position.y - savePoint.position.y);
+ const distanceX = abs(player.position.x - room.savePoint.position.x);
+ const distanceY = abs(player.position.y - room.savePoint.position.y);
if (!nearSavedPosition && distanceX < player.size.x && distanceY < player.size.y) {
saveGameData();
nearSavedPosition = true;
@@ -17,16 +17,16 @@ function checkSavePoint() {
function saveGameData() {
if (nearSavedPosition) return;
- localStorage.setItem('lastSavePoint', JSON.stringify(savePoint));
+ localStorage.setItem('lastSavePoint', JSON.stringify(room.savePoint));
localStorage.setItem('playerHp', JSON.stringify(player.hp));
- lastSavedPosition.xPos = savePoint.position.x;
- lastSavedPosition.yPos = savePoint.position.y;
+ lastSavedPosition.xPos = room.savePoint.position.x;
+ lastSavedPosition.yPos = room.savePoint.position.y;
console.log("Game Saved!");
}
function loadGameData() {
- generateEnemies();
- generateObstacles();
+ room.generateEnemies();
+ room.generateObstacles();
let savedPosition = localStorage.getItem('lastSavePoint');
let playerHp = localStorage.getItem('playerHp');
if (!savedPosition || !playerHp) {
@@ -93,19 +93,22 @@ function exitGame() {
}
function resetGame() {
+ menuDisplayed = false;
+ isGamePaused = false;
+ gameOver = false;
+
player = new Player(playerX, playerY);
- generateObstacles();
- generateEnemies();
- console.log("Player is reset!")
- startTime = millis();
-}
-
-function checkWinCondition() {
- // 当所有敌人被消灭,且玩家位于画布上方(yPos < 10)且血量大于 0 时,认为达成胜利条件
- return (enemies.length === 0 && player.position.y < 10 && player.hp > 0)
+ room = new Room();
+ room.setup();
+ inputHandler = new InputHandler(room);
+ console.log("Game is reset!")
}
function isGameOver() {
return player.hp <= 0;
}
+function loadRoom() {
+
+}
+
diff --git a/docs/src/core/main.js b/docs/src/core/main.js
index 76f680b..c2ae9a1 100644
--- a/docs/src/core/main.js
+++ b/docs/src/core/main.js
@@ -1,64 +1,35 @@
let pauseSound = new Audio("assets/music/Pause.mp3");
let hitSound = new Audio("assets/music/Enemy_Hurt.mp3");
-let deathSound = new Audio("assets/music.Enemy_Death.mp3");
+let deathSound = new Audio("assets/music/Enemy_Death.mp3");
let shootSound = new Audio("assets/music/Player_Shoot.mp3");
let hurtSound = new Audio("assets/music/Player_Hurt.mp3");
let deathSound2 = new Audio("assets/music/Player_Death.mp3");
let walkSound = new Audio("assets/music/Player_Walk.mp3");
walkSound.loop = true;
-function generateObstacles() {
- obstacles = [];
- for (let i = 0; i < obstacleCount; i++) {
- let x = random(hPadding, widthInPixel - hPadding);
- let y = random(vPadding, heightInPixel - vPadding);
- obstacles.push(new Obstacle(x, y));
- }
-}
-
-function generateEnemies() {
- enemies = [];
- for (let i = 0; i < enemyCount; i++) {
- let x = random(hPadding, widthInPixel - hPadding);
- let y = random(vPadding, heightInPixel - vPadding);
-
- let hp = random([smallEnemyHp, largeEnemyHp]);
- enemies.push(new Enemy(x, y, hp));
- }
-}
-
-function updateObstacles() {
- obstacles.forEach(o => o.display());
-}
-
-function updateEnemies() {
- enemies.forEach(e => {
- e.update();
- e.display();
- });
-}
-
function preload() {
+ uiFont = loadFont('assets/fonts/PressStart2P.ttf');
heart = loadImage('assets/icons/heart.svg');
damagedHeart = loadImage('assets/icons/damagedHeart.svg');
+ startMenuImg = loadImage('assets/background/menu_start.png');
+ closedDoorImg = loadImage('assets/door/door_close.png');
+ openDoorImg = loadImage('assets/door/door_open.png');
+ officeRoomImg = loadImage('assets/background/room_tutorial.png');
}
function setup() {
cnv = createCanvas(windowWidth, windowHeight);
adjustCanvasWithAspectRatio();
player = new Player(playerX, playerY);
- savePoint = new SavePoint(savePointX, savePointY);
- inputHandler = new InputHandler();
+ room = new Room();
+ room.setup();
+ inputHandler = new InputHandler(room);
setupMenu();
setupPauseMenu();
- startTime = millis();
- generateObstacles();
- generateEnemies();
}
function draw() {
- // push();
adjustCanvasWithAspectRatio();
background(220);
if (menuDisplayed) {
@@ -70,18 +41,13 @@ function draw() {
}
else {
displayTutorial();
- updateObstacles();
- updateEnemies();
-
+ // room.update();
inputHandler.update();
- savePoint.display();
player.display();
drawUiHub();
checkSavePoint();
- checkWinCondition();
}
- // pop();
}
function keyPressed() {
diff --git a/docs/src/entities/Door.js b/docs/src/entities/Door.js
new file mode 100644
index 0000000..bbcc7df
--- /dev/null
+++ b/docs/src/entities/Door.js
@@ -0,0 +1,16 @@
+class Door {
+ constructor(x = rightBoundary, y = heightInPixel / 2 - doorSize.h / 2) {
+ this.position = createVector(x, y);
+ this.size = createVector(doorSize.w, doorSize.h);
+ this.currentDoorImg = closedDoorImg;
+ }
+
+ display() {
+ image(this.currentDoorImg, this.position.x, this.position.y, this.size.x, this.size.y);
+ }
+
+ open() {
+ if (this.currentDoorImg === openDoorImg) return;
+ this.currentDoorImg = openDoorImg;
+ }
+}
diff --git a/docs/src/entities/Obstacle.js b/docs/src/entities/Obstacle.js
index a5c1f71..a22e5fc 100644
--- a/docs/src/entities/Obstacle.js
+++ b/docs/src/entities/Obstacle.js
@@ -1,11 +1,11 @@
class Obstacle {
constructor(x, y) {
this.position = createVector(x, y);
- this.size = createVector(obstacleSize.w, obstacleSize.h);
+ this.size = createVector(heightInPixel / 12, heightInPixel / 12);
}
display() {
fill(100);
rect(this.position.x, this.position.y, this.size.x, this.size.y);
}
-}
\ No newline at end of file
+}
diff --git a/docs/src/entities/Player.js b/docs/src/entities/Player.js
index e683f0a..2182791 100644
--- a/docs/src/entities/Player.js
+++ b/docs/src/entities/Player.js
@@ -7,7 +7,7 @@ class Player {
this.velocity = createVector(0, 0);
this.atk = defaultAtk;
this.maxAtk = playerMaxAtk;
- this.size = createVector(playerSize.w, playerSize.h);
+ this.size = createVector(heightInPixel / 12, heightInPixel / 12);
this.bullets = [];
}
diff --git a/docs/src/entities/Room.js b/docs/src/entities/Room.js
new file mode 100644
index 0000000..4c2640c
--- /dev/null
+++ b/docs/src/entities/Room.js
@@ -0,0 +1,66 @@
+class Room {
+ constructor() {
+ this.savePoint = null;
+ this.door = null;
+ this.enemies = [];
+ this.obstacles = [];
+ }
+
+ setup() {
+ this.savePoint = new SavePoint(savePointParam.x, savePointParam.y);
+ this.door = new Door();
+ this.generateObstacles();
+ this.generateEnemies();
+ startTime = millis();
+ }
+
+ update() {
+ image(officeRoomImg, 0, 0, widthInPixel, heightInPixel);
+ this.savePoint.display();
+ this.updateObstacles();
+ this.updateEnemies();
+ this.updateDoor();
+ this.checkClearCondition();
+ }
+
+ generateObstacles() {
+ this.obstacles = [];
+ const maxEntitySize = heightInPixel / 8;
+ for (let i = 0; i < obstacleCount; i++) {
+ let x = random(leftBoundary, rightBoundary - maxEntitySize);
+ let y = random(topBoundary, bottomBoundary - maxEntitySize);
+ this.obstacles.push(new Obstacle(x, y));
+ }
+ }
+
+ generateEnemies() {
+ this.enemies = [];
+ const maxEntitySize = heightInPixel / 8;
+ for (let i = 0; i < enemyCount; i++) {
+ let x = random(leftBoundary, rightBoundary - maxEntitySize);
+ let y = random(topBoundary, bottomBoundary - maxEntitySize);
+ let hp = random([smallEnemyHp, largeEnemyHp]);
+ this.enemies.push(new Enemy(x, y, hp));
+ }
+ }
+
+ updateObstacles() {
+ this.obstacles.forEach(o => o.display());
+ }
+
+ updateEnemies() {
+ this.enemies.forEach(e => {
+ e.update();
+ e.display();
+ });
+ }
+
+ updateDoor() {
+ if (this.checkClearCondition()) this.door.open();
+ this.door.display();
+ }
+
+ checkClearCondition() {
+ return (this.enemies.length === 0 && player.hp > 0);
+ }
+}
diff --git a/docs/src/entities/SavePoint.js b/docs/src/entities/SavePoint.js
index 1280194..1ded2ee 100644
--- a/docs/src/entities/SavePoint.js
+++ b/docs/src/entities/SavePoint.js
@@ -1,8 +1,7 @@
class SavePoint {
constructor(x, y) {
this.position = createVector(x, y);
- this.size = savePointSize;
- this.size = createVector(savePointSize.w, savePointSize.h);
+ this.size = createVector(savePointParam.w, savePointParam.h);
}
display() {
diff --git a/docs/src/entities/enemies/Enemy.js b/docs/src/entities/enemies/Enemy.js
index 1bdf08a..060f2f7 100644
--- a/docs/src/entities/enemies/Enemy.js
+++ b/docs/src/entities/enemies/Enemy.js
@@ -3,18 +3,18 @@ class Enemy {
this.hp = hp;
this.position = createVector(x, y);
this.size = createVector(
- hp === smallEnemyHp ? smallEnemySize.w : largeEnemySize.w,
- hp === smallEnemyHp ? smallEnemySize.h : largeEnemySize.h
+ hp === smallEnemyHp ? heightInPixel / 12 : largeEnemySize.w,
+ hp === smallEnemyHp ? heightInPixel / 12 : largeEnemySize.h
);
this.velocity = createVector(random([-1, 1]), random([-1, 1]));
}
update() {
this.position.add(this.velocity);
- if (this.position.x < 0 || this.position.x > widthInPixel - this.size.x) {
+ if (this.position.x < leftBoundary || this.position.x > rightBoundary - this.size.x) {
this.velocity.x *= -1;
}
- if (this.position.y < 0 || this.position.y > heightInPixel - this.size.y) {
+ if (this.position.y < topBoundary || this.position.y > bottomBoundary - this.size.y) {
this.velocity.y *= -1;
}
}
diff --git a/docs/src/ui/hud.js b/docs/src/ui/hud.js
index 0de278c..9fb8348 100644
--- a/docs/src/ui/hud.js
+++ b/docs/src/ui/hud.js
@@ -40,7 +40,9 @@ function drawHealthBar() {
function drawCurrentLevel() {
fill(255);
- textFont('Courier New', uiTextSize);
+ stroke(0);
+ strokeWeight(5);
+ textFont(uiFont, uiTextSize);
textAlign(LEFT, BOTTOM);
text(`Level:${currentLevel}-${currentStage}`, hPadding, heightInPixel - vPadding);
}
@@ -51,9 +53,7 @@ function drawBossStatus() {
let barX = (widthInPixel / 2) - (bossHpWidth / 2);
// Draw HP bar background
- fill(200);
- stroke(0);
- strokeWeight(3);
+ fill(0);
rect(barX, vPadding, bossHpWidth, bossHpHeight, bossHpCorner);
// Draw HP bar
@@ -65,9 +65,6 @@ function drawBossStatus() {
let lineX = barX + bossHpWidth * i;
line(lineX, vPadding, lineX, vPadding + bossHpHeight);
}
-
- // Back to default weight
- strokeWeight(1);
}
function adjustBossStatusColor(percentage) {
@@ -86,7 +83,9 @@ function drawTimer() {
let secs = totalSecs % 60;
fill(255);
- textFont('Courier New', uiTextSize);
+ stroke(0);
+ strokeWeight(5);
+ textFont(uiFont, uiTextSize);
textAlign(RIGHT, BOTTOM);
text(`Time Taken:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`, widthInPixel - hPadding, heightInPixel - vPadding);
}
diff --git a/docs/src/ui/menu.js b/docs/src/ui/menu.js
index 1dac26c..fb54e37 100644
--- a/docs/src/ui/menu.js
+++ b/docs/src/ui/menu.js
@@ -27,17 +27,15 @@ function setupPauseMenu() {
}
function drawMenu() {
- fill(0);
- textSize(uiTextSize);
- textAlign(CENTER, CENTER);
- text("Welcome to the Game!", widthInPixel / 2, heightInPixel / 3);
-
+ image(startMenuImg, 0, 0, widthInPixel, heightInPixel);
btnContinue.position(windowWidth / 2 - hPadding, windowHeight / 2 - vPadding);
btnNewGame.position(windowWidth / 2 - hPadding, windowHeight / 2 + vPadding);
}
function drawPauseMenu() {
- fill(0);
+ fill(255);
+ stroke(0);
+ strokeWeight(5);
textSize(uiTextSize);
textAlign(CENTER, CENTER);
text("Paused", widthInPixel / 2, heightInPixel / 3);
diff --git a/docs/src/utils.js b/docs/src/utils.js
index 404dc4f..afb035b 100644
--- a/docs/src/utils.js
+++ b/docs/src/utils.js
@@ -1,5 +1,4 @@
// TODO: Merge into classes
-let tempPlayerHp;
let lastCollisionTime = 0;
let menuDisplayed = true;
@@ -7,15 +6,20 @@ let isGamePaused = false;
let isBossStage = false;
let btnPause, btnResume, btnExit, btnContinue, btnNewGame;
let inputHandler = null;
+let room = null;
+
+let openDoorImg, closedDoorImg;
let startTime;
let timeSpent = 0;
-let savePointX = 300;
-let savePointY = 200;
let currentLevel = 1;
let currentStage = 1;
+const uiTextSize = 20;
+const hPadding = 50;
+const vPadding = 20;
+
let nearSavedPosition = false;
let lastSavedPosition = { xPos: null, yPos: null };
let minDistanceToSave = 50;
@@ -25,11 +29,10 @@ const chaserSize = 30;
const shootSize = 25;
const smallEnemyHp = 50;
const largeEnemyHp = 100;
-const smallEnemySize = { w: 40, h: 40 };
const largeEnemySize = { w: 50, h: 60 };
-let player, savePoint;
-let enemyCount = 5;
+let player;
+let enemyCount = 1;
let obstacleCount = 5;
// Add variables and functions from feature_enemies_lyz_before0225
@@ -42,7 +45,7 @@ const tutorialMessages = [
"You can start the game now!"
];
-const obstacleSize = { w: 30, h: 30 };
+const doorSize = { w: 73, h: 95 };
const defaultSpeed = 5;
const defaultHp = 3;
@@ -50,12 +53,8 @@ const defaultAtk = 50;
const playerMaxHp = 5;
const playerMaxSpeed = 15;
const playerMaxAtk = 20;
-const playerSize = { w: 20, h: 20 };
-const playerX = 50;
-const playerY = 50;
-
-const savePointSize = { w: 30, h: 30 };
+const savePointParam = { x: 300, y: 200, w: 30, h: 30 };
const iconSize = 24;
const iconPadding = 15;
@@ -66,7 +65,11 @@ const bossHpCorner = 10;
const widthInPixel = 1024;
const heightInPixel = 576;
+const boundaryInPixel = { w: 80 , h: 72 }
+const leftBoundary = boundaryInPixel.w;
+const rightBoundary = widthInPixel - boundaryInPixel.w;
+const topBoundary = boundaryInPixel.h;
+const bottomBoundary = heightInPixel - boundaryInPixel.h;
-const uiTextSize = 24;
-const hPadding = 50;
-const vPadding = 20;
+const playerX = leftBoundary;
+const playerY = heightInPixel / 2;