1

I am having a problem where when I fire either left or right, once i move the character the bullets direction will change while its still fired. I am using the protagonist picture as the condition to either shoot right or left but i would like the bullet to keep firing in the fired direction even if i change the movement of the character

I am a beginner in Javascript and I'm using canvas to create a game for a college project.

if (moveBullet) {
    let s = heroPic.src.substring(heroPic.src.lastIndexOf("/") + 1);
    //alert(s);

    if (s == "Protagenist_Right_Jet.png" || s == "Protagenist_Stand_Jet.png") {
        bulletX += 20;
    }

    if (s == "Protagenist_Left_Jet.png") {
        bulletX -= 20;
    }

    if (bulletX >= canvas.width) {
        moveBullet = false;
        bulletX = canvas.width + 50
        bulletY = canvas.height + 50;

    }

    if (bulletX <= 0) {
        moveBullet = false;
        bulletX = canvas.width + 50
        bulletY = canvas.height + 50;

    }
}

Full Code

<!DOCTYPE html>
    <body>

        <div id="canvasesdiv" style="text-align: center;">

            <canvas id="canvas1" width="800" height="500" tabIndex="0" style="background: url('Level 1.png');position: relative; display: block;">


        </div>

        
        <script>
            
            var canvas = document.getElementById("canvas1");
            var ctx = canvas.getContext("2d");

                
            //get the animation frame depending on the browser engine
            var requestAnimationFrame = window.requestAnimationFrame ||
                                        window.mozRequestAnimationFrame ||
                                        window.webkitRequestAnimationFrame ||
                                        window.msRequestAnimationFrame;



        
            //Hero Attributes
            var jetPackAudio = new Audio();
            jetPackAudio.src = "Jetpack Sound.mp3";
            var heroPic = new Image();

            var heroX ;
            var heroY ;

            //Decides where the hero is looking

            var heroRight = false;

            var life = 3;

            var heroWidth = 50 ;
            var heroHeight = 50 ;

            var gravity = 5;

            heroX = 20;
            heroY = 440;

            heroPic.src = "Protagenist_Stand_Jet.png";

            function drawHero(x,y)
            {
                ctx.drawImage(heroPic,x,y,heroWidth,heroHeight);

            }

            hitBottom = function() {
                var rockbottom = canvas.height - heroHeight;
                if (heroY > rockbottom) {
                    heroY = rockbottom;
                }
            }

            // Key Attribute

            var key = new Image();
            key.src = "Key1.png"            

            var keyX ;
            var keyY ;
            var keyCounter = 0;

            var keyWidth = 30 ;
            var keyHeight = 30 ;


            function drawKey()
            {
                ctx.drawImage(key,keyX,keyY,keyWidth,keyHeight);

            } 

            var killCounter = 0 ;
            var levelKillCounter;

            // Monster 1 Attributes

            var monster1 = new Image();
            monster1.src = "Monster1_Left.png"

            var m1MoveLeft = true;
            

            var m1X ;
            var m1Y ;

            var m1Width = 50 ;
            var m1Height = 50 ;


            function drawMonster1()
            {
                ctx.drawImage(monster1,m1X,m1Y,m1Width,m1Height);

            }

            // Monster 2 Attributes

            var monster2 = new Image();
            monster2.src = "Monster 2_Right.png"

            var m2MoveRight = true;
            

            var m2X ;
            var m2Y ;

            var m2Width = 50 ;
            var m2Height = 50 ;


            function drawMonster2()
            {
                ctx.drawImage(monster2,m2X,m2Y,m2Width,m2Height);

            }

            // Monster 3 Attributes

            var monster3 = new Image();
            monster3.src = "Monster3_Right.png"
            
            var m3MoveRight = true;


            var m3X ;
            var m3Y ;

            var m3Width = 50 ;
            var m3Height = 50 ;


            function drawMonster3()
            {
                ctx.drawImage(monster3,m3X,m3Y,m3Width,m3Height);

            }

            
            // Hit Bottom
            hitBottom = function() {
                var rockbottom = canvas.height - heroHeight;
                if (heroY > rockbottom) {
                    heroY = rockbottom;
                }
            }


            //Bullet Attribute
            var bulletX;
            var bulletY;

            const ammo = [];
            
            var moveBullet = false;
            
            var bulletImage = new Image();
            bulletImage.src = 'Bullet.png';

            function drawBullet(x,y)
            {

                ctx.drawImage(bulletImage,bulletX,bulletY);

            }

            //this function is used to detect a hit monster 1
            function getDistanceHit1() {
                
                var xRect = (m1X - bulletX);
                var yRect = (m1Y - bulletY);
                return Math.sqrt(Math.pow((xRect), 2) + Math.pow((yRect), 2));
            }
            //this function is used to detect a hit monster 2
            function getDistanceHit2() {
                
                var xRect = (m2X - bulletX);
                var yRect = (m2Y - bulletY);
                return Math.sqrt(Math.pow((xRect), 2) + Math.pow((yRect), 2));
            }
            //this function is used to detect a hit monster 3
            function getDistanceHit3() {
                
                var xRect = (m3X - bulletX);
                var yRect = (m3Y - bulletY);
                return Math.sqrt(Math.pow((xRect), 2) + Math.pow((yRect), 2));
            }

            //this function is used to detect if the player got the key
            function getDistanceKey() {
                
                var xRect = (keyX - heroX);
                var yRect = (keyY - heroY);
                return Math.sqrt(Math.pow((xRect), 2) + Math.pow((yRect), 2));
            }

            //configure the audio files
            var fireAudio = new Audio();
            fireAudio.src = "fire.mp3";

            var hitAudio = new Audio();
            hitAudio.src = "neck_snap.wav"

            //Hero Movement
            var rightPressed = false;
            var leftPressed = false;
            var upPressed = false;
            var downPressed = false;

            window.addEventListener("keydown", heroControl);

            //Keyboard Cotrolls
            function heroControl(event) { //event handler function
    if (event.keyCode == 32) { //SPACE BAR PRESSED - fire gun

     moveBullet = true;
                    fireAudio.play();

                    
                    bulletX = heroX + 10;
                    bulletY = heroY + (heroHeight / 2);
                    
                    
                    console.log("BulletX = " + bulletX);


    }
                // 38 is up arrow, 87 is the W key
                if (event.keyCode == 38 || event.keyCode == 87) { //Jump
                    upPressed = true;
                    console.log("HeroY = " + heroY);
                    
                }
                // 39 is right arrow, 68 is thw D key
                else if (event.keyCode == 39 || event.keyCode == 68) { //move Right
                    rightPressed = true;
                    console.log("Herox = " + heroX);
                }
                else if(event.keyCode == 37 || event.keyCode == 65) { // Move Left
                    leftPressed = true;
                    console.log("Herox = " + heroX);

                }
                else if(event.keyCode == 40 || event.keyCode == 83) { // Move Left
                    downPressed = true;
                    console.log("Heroy = " + heroY);

                }
            }

            //Touch Controls

            canvas.addEventListener("touchstart", handleTouchStart, false);

            function handleTouchStart(touchEvent) { //event handler for touch events

             var rect = canvas.getBoundingClientRect(); //to get canvas offsets

                let touchX = touchEvent.changedTouches[0].clientX - rect.left;
                let touchY = touchEvent.changedTouches[0].clientY - rect.top;

                if (touchX <= canvas.width && touchX > canvas.width - 200) {

                    rightPressed = true;

                }

                if (touchX >= 0 && touchX < canvas.width - 600) {

                    leftPressed = true;

                }

                if (touchY >= 0 && touchY < canvas.height - 200) {

                    upPressed = true;

                }

                if (touchY <= canvas.height && touchY > canvas.height - 200) {

                    downPressed = true;

                }


            } 




            function moveHero() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);



                if(rightPressed) {

                    if(heroX < canvas.width - 53){

                        heroPic.src = "Protagenist_Right_Jet.png"
                        heroRight = true;

                        heroX = heroX + 10;   
                        heroRight = true;


                        rightPressed = false;
                    }
                    else
                    {
                        rightPressed = false;
                        heroRight = false;


                    }
 

                }

                if(leftPressed) {

                    if(heroX > 0){

                        heroX = heroX - 10;
                        heroLeft = true;
 

                        heroPic.src = "Protagenist_Left_Jet.png";
                        bulletImage.src = "left_bullet.png";

                        leftPressed = false;
                    }
                    else
                    {
                        leftPressed = false;
                        heroLeft = false;


                    }

                
                }
                if(upPressed) {

                    if(heroY > 0){

                        heroY = heroY - 20;
                        heroStand = true;;

                        jetPackAudio.play();

                        heroPic.src = "Protagenist_Stand_Jet.png";

                        upPressed = false;
                    }
                    else
                    {
                        upPressed = false;
                        heroStand = false;;


                    }

                    

                }

                if(downPressed) {

                    if(heroY < canvas.height){

                        heroPic.src = "Protagenist_Stand_Jet.png"
                        heroStand = true;

                        heroY = heroY + 10;   


                        downPressed = false;
                    }
                    else
                    {
                        downPressed = false;
                        heroStand = false;


                    }
 

                }

                
                displayScoreArea();

                drawHero(heroX,heroY);

                drawMonster1();
                drawMonster2();
                drawMonster3();

                drawKey();


                drawBullet(bulletX,bulletY);
                requestAnimationFrame(moveHero);
            }

            //Level Setter
            var level = 2;

            function setLvl()
            {   
                
                if(level == 1)
                {

                    canvas.style = "background: url('Level 1.png')";
                    levelKillCounter = 3;


                }
                else if(level == 2)
                {
                    canvas.style = "background: url('Level 2.png')";
                    monster1.src = "Monster3_Right.png"
                    monster2.src = "Monster3_Right.png"

                }
                else if(level == 3)
                {
                    canvas.style = "background: url('Level 3.png')";

                }
                

            }

            var gameAudio = new Audio();
            gameAudio.src = "Dungeon Theme.mp3"

            function animation()
            {
                setTimeout(() => {

                    //animation code goes into this anonymous function handler
                    requestAnimationFrame(animation);

                    //clear the whole canvas area   
                    ctx.clearRect(0, 0, canvas.width, canvas.height);

                    moveHero();

                    drawMonster1();
                    drawMonster2();
                    drawMonster3();


                    drawKey();


                    drawBullet(bulletX,bulletY);

                    monsterAnimate();

                    
                    setLvl();

                    heroY = heroY + gravity;

                    if(moveBullet)
                    {
                        let s = heroPic.src.substring(heroPic.src.lastIndexOf("/") + 1);
                        //alert(s);
                        
                        if(s == "Protagenist_Right_Jet.png" || s == "Protagenist_Stand_Jet.png")
                        {
                            bulletX +=20;
                        }

                        if(s == "Protagenist_Left_Jet.png")
                        {
                            bulletX -=20;
                        }

                        if(bulletX >= canvas.width)
                        {
                            moveBullet = false;
                            bulletX = canvas.width + 50
                            bulletY = canvas.height +50;
                            
                        }

                        if(bulletX <= 0)
                        {
                            moveBullet = false;
                            bulletX = canvas.width + 50
                            bulletY = canvas.height +50;
                            
                        }
                         
                        console.log(getDistanceHit1()); 
                        if (getDistanceHit1() <= 30 ||
                            getDistanceHit2() <= 30 ||
                            getDistanceHit3() <= 30 ) 
                        {
                            
                            //Delete Monster
                            if(getDistanceHit1() <= 30)
                            {
                                m1X = 1000;
                                m1Y = 1000;
                            }

                            if(getDistanceHit2() <= 30)
                            {
                                m2X = 1000;
                                m2Y = 1000;
                            }

                            if(getDistanceHit3() <= 30)
                            {
                                m3X = 1000;
                                m3Y = 1000;
                            }
                            
                            //increase the hit count
                            killCounter++;
                            //we have a hit
                            moveBullet = false;
                            
                            //play the hitAudio
                            hitAudio.play();

                            //Reset Bullet
                            bulletX = canvas.width + 50
                            bulletY = canvas.height +50;

                            
                                                    
                        
                        }
                                                
                    }

                    if(killCounter == 3)
                    {
                        keyX = canvas.width / 2;
                        keyY = 150;
                    }

                    if(getDistanceKey() <= 10)
                    {
                        keyCounter = 1;
                        keyX = 1000;
                        keyY = 1000;
                    }

                    //level progression flow - check of level objectives are met
                    if (level == 1 && keyCounter == 1 && heroX >= 700 & heroY >= 50) {
                        alert("Level 1 completed. Starting Level 2...");
                        level = 2;
                        killCounter = 0; //reset
                        keyCounter = 0;//reset

                        m1X = 700;
                        m1Y = 370;

                        m2X = 100;
                        m2Y = 320;

                        m3X = 100;
                        m3Y = 170;

                    }
                    else if (level == 2 && keyCounter == 1 && heroX == 700 & heroY == 50) {
                        alert("Level 2 completed. Starting Level 3...");
                        level = 3;
                        killCounter = 0; //reset
                        keyCounter = 0;//reset
                    }

                    else if (level == 3 && currentLevelHits == 4) {
                        //last level
                        var playAgain = confirm("Game completed. Play again?");
                        if (playAgain)
                            window.location.reload(true); //force reload  
                        else
                            stopAnimation = true;
                    }


                    //gameAudio.play();

                    displayScoreArea();


                    hitBottom();

                },100)
            }

            m1X = 700;
            m1Y = 370;

            m2X = 100;
            m2Y = 320;

            m3X = 100;
            m3Y = 170;

            function monsterAnimate()
            {
        
                //Movement for level 1
                if(level == 1)
                {
                    

                    if(m1MoveLeft)
                    {
                        m1X -= 10
                    }
                    else if(!m1MoveLeft)
                    {
                        m1X += 10
                    }

                    if(m2MoveRight)
                    {
                        m2X += 10
                    }
                    else if(!m2MoveRight)
                    {
                        m2X -= 10
                    }
                    
                    if(m3MoveRight)
                    {
                        m3X +=10
                    }
                    else if(!m3MoveRight)
                    {
                        m3X -= 10
                    }

                    if(m1X == 420)
                    {
                        m1MoveLeft = false;
                        monster1.src ="Monster 1_Right.png"
                    }
                    else if(m1X == 700)
                    {
                        m1MoveLeft = true;
                        monster1.src ="Monster1_Left.png"

                    }

                    if(m2X == 310)
                    {
                        m2MoveRight = false;
                        monster2.src ="Monster2_left.png"
                    }
                    else if(m2X == 100)
                    {
                        m2MoveRight = true;
                        monster2.src ="Monster 2_Right.png"

                    }

                    if(m3X == 310)
                    {
                        m3MoveRight = false;
                        monster3.src ="Monster 3_left.png"
                    }
                    else if(m3X == 100)
                    {
                        m3MoveRight = true;
                        monster3.src ="Monster3_Right.png"

                    }

                }

                //Movement for level 2

                if(level == 2)
                {
                    

                    if(m1MoveLeft)
                    {
                        m1X -= 20
                    }
                    else if(!m1MoveLeft)
                    {
                        m1X += 20
                    }

                    if(m2MoveRight)
                    {
                        m2X += 20
                    }
                    else if(!m2MoveRight)
                    {
                        m2X -= 20
                    }
                    
                    if(m3MoveRight)
                    {
                        m3X +=20
                    }
                    else if(!m3MoveRight)
                    {
                        m3X -= 20
                    }

                    if(m1X == 420)
                    {
                        m1MoveLeft = false;
                        monster1.src ="Monster 1_Right.png"
                    }
                    else if(m1X == 700)
                    {
                        m1MoveLeft = true;
                        monster1.src ="Monster1_Left.png"

                    }

                    if(m2X == 600)
                    {
                        m2MoveRight = false;
                        monster2.src ="Monster2_left.png"
                    }
                    else if(m2X == 100)
                    {
                        m2MoveRight = true;
                        monster2.src ="Monster 2_Right.png"

                    }

                    if(m3X == 500)
                    {
                        m3MoveRight = false;
                        monster3.src ="Monster 3_left.png"
                    }
                    else if(m3X == 100)
                    {
                        m3MoveRight = true;
                        monster3.src ="Monster3_Right.png"

                    }

                }
            }

            // Create gradient
            var gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);

            gradient.addColorStop("0", "black");
            gradient.addColorStop("0.5", "red");
            gradient.addColorStop("1.0", "white");

            //Draw Score Area
            function displayScoreArea() {

                ctx.font = "40px Arial";
                ctx.strokeStyle = gradient;
                ctx.fillStyle = gradient;
                ctx.strokeText(killCounter, 380, 60);
                ctx.strokeText(life, 65, 45);
                ctx.strokeText(keyCounter, 65, 90);

                    
                }
            animation();


            function moveup()
            {
                upPressed = true;
            }

            function movedown()
            {
                downPressed = true;
            }

            function moveright()
            {
                rightPressed = true;
            }

            function moveleft()
            {
                leftPressed = true;
            }

            function shootGun()
            {
                moveBullet = true;
                fireAudio.play();

                
                bulletX = heroX + 10;
                bulletY = heroY + (heroHeight / 2);
                
                
                console.log("BulletX = " + bulletX);
            }



        </script>

    <div style="text-align:center;width:900px;">
        <button style="width: 100px; height: 60px;" onclick="moveup()">UP</button><br><br>
        <button style="width: 100px; height: 60px;" onclick="moveleft()">LEFT</button>
        <button style="width: 100px; height: 60px; margin-left: 20px;" onclick="moveright()">RIGHT</button><br><br>
        <button style="width: 100px; height: 60px;" onclick="movedown()">DOWN</button>
        <button style="width: 100px; height: 60px;" onclick="shootGun()">SHOOT</button>

    </div>
            
    </body>        
