bug fix in secret game

This commit is contained in:
Hesabix 2025-03-27 23:10:24 +00:00
parent 3b36749b43
commit 76189ba1d7

View file

@ -10,7 +10,8 @@
<strong>کنترلها:</strong> H برای پرش (حداکثر ۳ بار) | D برای حالت قهرمان ({{ superModeCount }} باقیمانده) <strong>کنترلها:</strong> H برای پرش (حداکثر ۳ بار) | D برای حالت قهرمان ({{ superModeCount }} باقیمانده)
</div> </div>
<div class="mt-2"> <div class="mt-2">
<strong>امتیاز:</strong> {{ Math.floor(score) }} <strong>امتیاز کنونی:</strong> {{ Math.floor(score) }} |
<strong>بهترین رکورد:</strong> {{ bestScore }}
</div> </div>
<div class="mt-2 text-caption"> <div class="mt-2 text-caption">
هلو در حسابداری نمادی از انحصارگری نرمافزارهای حسابداری است که باید شکستش داد! هلو در حسابداری نمادی از انحصارگری نرمافزارهای حسابداری است که باید شکستش داد!
@ -25,14 +26,14 @@
</v-card> </v-card>
</v-dialog> </v-dialog>
</div> </div>
</template> </template>
<script> <script>
import dinoImage from '@/assets/dino.png' import dinoImage from '@/assets/dino.png';
import peachImage from '@/assets/peach.png' import peachImage from '@/assets/peach.png';
import heroImage from '@/assets/hero.png' import heroImage from '@/assets/hero.png';
export default { export default {
name: 'SecretDialog', name: 'SecretDialog',
data() { data() {
return { return {
@ -54,6 +55,7 @@
}, },
obstacles: [], obstacles: [],
score: 0, score: 0,
bestScore: 0, // بهترین امتیاز
gameRunning: false, gameRunning: false,
animationFrameId: null, animationFrameId: null,
dinoImg: null, dinoImg: null,
@ -67,227 +69,239 @@
lastObstacleTime: 0, lastObstacleTime: 0,
canvasWidth: 0, canvasWidth: 0,
canvasHeight: 0 canvasHeight: 0
} };
}, },
computed: { computed: {
dialogWidth() { dialogWidth() {
return window.innerWidth > 600 ? '600px' : '90%' return window.innerWidth > 600 ? '600px' : '90%';
} }
}, },
mounted() { mounted() {
window.addEventListener('keydown', this.handleKeyDown) window.addEventListener('keydown', this.handleKeyDown);
window.addEventListener('keyup', this.handleKeyUp) window.addEventListener('keyup', this.handleKeyUp);
window.addEventListener('resize', this.handleResize) window.addEventListener('resize', this.handleResize);
this.loadImages() this.loadImages();
// بارگذاری بهترین امتیاز از localStorage
this.bestScore = parseInt(localStorage.getItem('bestScore') || '0', 10);
}, },
watch: { watch: {
showDialog(newVal) { showDialog(newVal) {
if (newVal) { if (newVal) {
this.$nextTick(() => { this.$nextTick(() => {
this.updateCanvasSize() this.updateCanvasSize();
}) });
} }
} }
}, },
beforeUnmount() { beforeUnmount() {
window.removeEventListener('keydown', this.handleKeyDown) window.removeEventListener('keydown', this.handleKeyDown);
window.removeEventListener('keyup', this.handleKeyUp) window.removeEventListener('keyup', this.handleKeyUp);
window.removeEventListener('resize', this.handleResize) window.removeEventListener('resize', this.handleResize);
if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId) if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);
if (this.superModeTimeout) clearTimeout(this.superModeTimeout) if (this.superModeTimeout) clearTimeout(this.superModeTimeout);
}, },
methods: { methods: {
loadImages() { loadImages() {
this.dinoImg = new Image() this.dinoImg = new Image();
this.dinoImg.src = dinoImage this.dinoImg.src = dinoImage;
this.dinoImg.onerror = () => console.error('Failed to load dino image:', dinoImage) this.dinoImg.onerror = () => console.error('Failed to load dino image:', dinoImage);
this.peachImg = new Image() this.peachImg = new Image();
this.peachImg.src = peachImage this.peachImg.src = peachImage;
this.peachImg.onerror = () => console.error('Failed to load peach image:', peachImage) this.peachImg.onerror = () => console.error('Failed to load peach image:', peachImage);
this.heroImg = new Image() this.heroImg = new Image();
this.heroImg.src = heroImage this.heroImg.src = heroImage;
this.heroImg.onerror = () => console.error('Failed to load hero image:', heroImage) this.heroImg.onerror = () => console.error('Failed to load hero image:', heroImage);
this.heroImg.onload = () => console.log('Hero image loaded successfully') this.heroImg.onload = () => console.log('Hero image loaded successfully');
}, },
updateCanvasSize() { updateCanvasSize() {
if (!this.$refs.gameCanvas) return if (!this.$refs.gameCanvas) return;
this.canvas = this.$refs.gameCanvas this.canvas = this.$refs.gameCanvas;
this.ctx = this.canvas.getContext('2d') this.ctx = this.canvas.getContext('2d');
this.canvasWidth = this.canvas.parentElement.clientWidth this.canvasWidth = this.canvas.parentElement.clientWidth;
this.canvasHeight = this.canvasWidth * 0.333 // نسبت 3:1 this.canvasHeight = this.canvasWidth * 0.333; // نسبت 3:1
this.canvas.width = this.canvasWidth this.canvas.width = this.canvasWidth;
this.canvas.height = this.canvasHeight this.canvas.height = this.canvasHeight;
}, },
handleResize() { handleResize() {
if (this.showDialog) { if (this.showDialog) {
this.updateCanvasSize() this.updateCanvasSize();
} }
}, },
handleKeyDown(event) { handleKeyDown(event) {
const gameKeys = [72, 68, 81] // H, D, Q const gameKeys = [72, 68, 81]; // H, D, Q
if (gameKeys.includes(event.keyCode)) { if (gameKeys.includes(event.keyCode)) {
event.preventDefault() event.preventDefault();
} }
if (event.keyCode === 81) { if (event.keyCode === 81) {
this.isQPressed = true this.isQPressed = true;
} }
if (this.showDialog && event.keyCode === 72 && this.dino.jumpCount < this.dino.maxJumps) { if (this.showDialog && event.keyCode === 72 && this.dino.jumpCount < this.dino.maxJumps) {
this.dino.dy = this.dino.jump - (this.dino.jumpCount * 0.015) // پرشهای بعدی قویتر this.dino.dy = this.dino.jump - (this.dino.jumpCount * 0.015); // پرشهای بعدی قویتر
this.dino.jumpCount++ this.dino.jumpCount++;
} }
if (this.showDialog && event.keyCode === 68 && this.superModeCount > 0 && !this.superMode) { if (this.showDialog && event.keyCode === 68 && this.superModeCount > 0 && !this.superMode) {
this.activateSuperMode() this.activateSuperMode();
} }
if (this.isQPressed) { if (this.isQPressed) {
this.checkSequence(event) this.checkSequence(event);
} }
}, },
handleKeyUp(event) { handleKeyUp(event) {
if (event.keyCode === 81) { if (event.keyCode === 81) {
this.isQPressed = false this.isQPressed = false;
this.keySequence = [] this.keySequence = [];
if (this.timeoutId) clearTimeout(this.timeoutId) if (this.timeoutId) clearTimeout(this.timeoutId);
} }
}, },
checkSequence(event) { checkSequence(event) {
const targetKeyCodes = [72, 69, 83, 65, 66, 73, 88] // H E S A B I X const targetKeyCodes = [72, 69, 83, 65, 66, 73, 88]; // H E S A B I X
const currentKeyCode = event.keyCode const currentKeyCode = event.keyCode;
if (this.timeoutId) clearTimeout(this.timeoutId) if (this.timeoutId) clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => { this.timeoutId = setTimeout(() => {
this.keySequence = [] this.keySequence = [];
}, 2000) }, 2000);
if (targetKeyCodes.includes(currentKeyCode)) { if (targetKeyCodes.includes(currentKeyCode)) {
this.keySequence.push(currentKeyCode) this.keySequence.push(currentKeyCode);
} }
if (this.keySequence.length >= targetKeyCodes.length) { if (this.keySequence.length >= targetKeyCodes.length) {
const sequenceMatch = targetKeyCodes.every( const sequenceMatch = targetKeyCodes.every(
(code, index) => this.keySequence[index] === code (code, index) => this.keySequence[index] === code
) );
if (sequenceMatch) { if (sequenceMatch) {
this.showDialog = true this.showDialog = true;
this.keySequence = [] this.keySequence = [];
} else { } else {
this.keySequence = [] this.keySequence = [];
} }
} }
}, },
startGame() { startGame() {
if (!this.gameRunning) { if (!this.gameRunning) {
this.updateCanvasSize() this.updateCanvasSize();
this.gameRunning = true this.gameRunning = true;
this.score = 0 this.score = 0;
this.obstacles = [] this.obstacles = [];
this.lastObstacleTime = Date.now() this.lastObstacleTime = Date.now();
this.gameLoop() this.gameLoop();
} }
}, },
gameLoop() { gameLoop() {
try { try {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.drawBackground() this.drawBackground();
this.ctx.fillStyle = '#d3d3d3' this.ctx.fillStyle = '#d3d3d3';
this.ctx.fillRect(0, this.canvas.height * 0.95, this.canvas.width, this.canvas.height * 0.05) this.ctx.fillRect(0, this.canvas.height * 0.95, this.canvas.width, this.canvas.height * 0.05);
// اعمال جاذبه و حرکت عمودی دایناسور // اعمال جاذبه و حرکت عمودی دایناسور
this.dino.dy += this.dino.gravity this.dino.dy += this.dino.gravity;
this.dino.y += this.dino.dy this.dino.y += this.dino.dy;
if (this.dino.y >= 0.75) { if (this.dino.y >= 0.75) {
this.dino.y = 0.75 this.dino.y = 0.75;
this.dino.dy = 0 this.dino.dy = 0;
this.dino.jumpCount = 0 this.dino.jumpCount = 0;
} }
if (this.dino.y < 0) this.dino.y = 0 // جلوگیری از خروج از بالا if (this.dino.y < 0) this.dino.y = 0;
const dinoX = this.dino.x * this.canvasWidth const dinoX = this.dino.x * this.canvasWidth;
const dinoY = this.dino.y * this.canvasHeight const dinoY = this.dino.y * this.canvasHeight;
const dinoWidth = this.dino.width * this.canvasWidth const dinoWidth = this.dino.width * this.canvasWidth;
const dinoHeight = this.dino.height * this.canvasHeight const dinoHeight = this.dino.height * this.canvasHeight;
if (this.dinoImg && this.dinoImg.complete) { if (this.dinoImg && this.dinoImg.complete) {
this.ctx.drawImage(this.dinoImg, dinoX, dinoY, dinoWidth, dinoHeight) this.ctx.drawImage(this.dinoImg, dinoX, dinoY, dinoWidth, dinoHeight);
} else { } else {
this.ctx.fillStyle = 'green' this.ctx.fillStyle = 'green';
this.ctx.fillRect(dinoX, dinoY, dinoWidth, dinoHeight) this.ctx.fillRect(dinoX, dinoY, dinoWidth, dinoHeight);
console.warn('Dino image not loaded, using fallback') console.warn('Dino image not loaded, using fallback');
} }
const heroX = this.hero.x * this.canvasWidth const heroX = this.hero.x * this.canvasWidth;
const heroY = this.hero.y * this.canvasHeight const heroY = this.hero.y * this.canvasHeight;
const heroWidth = this.hero.width * this.canvasWidth const heroWidth = this.hero.width * this.canvasWidth;
const heroHeight = this.hero.height * this.canvasHeight const heroHeight = this.hero.height * this.canvasHeight;
if (this.hero.visible) { if (this.hero.visible) {
if (this.heroImg && this.heroImg.complete) { if (this.heroImg && this.heroImg.complete) {
this.ctx.drawImage(this.heroImg, heroX, heroY, heroWidth, heroHeight) this.ctx.drawImage(this.heroImg, heroX, heroY, heroWidth, heroHeight);
} else { } else {
this.ctx.fillStyle = 'blue' this.ctx.fillStyle = 'blue';
this.ctx.fillRect(heroX, heroY, heroWidth, heroHeight) this.ctx.fillRect(heroX, heroY, heroWidth, heroHeight);
console.warn('Hero image not loaded, using fallback') console.warn('Hero image not loaded, using fallback');
} }
} }
const now = Date.now() const now = Date.now();
if (!this.superMode && now - this.lastObstacleTime > 2000 && Math.random() < 0.02) { // تنظیم فاصله و سرعت هلوها برای قابلکنترل بودن
const baseInterval = 2500; // فاصله اولیه بیشتر برای پرش راحتتر
const minInterval = 1000; // حداقل فاصله برای جلوگیری از شلوغی
const obstacleInterval = Math.max(minInterval, baseInterval - Math.floor(this.score / 10) * 50); // کاهش ملایمتر فاصله
const obstacleProbability = Math.min(0.05, 0.01 + this.score * 0.0002); // افزایش کندتر احتمال
if (!this.superMode && now - this.lastObstacleTime > obstacleInterval && Math.random() < obstacleProbability) {
const baseSpeed = 0.004; // سرعت اولیه کمتر
const speedIncrease = Math.floor(this.score / 100) * 0.0005; // افزایش سرعت ملایمتر
const obstacleSpeed = Math.min(baseSpeed + speedIncrease, 0.01); // حداکثر سرعت محدود
this.obstacles.push({ this.obstacles.push({
x: 1, x: 1,
y: 0.75, y: 0.75, // ارتفاع ثابت روی زمین
width: 0.05, width: 0.05,
height: 0.1, height: 0.1,
speed: 0.005, speed: obstacleSpeed,
dx: 0, dx: 0,
dy: 0 dy: 0
}) });
this.lastObstacleTime = now this.lastObstacleTime = now;
} }
this.obstacles = this.obstacles.filter(obs => obs.x > -obs.width && obs.x < 1 + obs.width && obs.y > -obs.height) this.obstacles = this.obstacles.filter(obs => obs.x > -obs.width && obs.x < 1 + obs.width && obs.y > -obs.height);
this.obstacles.forEach(obs => { this.obstacles.forEach(obs => {
if (this.superMode) { if (this.superMode) {
obs.x += obs.dx obs.x += obs.dx;
obs.y += obs.dy obs.y += obs.dy;
obs.dy += 0.001 obs.dy += 0.001;
if (obs.y < 0) obs.y = 0 // جلوگیری از خروج از بالا if (obs.y < 0) obs.y = 0;
} else { } else {
obs.x -= obs.speed obs.x -= obs.speed;
} }
const obsX = obs.x * this.canvasWidth const obsX = obs.x * this.canvasWidth;
const obsY = obs.y * this.canvasHeight const obsY = obs.y * this.canvasHeight;
const obsWidth = obs.width * this.canvasWidth const obsWidth = obs.width * this.canvasWidth;
const obsHeight = obs.height * this.canvasHeight const obsHeight = obs.height * this.canvasHeight;
if (this.peachImg && this.peachImg.complete) { if (this.peachImg && this.peachImg.complete) {
this.ctx.drawImage(this.peachImg, obsX, obsY, obsWidth, obsHeight) this.ctx.drawImage(this.peachImg, obsX, obsY, obsWidth, obsHeight);
} else { } else {
this.ctx.fillStyle = '#ff9999' this.ctx.fillStyle = '#ff9999';
this.ctx.beginPath() this.ctx.beginPath();
this.ctx.arc(obsX + obsWidth / 2, obsY + obsHeight / 2, obsWidth / 2, 0, Math.PI * 2) this.ctx.arc(obsX + obsWidth / 2, obsY + obsHeight / 2, obsWidth / 2, 0, Math.PI * 2);
this.ctx.fill() this.ctx.fill();
console.warn('Peach image not loaded, using fallback') console.warn('Peach image not loaded, using fallback');
} }
if (!this.superMode && this.checkCollision(obs)) { if (!this.superMode && this.checkCollision(obs)) {
this.gameOver() this.gameOver();
return return;
} }
}) });
this.score += 0.05 this.score += 0.05;
if (this.gameRunning) { if (this.gameRunning) {
this.animationFrameId = requestAnimationFrame(this.gameLoop) this.animationFrameId = requestAnimationFrame(this.gameLoop);
} }
} catch (error) { } catch (error) {
console.error('Error in game loop:', error) console.error('Error in game loop:', error);
this.gameOver() this.gameOver();
} }
}, },
checkCollision(obs) { checkCollision(obs) {
@ -296,64 +310,69 @@
this.dino.x + this.dino.width > obs.x && this.dino.x + this.dino.width > obs.x &&
this.dino.y < obs.y + obs.height && this.dino.y < obs.y + obs.height &&
this.dino.y + this.dino.height > obs.y this.dino.y + this.dino.height > obs.y
) );
}, },
gameOver() { gameOver() {
this.gameRunning = false this.gameRunning = false;
this.hero.visible = false this.hero.visible = false;
cancelAnimationFrame(this.animationFrameId) cancelAnimationFrame(this.animationFrameId);
// بهروزرسانی بهترین امتیاز
if (Math.floor(this.score) > this.bestScore) {
this.bestScore = Math.floor(this.score);
localStorage.setItem('bestScore', this.bestScore);
}
}, },
resetGame() { resetGame() {
this.gameOver() this.gameOver();
this.score = 0 this.score = 0; // ریست امتیاز کنونی
this.obstacles = [] this.obstacles = [];
this.dino.y = 0.75 this.dino.y = 0.75;
this.dino.dy = 0 this.dino.dy = 0;
this.dino.jumpCount = 0 this.dino.jumpCount = 0;
this.superMode = false this.superMode = false;
this.hero.visible = false this.hero.visible = false;
this.startGame() this.startGame();
}, },
closeDialog() { closeDialog() {
this.showDialog = false this.showDialog = false;
this.gameOver() this.gameOver();
}, },
activateSuperMode() { activateSuperMode() {
if (this.superModeCount <= 0) return if (this.superModeCount <= 0) return;
this.superMode = true this.superMode = true;
this.superModeCount -= 1 this.superModeCount -= 1;
this.hero.visible = true this.hero.visible = true;
this.obstacles.forEach(obs => { this.obstacles.forEach(obs => {
const direction = obs.x < this.hero.x ? -1 : 1 const direction = obs.x < this.hero.x ? -1 : 1;
obs.dx = direction * (Math.random() * 0.01 + 0.005) obs.dx = direction * (Math.random() * 0.01 + 0.005);
obs.dy = -(Math.random() * 0.01 + 0.005) obs.dy = -(Math.random() * 0.01 + 0.005);
}) });
this.superModeTimeout = setTimeout(() => { this.superModeTimeout = setTimeout(() => {
this.superMode = false this.superMode = false;
this.hero.visible = false this.hero.visible = false;
this.obstacles = [] this.obstacles = [];
}, 15000) }, 15000);
}, },
drawBackground() { drawBackground() {
this.ctx.fillStyle = '#e0e0e0' this.ctx.fillStyle = '#e0e0e0';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height) this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.font = `${this.canvasWidth * 0.06}px Arial` this.ctx.font = `${this.canvasWidth * 0.06}px Arial`;
this.ctx.fillStyle = 'rgba(0, 0, 0, 0.2)' this.ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
this.ctx.textAlign = 'center' this.ctx.textAlign = 'center';
this.ctx.fillText('Hesabix', this.canvas.width / 2, this.canvas.height * 0.2) this.ctx.fillText('Hesabix', this.canvas.width / 2, this.canvas.height * 0.2);
} }
} }
} };
</script> </script>
<style scoped> <style scoped>
canvas { canvas {
border: 1px solid #ccc; border: 1px solid #ccc;
display: block; display: block;
width: 100%; width: 100%;
} }
</style> </style>