Pacman Stick
by DriftHawk95275 lines6.2 KB
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pacman Stick</title>
<style>
*{box-sizing:border-box}
body{
margin:0;background:#080d24;color:white;
font-family:Arial,sans-serif;
display:flex;flex-direction:column;
align-items:center;gap:12px;padding:15px;
}
.arena{
background:radial-gradient(circle,#18265b,#080d24);
border:2px solid #6575ff;border-radius:18px;
padding:9px;width:100%;max-width:400px;
}
canvas{width:100%;height:auto;display:block;border-radius:12px}
.stick{
width:142px;height:142px;border-radius:50%;
background:radial-gradient(circle,#293b77,#101936);
border:3px solid #738cff;
box-shadow:inset 0 0 20px #0009,0 0 20px #536dff66;
position:relative;touch-action:none;
}
.knob{
position:absolute;width:58px;height:58px;
border-radius:50%;left:39px;top:39px;
background:radial-gradient(circle at 35% 30%,#c9d6ff,#526cff 65%,#2635a0);
border:2px solid #dbe2ff;
box-shadow:0 4px 12px #0009;
}
button{
background:#5747d9;color:white;border:0;
padding:12px 25px;border-radius:12px;
font-size:17px;font-weight:bold;
}
</style>
</head>
<body>
<h2>🎮 Pacman Stick</h2>
<div class="arena">
<div style="display:flex;justify-content:space-between;margin-bottom:10px">
<span>⭐ امتیاز: <b id="sc">0</b></span>
<span>❤️ جان: <b id="lv">3</b></span>
</div>
<canvas id="game" width="360" height="420"></canvas>
<div id="status" style="text-align:center;font-size:13px;margin-top:10px">
برای شروع، شروع بازی را بزن
</div>
</div>
<button id="go">▶ شروع بازی</button>
<div>جویاستیک لمسی</div>
<div class="stick" id="stick">
<div class="knob" id="knob"></div>
</div>
<div style="font-size:12px">دایره وسط را بگیر و در جهت دلخواه بکش</div>
<script>
const c=document.getElementById('game');
const ctx=c.getContext('2d');
const stick=document.getElementById('stick');
const knob=document.getElementById('knob');
const cell=30;
const map=[
"############",
"#..........#",
"#.##.##.##.#",
"#..........#",
"#.##.#.##..#",
"#....#.....#",
"###.###.##.#",
"#..........#",
"#.##.##.##.#",
"#..........#",
"#.##.##.##.#",
"#..........#",
"#..........#",
"############"
];
let walls=new Set(),dots=[];
let px=1,py=1,dx=0,dy=0;
let score=0,lives=3,ghosts=[];
let active=false,frame=0,timer=null,power=0;
function reset(){
walls.clear();dots=[];
map.forEach((s,y)=>[...s].forEach((v,x)=>{
if(v==='#')walls.add(x+','+y);
else dots.push({x,y});
}));
px=1;py=1;dx=dy=0;
score=0;lives=3;power=0;
ghosts=[
{x:10,y:1,col:'#ff4d83'},
{x:10,y:12,col:'#54eaff'},
{x:6,y:7,col:'#d86bff'}
];
update();draw();
}
function wall(x,y){return walls.has(x+','+y)}
function update(){
document.getElementById('sc').textContent=score;
document.getElementById('lv').textContent=lives;
}
function draw(){
ctx.fillStyle='#080e27';
ctx.fillRect(0,0,360,420);
walls.forEach(k=>{
let [x,y]=k.split(',').map(Number);
ctx.fillStyle='#172c70';
ctx.fillRect(x*30+2,y*30+2,26,26);
ctx.strokeStyle='#526fff';
ctx.strokeRect(x*30+3,y*30+3,24,24);
});
ctx.fillStyle='#fff2a3';
dots.forEach(d=>{
ctx.beginPath();
ctx.arc(d.x*30+15,d.y*30+15,3,0,7);
ctx.fill();
});
ctx.fillStyle='#ffe65b';
ctx.beginPath();
ctx.arc(165,225,7+Math.sin(frame/3)*2,0,7);
ctx.fill();
ctx.fillStyle='#ffe23e';
ctx.beginPath();
let a=Math.atan2(dy,dx);
let m=.25+Math.abs(Math.sin(frame/2))*.3;
ctx.moveTo(px*30+15,py*30+15);
ctx.arc(px*30+15,py*30+15,12,a+m,a+Math.PI*2-m);
ctx.fill();
ghosts.forEach(g=>{
ctx.fillStyle=power?'#448cff':g.col;
ctx.beginPath();
ctx.arc(g.x*30+15,g.y*30+15,11,Math.PI,0);
ctx.lineTo(g.x*30+26,g.y*30+27);
ctx.lineTo(g.x*30+4,g.y*30+27);
ctx.fill();
ctx.fillStyle='white';
ctx.beginPath();
ctx.arc(g.x*30+11,g.y*30+13,3,0,7);
ctx.arc(g.x*30+19,g.y*30+13,3,0,7);
ctx.fill();
});
}
function move(){
if(!active)return;
frame++;
if(Math.abs(dx)+Math.abs(dy)>.2){
let nx=px+(Math.abs(dx)>Math.abs(dy)?Math.sign(dx):0);
let ny=py+(Math.abs(dy)>=Math.abs(dx)?Math.sign(dy):0);
if(!wall(nx,ny)){px=nx;py=ny}
}
let i=dots.findIndex(d=>d.x===px&&d.y===py);
if(i>=0){dots.splice(i,1);score+=10;update()}
if(px===5&&py===7){power=25;score+=50;update()}
if(frame%2===0){
ghosts.forEach(g=>{
let opts=[[1,0],[-1,0],[0,1],[0,-1]]
.filter(v=>!wall(g.x+v[0],g.y+v[1]));
if(opts.length){
opts.sort((a,b)=>
Math.abs(g.x+a[0]-px)+Math.abs(g.y+a[1]-py)-
(Math.abs(g.x+b[0]-px)+Math.abs(g.y+b[1]-py))
);
let v=Math.random()<.7?opts[0]:
opts[Math.floor(Math.random()*opts.length)];
g.x+=v[0];g.y+=v[1];
}
});
}
if(power>0)power--;
if(ghosts.some(g=>g.x===px&&g.y===py)){
if(power>0){
ghosts.forEach(g=>{g.x=10;g.y=1});
score+=100;update();
}else{
lives--;update();
if(lives<=0){
active=false;
document.getElementById('status').textContent=
'بازی تمام شد! دوباره شروع کن.';
}else{
px=1;py=1;dx=dy=0;
document.getElementById('status').textContent=
'یک جان از دست دادی!';
}
}
}
if(!dots.length){
active=false;
document.getElementById('status').textContent=
'برنده شدی! آفرین! 🎉';
}
draw();
}
function start(){
reset();
active=true;
document.getElementById('status').textContent=
'جویاستیک را بکش و حرکت کن!';
if(timer)clearInterval(timer);
timer=setInterval(move,220);
}
document.getElementById('go').addEventListener('click',start);
let held=false;
function position(e){
let b=stick.getBoundingClientRect();
let cx=b.left+b.width/2;
let cy=b.top+b.height/2;
let x=e.clientX-cx,y=e.clientY-cy;
let lim=43,len=Math.hypot(x,y);
if(len>lim){x=x/len*lim;y=y/len*lim}
knob.style.transform=`translate(${x}px,${y}px)`;
dx=x/43;dy=y/43;
}
function release(){
held=false;
knob.style.transform='translate(0,0)';
dx=dy=0;
}
stick.addEventListener('pointerdown',e=>{
held=true;
stick.setPointerCapture(e.pointerId);
position(e);
});
stick.addEventListener('pointermove',e=>{
if(held)position(e);
});
stick.addEventListener('pointerup',release);
stick.addEventListener('pointercancel',release);
reset();
</script>
</body>
</html>
Game Source: Pacman Stick
Creator: DriftHawk95
Libraries: none
Complexity: complex (275 lines, 6.2 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: pacman-stick-drifthawk95" to link back to the original. Then publish at arcadelab.ai/publish.