</html>
  • Can you add more code, such as HTML and CSS? – Matt Croak Nov 18 '19 at 16:17
  • Welcome to StackOverflow! It's hard to tell without seeing the full code, what have you tried? The problem there is that you're getting the name of the image (which represents the position of the character) each time but you should save the old position (when the bullet was fired) into a variable and use that one to move the bullet left or right. – fsinisi90 Nov 18 '19 at 16:19
  • Should it be possible to shoot more than one bullet? – Snackoverflow Nov 18 '19 at 16:20
  • Your bullet is a distinct object, so literally make it a js object. Provide it a `velocity` property initialized according to the character's position, then adjust your bullet movement function to use this velocity. Right now your velocity is recalculated each step, but what you seem to want is for it to be constant. – PartyLich Nov 18 '19 at 16:39
  • @MattCroak there is no CSS Code but i will add the full code – Kaizoku Gamer Nov 18 '19 at 17:14
  • @Snackoverflow Nah only one at a time is fine, but every time i shoot it resets the bullet anyways – Kaizoku Gamer Nov 18 '19 at 17:15
  • @fsinisi90 i will add the full code – Kaizoku Gamer Nov 18 '19 at 17:15
  • @PartyLich I understand what your saying, but i dont know how to create objects in JavaScript, i recommended the teacher to teach us about objects, but they are strictly aligned to the course material, but if you can help me create one, then i can add it in the project – Kaizoku Gamer Nov 18 '19 at 17:19
  • @KaizokuGamer I made a [code sandbox](https://codesandbox.io/s/peaceful-kilby-7xttv?fontsize=14) for this can you please add your images? I believe I've fixed some of the code but context keeps breaking because it doesn't have the images – Matt Croak Nov 18 '19 at 17:36

1 Answers1

1

Using objects would be one (of many) steps in the right direction. Even without them, you could:

In your bullet variable creation

...
//Bullet Attribute
  let bulletX;
  let bulletY;
  let bulletVelocity;
...

In your hero control function, where the firing action currently takes place, initialize your bullet properties once

...
//Keyboard Cotrolls
function heroControl(event) { //event handler function
  if (event.keyCode == 32) { //SPACE BAR PRESSED - fire gun
    moveBullet = true;
    fireAudio.play();


    bulletX = heroX + 10;
    bulletY = heroY + (heroHeight / 2);

    // Initialize bullet velocity
    let s = heroPic.src.substring(heroPic.src.lastIndexOf("/") + 1);
    //alert(s);

    if (s == "Protagenist_Right_Jet.png" || s == "Protagenist_Stand_Jet.png") {
        bulletVelocity = 20;
    } else {
        bulletVelocity = -20;
    }
...

In your animation function, where this currently takes place, update your bullet position according to its velocity

...
if (moveBullet) {
  bulletX += bulletVelocity;

  if (bulletX >= canvas.width) {
...

There are lots of things I would refactor in your current setup, but this should get you moving on your current problem.

And a quick example of a very simple object:

// create with key: value pairs
let bullet = {
  x: 0,
  y: 0,
  velocity: 0,
};

// Access or set properties using dot notation
bullet.x = heroX + 10;
bullet.y = heroY + (heroHeight / 2);
PartyLich
  • 319
  • 1
  • 8
  • Thank you very much for your help, so it seems that my placement of the code was a bit off, and i really find objects to be a more optimal solution when creating game objects, but we were not taught how to to it, but based on the example that you just gave me, makes it clear how objects work, and thank you again. – Kaizoku Gamer Nov 19 '19 at 09:25