diff --git a/html/css/dino.css b/html/css/dino.css
new file mode 100644
index 0000000..bd90cdc
--- /dev/null
+++ b/html/css/dino.css
@@ -0,0 +1,42 @@
+body {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ background-color: #f7f7f7;
+ font-family: Arial, sans-serif;
+}
+
+.game-container {
+ position: relative;
+}
+
+#gameCanvas {
+ border: 2px solid #535353;
+ background-color: #fff;
+ display: block;
+}
+
+#score {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ font-size: 20px;
+ font-weight: bold;
+ color: #535353;
+}
+
+#gameOver {
+ position: absolute;
+ width: 100%;
+ text-align: center;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 24px;
+ font-weight: bold;
+ color: #535353;
+ display: none;
+}
diff --git a/html/dino.html b/html/dino.html
new file mode 100644
index 0000000..cb5f81f
--- /dev/null
+++ b/html/dino.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Dino Game
+
+
+
+
+
+
Score: 0
+
+ Game Over! Press Space to Restart
+
+
+
+
+
diff --git a/html/index.html b/html/index.html
index 6cc4b66..a07f23f 100644
--- a/html/index.html
+++ b/html/index.html
@@ -19,7 +19,7 @@
gap: 1rem;
"
>
-
+ Dino
diff --git a/html/js/dino.js b/html/js/dino.js
new file mode 100644
index 0000000..fba1829
--- /dev/null
+++ b/html/js/dino.js
@@ -0,0 +1,246 @@
+const canvas = document.getElementById("gameCanvas");
+const ctx = canvas.getContext("2d");
+const scoreElement = document.getElementById("score");
+const gameOverElement = document.getElementById("gameOver");
+
+let score = 0;
+let gameSpeed = 3;
+let isGameOver = false;
+let frameCount = 0;
+let nextObstacleFrame = 10;
+
+const dino = {
+ x: 50,
+ y: 150,
+ width: 40,
+ height: 50,
+ dy: 0,
+ gravity: 0.3,
+ jumpPower: -8,
+ isJumping: false,
+ isDucking: false,
+
+ draw() {
+ ctx.fillStyle = "#8aacdf";
+ ctx.fillRect(this.x, this.y, this.width, this.height);
+ },
+
+ update() {
+ if (this.isDucking) {
+ this.y = 170;
+ this.height = 30;
+ } else {
+ this.height = 50;
+ }
+
+ if (this.isJumping) {
+ this.dy += this.gravity;
+ this.y += this.dy;
+
+ if (this.y >= 150) {
+ this.y = 150;
+ this.isJumping = false;
+ this.dy = 0;
+ }
+ }
+ },
+
+ duck() {
+ if (!this.isJumping && !isGameOver) {
+ this.isDucking = true;
+ } else if (this.isJumping && !isGameOver) {
+ this.dy += this.gravity * 10;
+ this.y += this.dy;
+ }
+ },
+
+ jump() {
+ if (!this.isJumping && !isGameOver) {
+ this.isJumping = true;
+ this.dy = this.jumpPower;
+ }
+ },
+};
+
+const obstacles = [];
+
+class Obstacle {
+ constructor() {
+ this.x = canvas.width;
+ const type = Math.random();
+ if (type < 0.5) {
+ this.width = 20;
+ this.height = 40;
+ this.y = 160;
+ } else if (type < 0.8) {
+ this.width = 20;
+ this.height = 25;
+ this.y = 175;
+ } else {
+ this.width = 40;
+ this.height = 32;
+ this.y = 168;
+ }
+ }
+
+ draw() {
+ ctx.fillStyle = "#40a02b";
+ ctx.fillRect(this.x, this.y, this.width, this.height);
+ }
+
+ update() {
+ this.x -= gameSpeed;
+ }
+}
+
+class BirdObstacle {
+ constructor() {
+ this.x = canvas.width;
+ this.width = 30;
+ this.height = 20;
+ const heightType = Math.floor(Math.random() * 3);
+ if (heightType === 0) {
+ this.y = 170;
+ } else if (heightType === 1) {
+ this.y = 150;
+ } else {
+ this.y = 130;
+ }
+ }
+
+ draw() {
+ ctx.fillStyle = "#dd7878";
+ ctx.fillRect(this.x, this.y, this.width, this.height);
+ }
+
+ update() {
+ this.x -= gameSpeed;
+ }
+}
+
+function checkCollision(dino, obstacle) {
+ return (
+ dino.x < obstacle.x + obstacle.width &&
+ dino.x + dino.width > obstacle.x &&
+ dino.y < obstacle.y + obstacle.height &&
+ dino.y + dino.height > obstacle.y
+ );
+}
+
+function spawnObstacle() {
+ if (frameCount >= nextObstacleFrame) {
+ const type = Math.random();
+ if (type < 0.9) {
+ obstacles.push(new Obstacle());
+ } else {
+ obstacles.push(new BirdObstacle());
+ }
+
+ const baseMin = 80;
+ const baseMax = 140;
+
+ const speedFactor = 3 / gameSpeed;
+
+ const minInterval = Math.floor(baseMin * speedFactor);
+ const maxInterval = Math.floor(baseMax * speedFactor);
+ nextObstacleFrame =
+ frameCount +
+ Math.floor(Math.random() * (maxInterval - minInterval) + minInterval);
+ }
+}
+
+function updateScore() {
+ if (!isGameOver) {
+ score++;
+ scoreElement.textContent = `Score: ${Math.floor(score / 10)}`;
+
+ // Increase difficulty
+ if (score % 500 === 0) {
+ gameSpeed += 0.5;
+ }
+ }
+}
+
+function gameLoop() {
+ if (isGameOver) return;
+
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ ctx.strokeStyle = "#535353";
+ ctx.beginPath();
+ ctx.moveTo(0, 200);
+ ctx.lineTo(canvas.width, 200);
+ ctx.stroke();
+
+ dino.update();
+ dino.draw();
+
+ spawnObstacle();
+
+ for (let i = obstacles.length - 1; i >= 0; i--) {
+ obstacles[i].update();
+ obstacles[i].draw();
+
+ if (checkCollision(dino, obstacles[i])) {
+ isGameOver = true;
+ gameOverElement.style.display = "block";
+ }
+
+ if (obstacles[i].x + obstacles[i].width < 0) {
+ obstacles.splice(i, 1);
+ }
+ }
+
+ updateScore();
+ frameCount++;
+
+ requestAnimationFrame(gameLoop);
+}
+
+function resetGame() {
+ score = 0;
+ gameSpeed = 3;
+ isGameOver = false;
+ frameCount = 0;
+ obstacles.length = 0;
+ dino.y = 150;
+ dino.dy = 0;
+ dino.isJumping = false;
+ gameOverElement.style.display = "none";
+ nextObstacleFrame = 10;
+ gameLoop();
+}
+
+document.addEventListener("keydown", (e) => {
+ e.preventDefault();
+ switch (e.code) {
+ case "ArrowUp":
+ case "Space": {
+ if (isGameOver) {
+ resetGame();
+ } else {
+ dino.jump();
+ }
+ break;
+ }
+ case "ArrowDown": {
+ dino.duck();
+ break;
+ }
+ default:
+ }
+});
+
+document.addEventListener("keyup", (e) => {
+ switch (e.code) {
+ case "ArrowDown": {
+ e.preventDefault();
+ dino.isDucking = false;
+ if (!dino.isJumping) {
+ dino.y = 150;
+ }
+ }
+ }
+});
+
+gameLoop();
diff --git a/html/js/script.js b/html/js/script.js
index 1834c7a..46ab4bb 100644
--- a/html/js/script.js
+++ b/html/js/script.js
@@ -1,4 +1,6 @@
-const projects = {};
+const projects = {
+ dino: "dino.html",
+};
const openProject = (project) => {
if (Object.keys(projects).includes(project)) {