HTML5 Game - Pacman and ghost

Description

Pacman and ghost

Demo

ResultView the demo in separate window

<!DOCTYPE html>
<html>
<head>
    <title>Pac-Man</title>
</head>//from   www  .  j  a  va 2s  . c o  m
<body>
    <h1>Pac-Man</h1>
    <canvas id="pacman" width="300" height="300"></canvas>
    <script>
        class PacMan {
            constructor(x, y, radius, speed) {
                this.x = x;
                this.y = y;
                this.radius = radius;
                this.speed = speed;
                this.angle = 0;
                this.x_speed = speed;
                this.y_speed = 0;
                this.time = 0;
                this.mouth = 0;
            }
            draw(ctx) {
                ctx.save();
                ctx.translate(this.x, this.y);
                ctx.rotate(this.angle);
                draw_pacman(ctx, this.radius, this.mouth);
                ctx.restore();
            }

            turn(direction) {
                if (this.y_speed) {
                    this.x_speed = -direction * this.y_speed;
                    this.y_speed = 0;
                    this.angle = this.x_speed > 0 ? 0 : Math.PI;
                } else {
                    this.y_speed = direction * this.x_speed;
                    this.x_speed = 0;
                    this.angle = this.y_speed > 0 ? 0.5 * Math.PI : 1.5 * Math.PI;
                }
            }
            turn_left = function() {
                this.turn(-1);
            }
            turn_right = function() {
                this.turn(1);
            }
            update(elapsed, width, height) {
                if (Math.random() <= 0.01) {
                    if (Math.random() < 0.5) {
                        this.turn_left();
                    } else {
                        this.turn_right();
                    }
                }

                if (this.x - this.radius + elapsed * this.x_speed > width) {
                    this.x = -this.radius;
                }
                if (this.x + this.radius + elapsed * this.x_speed < 0) {
                    this.x = width + this.radius;
                }
                if (this.y - this.radius + elapsed * this.y_speed > height) {
                    this.y = -this.radius;
                }
                if (this.y + this.radius + elapsed * this.y_speed < 0) {
                    this.y = height + this.radius;
                }
                this.x += this.x_speed * elapsed;
                this.y += this.y_speed * elapsed;
                this.time += elapsed;
                this.mouth = Math.abs(Math.sin(2 * Math.PI * this.time));
            }
        }

        function draw_pacman(ctx, radius, mouth) {
            angle = 0.2 * Math.PI * mouth;
            ctx.save();
            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 0.5;
            ctx.beginPath();
            ctx.arc(0, 0, radius, angle, 2 * Math.PI - angle);
            ctx.lineTo(0, 0);
            ctx.closePath()
            ctx.fill();
            ctx.stroke();
            ctx.restore();
        }

        function draw_ghost(ctx, radius, options) {
            options = options || {}
            let feet = options.feet || 4;
            let head_radius = radius * 0.8;
            let foot_radius = head_radius / feet;
            ctx.save();
            ctx.strokeStyle = options.stroke || "white";
            ctx.fillStyle = options.fill || "red";
            ctx.lineWidth = options.lineWidth || radius * 0.05;
            ctx.beginPath();
            for (foot = 0; foot < feet; foot++) {
                ctx.arc(
                    (2 * foot_radius * (feet - foot)) - head_radius - foot_radius,
                    radius - foot_radius,
                    foot_radius, 0, Math.PI
                );
            }
            ctx.lineTo(-head_radius, radius - foot_radius);
            ctx.arc(0, head_radius - radius, head_radius, Math.PI, 2 * Math.PI);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

            ctx.fillStyle = "white";
            ctx.beginPath();
            ctx.arc(-head_radius / 2.5, -head_radius / 2, head_radius / 3, 0, 2 * Math.PI);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(head_radius / 3.5, -head_radius / 2, head_radius / 3, 0, 2 * Math.PI);
            ctx.fill();

            ctx.fillStyle = "black";
            ctx.beginPath();
            ctx.arc(-head_radius / 2, -head_radius / 2.2, head_radius / 8, 0, 2 * Math.PI);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(head_radius / 4, -head_radius / 2.2, head_radius / 8, 0, 2 * Math.PI);
            ctx.fill();

            ctx.restore();
        }

        class Ghost {
            constructor(x, y, radius, speed, colour) {
                this.x = x;
                this.y = y;
                this.radius = radius;
                this.speed = speed;
                this.colour = colour;
            }

            draw(ctx) {
                ctx.save();
                ctx.translate(this.x, this.y);
                draw_ghost(ctx, this.radius, {
                    fill: this.colour
                });
                ctx.restore();
            }

            update = function(target, elapsed) {
                let angle = Math.atan2(target.y - this.y, target.x - this.x);
                let x_speed = Math.cos(angle) * this.speed;
                let y_speed = Math.sin(angle) * this.speed;
                this.x += x_speed * elapsed;
                this.y += y_speed * elapsed;
            }

        }
        let context = document.getElementById("pacman").getContext("2d");

        let pacman = new PacMan(context.canvas.width / 2, context.canvas.height / 2, 20, 100);
        let ghosts = [
            new Ghost(context.canvas.width * Math.random(), context.canvas.height * Math.random(), 20, 35, 'red'),
            new Ghost(context.canvas.width * Math.random(), context.canvas.height * Math.random(), 20, 45, 'pink'),
            new Ghost(context.canvas.width * Math.random(), context.canvas.height * Math.random(), 20, 55, 'cyan'),
            new Ghost(context.canvas.width * Math.random(), context.canvas.height * Math.random(), 20, 75, 'orange')
        ];

        function draw(ctx, guide) {
            pacman.draw(ctx);
            ghosts.forEach(function(ghost) {
                ghost.draw(context, guide);
            });
        }

        function update(elapsed) {
            pacman.update(elapsed, context.canvas.width, context.canvas.height);
            ghosts.forEach(function(ghost) {
                ghost.update(pacman, elapsed);
            });
        }

        let previous, elapsed;

        function frame(timestamp) {
            context.clearRect(0, 0, context.canvas.width, context.canvas.height);
            if (!previous) previous = timestamp;
            elapsed = timestamp - previous;
            update(elapsed / 1000);
            draw(context, true);
            previous = timestamp;
            window.requestAnimationFrame(frame);
        }
        window.requestAnimationFrame(frame);
    </script>
</body>

</html>

Related Topic