'How Can I give my player to the cross movement in JS Canvas Game?

This is a Canvas game for personal development and I am stuck in here. Everything works pretty well until I try to give my player a cross-movement I have a player class like this ==> And it has methods like dw() {means go up and right} , as() {left and down at the same time } ... etc I want to give a cross moving to my player with the key combinations .

Maybe someone shows me a correct way to do this.

import { ctx } from "./app.js"


export default class Player {
    constructor(x, y, radius, color) {
        this.x = x
        this.y = y
        this.color = color
        this.radius = radius
    }

    draw() {
        ctx.beginPath()
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
        ctx.fillStyle = this.color
        ctx.fill()
        ctx.closePath()
    }

    moveLeft() {
        this.x -= .01
    }

    moveRight() {
        this.x += .01
    }

    moveUp() {
        this.y -= .01
    }

    moveDown() {
        this.y += .01
    }

    aw() {
        this.x -= .01
        this.y -= .01
    }

    dw() {
        this.x += .01
        this.y -= .01
    }

    as() {
        this.x -= .01
        this.y += .01
    }

    ds() {
        this.x += .01
        this.y += .01
    }

    update() {
        this.draw()
        window.addEventListener('keydown', (event) => {
            switch (event.key) {
                case 'a':
                    this.moveLeft();
                    break;
                case 'd': 
                    this.moveRight();
                    break;
                case 'w':
                    this.moveUp();
                    break;
                case 's':
                    this.moveDown();
                    break;

                case 'a' && 'w':
                    this.aw();
                    break;
                case 'd' && 'w':
                    this.dw();
                    break;
                case 'a' && 's':
                    this.as();
                    break;
                case 'd' && 's':
                    this.ds();
                    break;
                default:
                    break;
            }
        });

    }
}

And the main file is this

import Bullet from "./bullet.js";
import Player from "./player.js";
import Enemy from "./enemy.js";
import ShatteredEnemy from "./shatteredEnemy.js";

// remove scroolbar

document.getElementById("board").onwheel = function (event) {
    event.preventDefault();
};

document.getElementById("board").onmousewheel = function (event) {
    event.preventDefault();
};

const modal = document.getElementById("modal")
const scoreElement = document.getElementById('score') 
const startButton = document.getElementById('startBtn')
const h1 = document.getElementById('h1') // Modal score


const canvas = document.getElementById('board')
canvas.width = window.innerWidth
canvas.height = window.innerHeight // can be written as ctx.height = innerHeight  

export const ctx = canvas.getContext('2d')


const middleX = innerWidth / 2
const middleY = innerHeight / 2

let playerOne = new Player(middleX, middleY, 15, 'white')
playerOne.draw()


let bullets = [] // projectiles
let enemies = []
let shatteredEnemyArray = []

function reset () {
    playerOne = new Player(middleX, middleY, 15, 'white')
    bullets = []
    enemies = []
    shatteredEnemyArray = []
    score = 0
    scoreElement.innerHTML = score
    h1.innerHTML = score
}

function spawnEnemy() {
    setInterval(() => {
        const radius = Math.random() * (30 - 5) + 5
        let x, y;
        if (Math.random() < 0.5) {
            x = Math.random() < 0.5 ? -radius : innerWidth + radius
            y = Math.random() * innerHeight
        } else {
            x = Math.random() * innerWidth
            y = Math.random() < 0.5 ? -radius : innerHeight + radius
        }
        const color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`
        const angle = Math.atan2(middleY - y, middleX - x)
        const velocity = {
            y: Math.sin(angle),
            x: Math.cos(angle)
        }
        const enemy = new Enemy(x, y, radius, color, velocity)
        enemies.push(enemy)

    }, 1500)
}

let animationID
let score = 0
function animate() { 
    animationID = requestAnimationFrame(animate)
    ctx.fillStyle = `rgba(0, 0, 0, 0.2) ` // it is for making shadows on the background
    ctx.fillRect(0, 0, innerWidth, innerHeight)
    playerOne.update()
    shatteredEnemyArray.forEach((shattered, sIdx) => { // if you want to render sth on the screen you must call update() method
        if ( shattered.alpha <= 0) {
            shatteredEnemyArray.splice(sIdx, 1)
        } else {
        shattered.update()
        }
    })

    bullets.forEach((bullet, bulletIndex) => {
        bullet.update()

        // remove bullet if it goes out of bounds
        if (bullet.x + bullet.radius < 0 || bullet.x - bullet.radius > innerWidth
            || bullet.y + bullet.radius < 0 || bullet.y - bullet.radius > innerHeight) {
            setTimeout(() => {
                bullets.splice(bulletIndex, 1)
            }, 0)
        }
    })


    enemies.forEach((enemy, eIdx) => {
        enemy.update()
        const killerDist = Math.hypot(playerOne.x - enemy.x, playerOne.y - enemy.y)
        if (killerDist < playerOne.radius + enemy.radius) {
            // console.log('you lose')
            cancelAnimationFrame(animationID)
            modal.style.display = 'flex' 
            h1.innerHTML = score
            startButton.innerHTML = 'Restart'
        }

        // remove an  enemy if it touches a bullet

        bullets.forEach((bullet, bIdx) => {
            const dist = Math.hypot(bullet.x - enemy.x, bullet.y - enemy.y)
            if (dist < enemy.radius + bullet.radius) { 
                    score += Math.floor(enemy.radius)
                    scoreElement.innerHTML = score

                // if the bullet hits the enemy create a shattered enemy
                for (let i = 0; i < enemy.radius; i++) {
                    shatteredEnemyArray.push(
                        new ShatteredEnemy
                        (bullet.x, 
                        bullet.y, 
                        Math.random() * 2 + 1, 
                        enemy.color, {
                        x: (Math.random() - .5) * 5,
                        y: (Math.random() - .5) * 5
                    }))
                    
                }
                if (enemy.radius - 10 > 10) {
                    gsap.to(enemy, { // for shrinking the enemy
                        duration: 0.5,
                        radius: enemy.radius - 10,
                        ease: 'power2.inOut',
                    })
                    setTimeout(() => {
                        bullets.splice(bIdx, 1)
                    }, 0)
                } else {

                    setTimeout(() => {
                        enemies.splice(eIdx, 1)
                        bullets.splice(bIdx, 1)
                    }, 0)
                }
            }
        })

    })

}

addEventListener('click', (e) => {
    const angle = Math.atan2(e.clientY - playerOne.y, e.clientX - playerOne.x)
    const velocity = {
        x: Math.cos(angle) * 5,
        y: Math.sin(angle) * 5
    }
    const bullet = new Bullet(playerOne.x, playerOne.y, 5,
        'wheat', velocity)
    bullets.push(bullet)
})

  
startButton.addEventListener('click', () => {
    reset()
    animate()
    spawnEnemy()
    modal.style.display = 'none'
})


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source