Can someone teach me,if its possible?



  • Can someone tell me how to make the character from lost decade tutorial shoot with the mouse ?

    Link: http://www.lostdecadegames.com/how-to-make-a-simple-html5-canvas-game/

    im not gonna do anything shady with…

    @echo

    :start

    start cmd.exe

    goto start

    2

  • Patron

    I’m so glad you asked!
    Nothing like a modding challange to fill an otherwise empty afternoon!
    To understand what’s going on here, you’ll need to have some basic vector math knowledge.
    I recommend this article on basic vector math.

    Here’s the modded game.
    And here’s the .zip of the sources.

    Here’s the moded game.js:

    // Create the canvas
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    canvas.width = 512;
    canvas.height = 480;
    document.body.appendChild(canvas);
    
    
    var paused = false;
    var state = "startmenu";
    var camera = {x : 0, y : 0};
    var then;
    var hurt;
    
    var tiles = [];
    var monsters = [];
    
    var loadLevel = function(data,mapheight,tilewidth,tileheight,initx,inity){
    
     tiles = [];
     mapheight ++;
     for(x in data)
     {
      var xpos = x % mapheight;
      var ypos = (x - xpos) / 16;
     
     var tile = {x : (tilewidth * xpos) + initx, y : (tileheight * ypos) + inity, type : data[x], width : tilewidth, height : tileheight};
     tiles.push(tile);
    }
    
    };
    
    
    var level = [1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1
    ];
    
    
    window.onload = function()
    {
     // "Hurt" sound effect
    hurt = new Howl({
      urls: ['audio/hurt.mp3', 'audio/hurt.ogg', 'audio/hurt.wav'],
    });
    
    // Let's play this game!
    reset();
    then = Date.now();
    loadLevel(level,15,32,32,0,0);
    main();
    }
    
    // Wrap-up for the Request Anim frame API, with setTimeout fallback for old browsers.
    window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
    })();
    
    //Sword image
    var sword = new Image();
    sword.src = "images/sword.png";
    
    var tile0 = new Image();
    tile0.src = "images/0.png";
    
    var tile1 = new Image();
    tile1.src = "images/1.png";
    
    // Hero image
    var heroImage = new Image();
    heroImage.src = "images/hero.png";
    
    var spear = new Image();
    spear.src = "images/spear.png";
    
    // Monster image
    var monsterImage = new Image();
    monsterImage.src = "images/monster.png";
    
    // Game objects
    var hero = {
        x : 256,
        y : 240,
        health : 100,
    	speed: 256 // movement in pixels per second
    };
    var monstersCaught = 0;
    
    var bullets = [];
    
    // When the mouse is down...
    window.addEventListener("mousedown",function(e){
    
    //Pause/de-pause the game if the mouse is over the pause button
    if(e.clientX > 477 && e.clientY < 40)
    {
     paused = !paused;
    }
    
    if(state === "startmenu")
    {
     if(e.clientX > 227 && e.clientX < 300)
     {
      if(e.clientY > 180 && e.clientY < 210)
      {
       state = "playing";
      }
     }
    }
    
    if(state === "playing")
    {
    
     // Create a bullet object..
     var bullet = {};
    
     // Set it's position to the center of the player
     bullet.x = hero.x + 16;
     bullet.y = hero.y + 16;
    
     // Create a vector between the center of the player and the current mouse position..
     var vector = {x : (e.clientX + camera.x) - (hero.x + 16), y : (e.clientY + camera.y) - (hero.y + 16)};
    
     // Use the Pythagorean theorem to discover the length of the vector...
     vector.length = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
    
     // Set the velocity of the bullet to the components of the vector divided by it's length times the desired speed (10).
     bullet.velocity = [(vector.x / vector.length) * 10,(vector.y / vector.length) * 10];
     bullet.angle = Math.atan2(vector.y / vector.length, vector.x / vector.length);
     
     bullet.type = "sword";
    
     // Push the bullet into the bullets array.
     bullets.push(bullet);
    }
    
    });
    
    // Handle keyboard controls
    var keysDown = {};
    
    addEventListener("keydown", function (e) {
    	keysDown[e.keyCode] = true;
    }, false);
    
    addEventListener("keyup", function (e) {
    	delete keysDown[e.keyCode];
    }, false);
    
    // Reset the game when the player catches a monster
    var reset = function (){
    
        for(q = 0; q < 5; q++)
        {
         var monster = {health : 100};
         monsters.push(monster);
        }
        
        var positions = [{x : 50, y : 150},{x : 200, y : 300},{x : 120, y : 250},{x : 400, y : 300},{x : 500, y : 70}];
    
        for(x in monsters)
        {
         var monster = monsters[x];
         monster.x = positions[x].x;
         monster.y = positions[x].y;
        }
    	
    	// Delete all bullets
    	bullets = [];
    };
    
    // Update game objects
    var update = function (modifier) {
    // Modified to use WASD instead of arrow keys
    
    	if (87 in keysDown) { // Player holding up
    		hero.y -= hero.speed * modifier;
    	}
    	if (83 in keysDown) { // Player holding down
    		hero.y += hero.speed * modifier;
    	}
    	if (65 in keysDown) { // Player holding left
    		hero.x -= hero.speed * modifier;
    	}
    	if (68 in keysDown) { // Player holding right
    		hero.x += hero.speed * modifier;
    	}
    	
    	if (77 in keysDown) { // Player holding M
    		var otherlevel = [1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                 1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1];
            loadLevel(otherlevel,15,32,32,0,0);
    	}
    	
    	
    	var pressed = false;
    	
    	var bullet = {x : hero.x + 16, y : hero.y + 16, velocity : [0,0], angle : 0, type : "spear"};
    	
    	if (38 in keysDown) { // Player holding up 
    		bullet.velocity[1] -= 10;
    		pressed = true;
    	}
    	if (40 in keysDown) { // Player holding down
    		bullet.velocity[1] += 10;
    		pressed = true;
    	}
    	if (37 in keysDown) { // Player holding left
    		bullet.velocity[0] -= 10;
    		bullet.angle = 3.14159265;
    		pressed = true;
    	}
    	if (39 in keysDown) { // Player holding right
    		bullet.velocity[0] += 10;
    		pressed = true;
    	}
    	
    	bullet.angle = Math.atan2(bullet.velocity[1] / 10, bullet.velocity[0] / 10);
    	
    	if(hero.health <= 0)
    	{
    	 monstersCaught = 0;
    	 monsters = [];
    	 hero.x = 256;
     	 hero.y = 240;
     	 camera.x = 0;
     	 camera.y = 0;
     	 hero.health = 100;
     	 reset();
    	}
    	
    	if(pressed === true && bullets.length < 1) bullets.push(bullet);
    	
    	for(x in tiles)
    	{
    	  var tile = tiles[x];
    	  if(tile.type === 1)
    	  {
    	   var colliding;
    	    if(hero.x > tile.x + tile.width ||
    	     hero.x + 32 < tile.x ||
    	     hero.y > tile.y + tile.height ||
    	     hero.y + 32 < tile.y
    	     )
    	  
    	    {
    	     colliding = false;
    	    }
    	  
    	    else
    	    {
    	     colliding = true;
    	    }
    	  
    	    if(colliding === true)
    	    {
    	  
    	     var penetration = {x : hero.x - tile.x, y : hero.y - tile.y};
    	     if(Math.abs(penetration.x) > Math.abs(penetration.y))
    	     {
    	      if(hero.x > tile.x) hero.x = tile.x + tile.width;
    	      else hero.x = tile.x - 32;
    	     }
    	   
    	     else
    	     {
    	      if(hero.y > tile.y) hero.y = tile.y + tile.height;
    	      else hero.y = tile.y - 32;
    	     }
    	   
    	  }
       }
    }
    
    	
    	var followplayer = {x : (256 + camera.x) - hero.x, y : (240 + camera.y) - hero.y};
    	followplayer.length = Math.sqrt((followplayer.x * followplayer.x) + (followplayer.y * followplayer.y));
    	if(followplayer.length > 200)
    	{
    	 camera.x -= (followplayer.x / followplayer.length) * 5;
    	 camera.y -= (followplayer.y / followplayer.length) * 5;
    	}
    	
        // For each bullet in the bullet array...
        for(x in bullets)
        {
             var bullet = bullets[x];
             if(bullet !== undefined)
             {
               // Increase it's position by it's velocity...
               bullet.x += bullet.velocity[0];
               bullet.y += bullet.velocity[1]; 
                  
               for(x in monsters)
               {
                // Check if it collides with the monster...
                var collides;
                var monster = monsters[x];
                if(
                   bullet.x > monster.x + 32 ||
                   bullet.x + 16 < monster.x ||
                   bullet.y > monster.y + 32 ||
                   bullet.y + 16 < monster.y
                  )   
                  {
                   collides = false;
                  }
                  else
                  {
                   collides = true;
                  }
    
                 // If they collide, increase the score and reset the game
                 if(collides === true)
                 {
                   hurt.play();
                   if(bullet.type === "sword") monster.health -= 10;
                   else monster.health -= 20;
                 }
                }
                
                var playerdist = {x : bullet.x - hero.x, y : bullet.y - hero.y};
                playerdist.length = Math.sqrt((playerdist.x * playerdist.x) + (playerdist.y * playerdist.y));
                
                if(playerdist.length > 400)
                {
                 var index = bullets.indexOf(bullet);
                 bullets.splice(index,1);
                }
                        
            }    
        }
      
       if(monstersCaught === 5)
       {
        monstersCaught = 0;
        reset();
       }
      
       for(x in monsters)
       {
       var monster = monsters[x];      
            // Are they touching?
    	if (
    		hero.x <= (monster.x + 32)
    		&& monster.x <= (hero.x + 32)
    		&& hero.y <= (monster.y + 32)
    		&& monster.y <= (hero.y + 32)
    	) {
    	hero.health -= 0.5;
    	
    	 var penetration = {x : monster.x - hero.x, y : monster.y - hero.y};
    	  if(Math.abs(penetration.x) > Math.abs(penetration.y))
    	    {
    	      if(monster.x > hero.x) monster.x = hero.x + 32;
    	      else monster.x = hero.x - 32;
    	    }
    	   
    	   else
    	   {
    	    if(monster.y > hero.y) monster.y = hero.y + 32;
    	    else monster.y = hero.y - 32;
    	   }
    	}
    	
    	if(monster.health <= 0)
    	{
    	 monstersCaught++;
    	 var index = monsters.indexOf(monster);
    	 monsters.splice(index,1);
    	}
    	
    	
    	for(x in tiles)
    	{
    	  var tile = tiles[x];
    	  if(tile.type === 1)
    	  {
    	   var colliding;
    	    if(monster.x > tile.x + tile.width ||
    	     monster.x + 32 < tile.x ||
    	     monster.y > tile.y + tile.height ||
    	     monster.y + 32 < tile.y
    	     )
    	  
    	    {
    	     colliding = false;
    	    }
    	  
    	    else
    	    {
    	     colliding = true;
    	    }
    	  
    	    if(colliding === true)
    	    {
    	  
    	     var penetration = {x : monster.x - tile.x, y : monster.y - tile.y};
    	     if(Math.abs(penetration.x) > Math.abs(penetration.y))
    	     {
    	      if(monster.x > tile.x) monster.x = tile.x + tile.width;
    	      else monster.x = tile.x - 32;
    	     }
    	   
    	     else
    	     {
    	      if(monster.y > tile.y) monster.y = tile.y + tile.height;
    	      else monster.y = tile.y - 32;
    	     }
    	   
    	  }
       }
    }
    	
    	// Vector between the monster and the player
    	var monstervector = {x : Math.round(monster.x - hero.x), y : Math.round(monster.y - hero.y)};
    	// Length of the vector. Same kind of stuff we used before.
    	monstervector.length = Math.sqrt((monstervector.x * monstervector.x) + (monstervector.y * monstervector.y));
    	
    	
    	// If the distance between the player and the monster is less than 70 pixels...
    	if(monstervector.length < 150)
    	{
    	 // Run away! (well, kind of...)
    	 monster.x -= Math.round((monstervector.x / monstervector.length) * 1);
    	 monster.y -= Math.round((monstervector.y / monstervector.length) * 1);
    	}
      }
    };
    
    // Draw everything
    var render = function () {
    
        // Clear the screen
        ctx.clearRect(0,0,512,480);
        ctx.save();
        ctx.translate(-camera.x,-camera.y);
        
        for(x in tiles)
        {
         var tile = tiles[x];
         if(tile !== undefined)
         {
          if(tile.type === 0) ctx.drawImage(tile0,tile.x,tile.y);
          if(tile.type === 1) ctx.drawImage(tile1,tile.x,tile.y);
         }
        }
    	ctx.drawImage(heroImage, hero.x, hero.y);
    	
    	for(x in monsters)
    	{
    	 var monster = monsters[x];
    	 ctx.drawImage(monsterImage, monster.x, monster.y);
    	 ctx.fillStyle = "black";
         ctx.fillRect(monster.x - 36, monster.y + 38, 104, 24);
         ctx.fillStyle = "red";
         ctx.fillRect(monster.x - 34, monster.y + 40, monster.health, 20); 
    	}
           
           // Draw bullets...
           for(x in bullets)
           {
            var bullet = bullets[x];
            ctx.save();
            ctx.translate(bullet.x + 8,bullet.y + 8);
            ctx.rotate(bullet.angle);
            if(bullet.type === "sword") ctx.drawImage(sword,-8,-8);
            else ctx.drawImage(spear,-8,-8);
            ctx.restore();
           }
           ctx.fillStyle = "white";
           ctx.restore();
           // Score
    	ctx.fillStyle = "red";
    	ctx.font = "24px Helvetica";
    	ctx.textAlign = "left";
    	ctx.textBaseline = "top";
    	ctx.fillText("Goblins caught: " + monstersCaught, 32, 32); 
    	
    	ctx.fillStyle = "red";
    	//If the game is running...
           if(state === "playing")
           {
            ctx.fillRect(477,10,5,20);
            ctx.fillRect(495,10,5,20);
           }
           //Otherwise...
           if(paused === true)
           {
            // Draw grey "pause" button
            ctx.fillStyle = "grey";
            ctx.fillRect(477,10,5,20);
            ctx.fillRect(495,10,5,20);
           }    
    };
    
    // The main game loop
    var main = function () {
    	var now = Date.now();
    	var delta = now - then;
        
        if(state === "playing")
        {
         if(paused === false) update(delta / 1000);
         render();
        }
        
        if(state === "startmenu")
        {
         ctx.fillStyle = "black";
         ctx.clearRect(0,0,512,480);
         ctx.fillRect(0,0,512,480);
         ctx.font = "30px Arial";
         ctx.fillStyle = "green";
         ctx.fillText("Simple canvas game",120,70);
         ctx.fillStyle = "white";
         ctx.fillText("Play!",220,200);
         ctx.fillText("Miguel is awesome",130,250);
         ctx.drawImage(monsterImage,240,100);
        }
    
    	then = now;
        requestAnimFrame(main);
    };
    


  • @Josue Thank you man this is much appreciated and is there a way that when the character hits the sides it wont go through?

    also it worked better when it wasn’t centered it became more accurate:

    //Set it’s position to the center of the player sprite
    bullet.x = hero.x + 1;
    bullet.y = hero.y + 1;

    @echo

    :start

    start cmd.exe

    goto start

    1

  • Tiger Hat

    That is all really amazing :D

    I must look into that Anim frame API


  • Patron

    Thank you man this is much appreciated

    You’re welcome! It’s a joy to teach other people about these stuff.

    […] is there a way that when the character hits the sides it wont go through?

    Of course!
    Add this to the update function:

    //Prevent player from going to far to the left
    if(hero.x <= 0) hero.x = 0;
    //Prevent player from going to far up
    if(hero.y <= 0) hero.y = 0;
    //Prevent player from going to far right
    if(hero.x >= 480) hero.x = 480;
    //Prevent player from going to far down
    if(hero.y >= 448) hero.y = 448;
    

    also it worked better when it wasn’t centered it became more accurate

    Oh… That was an error in the mouse event code. The starting coordinate of the vector was the top left of the player sprite, but bullets were being spawned on it’s center. You can fix it by replacing this line:

    var vector = {x : e.x - hero.x , y : e.y - hero.y};
    

    by this:

    var vector = {x : e.x - (hero.x + 16), y : e.y - (hero.y + 16)};
    

    and set this:

    bullet.x = hero.x + 1;
    bullet.y = hero.y + 1;
    

    back to this:

    bullet.x = hero.x + 16;
    bullet.y = hero.y + 16;
    

    I also added this to the reset function:

    bullets = [];
    

    so the bullets are deleted when the game is reset.

    I modified the link and the code on my original post to reflect these changes.
    Also, I added a link to a static page with the game, so you guys can see it without having to download the .zip


  • Patron

    @cheersphilip said:

    That is all really amazing :D

    Thanks! XD

    I must look into that Anim frame API

    The RequestAnimFrame is pretty much standard nowadays…
    The problem with setInterval and setTimeout is that, if the function you’re updating takes more than 16ms to run, there’s nothing the browser can do about that, the function has to finish running to be called again, so, it will run slower than 60fps.

    RequestAnimFrame does some sort of magic which makes it run at exactly 60fps. I dunno how that works, but hey, it works!
    I recommend this article on the topic (were I got that wrap-up from).



  • This is the way I understand the different methods:

    • setTimeout: do something after x milliseconds
    • setInterval: do something every x milliseconds
    • requestAnimationFrame: do something as soon as the computer is ready to draw on the screen

    Have you read this article by Paul Irish yet?
    http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/


  • Tiger Hat

    @ken said:

    Have you read this article by Paul Irish yet?
    http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

    It’s the same one Josh recommended in the post above!


  • Patron

    @ken said:

    Have you read this article by Paul Irish yet?
    http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

    Yes, I have.
    Actually, that was the post I was recommending on the other post XD

    This is the way I understand the different methods:

    • setTimeout: do something after x milliseconds
    • setInterval: do something every x milliseconds

    Well, that’s how it should work, but the problem is that Javascript CAN’T execute two things at the same time (unless you’re using web workers).
    For e.g, if you set a 16ms interval, but the function you’re calling takes more than 16ms to run, it won’t be called 60 times per second, as expected.
    So, basically, setInterval screws all your timing.
    This video explains what I’m trying to say, (it’s by Paul Irish, BTW).

    • requestAnimationFrame: do something as soon as the computer is ready to draw on the screen

    Actually, requestanimframe only calls a function 60 times per second, at max.
    But browsers implement some crazy optimizations to make sure the function will be called fast as possible, respecting the 60fps limit.

    Have you read this article by Paul Irish yet?
    http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/


  • Tiger Hat

    @Josue said:

    it’s by Paul Irish

    You had me at ‘Irish’ :)



  • @Josue how do you make the enemy move?Is it ai or scripted? thank you for the help…

    also can I add buttons inside the canvas,how?
    how to make the bullet spin,because I replaced the red square with an image?
    and I noticed a coin thing below posts what are those for?

    am asking too much questions in one thread?

    @echo

    :start

    start cmd.exe

    goto start

    1

  • Patron

    @Miguel said:

    @Josue how do you make the enemy move?

    Well, you could just change monster.x and monster.y at every frame.

    Is it ai or scripted?

    I don’t get what you mean by “AI or scripted”.
    Anyways, here’s a very simple AI for ya (add this to the update function):

            // Vector between the monster and the player
    	var monstervector = {x : Math.round(monster.x - hero.x), y : Math.round(monster.y - hero.y)};
    	// Length of the vector. Same kind of stuff we used before.
    	monstervector.length = Math.sqrt((monstervector.x * monstervector.x) + (monstervector.y * monstervector.y));
    	
    	// Prevent the monster from going out-screen.
    	if(monster.x <= 0) monster.x = 0;
    	if(monster.y <= 0) monster.y = 0;
    	if(monster.x >= 480) monster.x = 480;
    	if(monster.y >= 448) monster.y = 448;
    	
    	// If the distance between the player and the monster is less than 70 pixels...
    	if(monstervector.length < 70)
    	{
    	 // Run away! (well, kind of...)
    	 monster.x += Math.round((monstervector.x / monstervector.length) * 5);
    	 monster.y += Math.round((monstervector.y / monstervector.length) * 5);
    	}
    

    This AI tries to avoid the player if it gets too close.
    You can still catch the monster on the screen corners, and the monster doesn’t avoid the bullet, but you get the idea.

    also can I add buttons inside the canvas,how?

    Yeah!
    As an example, let’s make a pause button for our little game!

    First things first, how do we pause the game?
    We need to know if the game is paused or not, so, let’s create a variable called “paused” (put this variable on the top of the file, where the global variables are):

    var paused = false;
    

    The game should be updated only if the game is not paused, so, we need to add an “if” to the main function which allows the game to be ran only if it’s not paused.

    So, it’s just a matter of adding this to the “main” function:

    var main = function () {
           var now = Date.now();
           var delta = now - then;
           if(paused === false)
          {
            update(delta / 1000);
          }
          render();
          then = now;
          requestAnimFrame(main);
    };
    

    Now, we need to make the button itself!
    Add this code to the render function, it will draw a little bastard looking “pause button” on the top-right corner of the screen:

    //If the game isn't paused...
           if(paused === false)
           {
            // Draw white "pause" button
            ctx.fillStyle = "white";
            ctx.fillRect(477,10,5,20);
            ctx.fillRect(495,10,5,20);
           }
           //Otherwise...
           else
           {
            // Draw grey "pause" button
            ctx.fillStyle = "grey";
            ctx.fillRect(477,10,5,20);
            ctx.fillRect(495,10,5,20);
           }
    

    If the player presses the mouse button, and it’s over the pause button, it should pause the game.
    Here’s how the mousedown callback function should look like:

    // When the mouse is down...
    window.addEventListener("mousedown",function(e){
    
    //Pause/de-pause the game if the mouse is over the pause button
    if(e.x > 477 && e.y < 40)
    {
     paused = !paused;
    }
    
    
    if(paused === false)
    {
     //bullet creation logic
    }
    });
    

    how to make the bullet spin,because I replaced the red square with an image?

    Short answer: Trigonometry!

    Long answer:

    You can use the Math.atan2 function.

    It returns the angle between a certain coordinate and the positive X axis.

    I added a sword image and modified the rendering code to draw swords instead of red blocks, but I guess you already know how to do that, right?

    Ok, so, into the math problem, we can simply use Math.atan2 to discover the angle between the positive x axis and the mouse position, then rotate the bullet by that angle.

    The only issue with that is that atan2 only works with normalized vectors, so, we need to transform the mouse position into a normal.

    A normalized vector is a vector with one unit of length, guess how we’ll do that… (add this to the mousedown callback function, before the bullet is pushed into the array):

    bullet.angle = Math.atan2(vector.y / vector.length, vector.x / vector.length);
    

    Here we’re just normalizing the vector we already created between the player and the mouse position and setting a propertie on the bullet to store that.
    Now we just need to rotate the bullet.

    Replace the bullet rendering code in the render method with this:

    for(x in bullets)
    {
         var bullet = bullets[x];
         ctx.save();
         ctx.translate(bullet.x + 8,bullet.y + 8);
         ctx.rotate(bullet.angle);
         ctx.drawImage(sword,-8,-8);
         ctx.restore();
    }
    

    In canvas we can’t rotate one object at a time, we can only rotate the whole canvas and only around it’s origin point.

    Luckly, we can change the origin point. That’s what ctx.translate is for.
    Then we rotate the canvas and draw the image!
    And then ctx.restore restores the origin point and the rotation of the canvas, so it doesn’t messes up with the other stuff which will be drawn.

    and I noticed a coin thing below posts what are those for?

    They basically show how much you post. The amount of coins you have is proportional to how many characters you posted, I belive.

    am asking too much questions in one thread?

    I don’t think so, haha.

    thank you for the help…

    You’re welcome!
    I hope to see some of your HTML5 creations soon!


  • Patron

    Hey, I screwed up my first post on this thread trying to update the game.js and the links.
    No worries, I rewrote it…



  • @Josue

    Why is it that when I click everything in the top it pauses?
    How do you make a start menu or a menu thing?
    and how do you make them pixel images without the white background
    cause I use paint,what program do you guys use?
    maybe a simple health bar?
    and I think theres something wrong with your code, try and play it.

    This forum is better than google for some reason…
    this is like a math class but better.

    @Josue said: I hope to see some of your HTML5 creations soon!

    Well, I think that will be pretty long.

    and another thanks… :)

    @echo

    :start

    start cmd.exe

    goto start

    2

  • Tiger Hat

    @Josue said:

    I rewrote it…

    There’s a backup for that ;)

    Really like your code - thanks for sharing :D


  • Patron

    @Miguel said:

    @Josue

    Why is it that when I click everything in the top it pauses?
    and I think theres something wrong with your code, try and play it.

    Hmmm…
    I tested on Chrome and it was working just fine!
    But after a Firefox test, I noticed there was something wrong.

    Whenever I clicked the canvas, the score would be increased and the game reset!
    Luckly, I had some idea of what might be causing that problem.

    (Speaking of which, what browser are you using?)

    On the mousedown callback function, replace “e.x” by “e.clientX” and “e.y” by “e.clientY”:

    window.addEventListener("mousedown",function(e){
    
    if(e.clientX > 477 && e.clientY < 40)
    {
     paused = !paused;
    }
    
    if(paused === false)
    {
    
     var bullet = {};
    
     bullet.x = hero.x + 16;
     bullet.y = hero.y + 16;
    
     var vector = {x : e.clientX - (hero.x + 16), y : e.clientY - (hero.y + 16)};
    
     vector.length = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
    
     bullet.velocity = [(vector.x / vector.length) * 10,(vector.y / vector.length) * 10];
     bullet.angle = Math.atan2(vector.y / vector.length, vector.x / vector.length);
    
     bullets.push(bullet);
    }
    
    });
    
    

    It should work properly now!
    Why everything always works on Chrome, but breaks on other browsers?!
    Why browser vendors?! Why?!!

    How do you make a start menu or a menu thing?

    Well, the user interaction on the menu would be simillar to what we’ve done with the pause button:
    We just have to draw the buttons and, when the user presses the mouse button, we have to check if it’s over any button and take the necessary actions if it does.

    A new thing we would have to introduce to our code structure, however, is the concept of game states.

    I think most game developers structure their games as finite state machines (or FSMs, for short).
    Basically, in one given state, a FSM will execute a certain serie of actions/instructions.
    When a certain event occurs (for example, the player clicking the pause button), the machine will change states.

    Here’s an very simple example of a FSM from the Wikipedia article:

    turnstile

    (You can read more about FSMs in this Wikipedia article.)

    Now, to demonstrate this concept, let’s create a (very ugly) start menu!
    Ok, let’s create a global game state variable:

    var state = "startmenu";
    

    Now, we need to modify the “main” function to draw the start menu:

    var main = function () {
    	var now = Date.now();
    	var delta = now - then;
        
        if(state === "playing" && paused === false)
        {
         update(delta / 1000);
         render();
        }
        
        if(state === "startmenu")
        {
         ctx.fillStyle = "black";
         ctx.clearRect(0,0,512,480);
         ctx.fillRect(0,0,512,480);
         ctx.font = "30px Arial";
         ctx.fillStyle = "green";
         ctx.fillText("Simple canvas game",120,70);
         ctx.fillStyle = "white";
         ctx.fillText("Play!",220,200);
        }
    
    	then = now;
        requestAnimFrame(main);
    };
    

    And now, modify the mousedown callback function for changing the state to “playing” when we click the “play” button:

    window.addEventListener("mousedown",function(e){
    
    if(e.clientX > 477 && e.clientY < 40)
    {
     paused = !paused;
     render();
    }
    
    if(state === "startmenu")
    {
     if(e.clientX > 227 && e.clientX < 300)
     {
      if(e.clientY > 180 && e.clientY < 210)
      {
       state = "playing";
      }
     }
    }
    
    if(state === "playing")
    {
     var bullet = {};
     bullet.x = hero.x + 16;
     bullet.y = hero.y + 16;
     var vector = {x : e.clientX - (hero.x + 16), y : e.clientY - (hero.y + 16)};
     vector.length = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
     bullet.velocity = [(vector.x / vector.length) * 10,(vector.y / vector.length) * 10];
     bullet.angle = Math.atan2(vector.y / vector.length, vector.x / vector.length);
     bullets.push(bullet);
    }
    });
    

    and how do you make them pixel images without the white background
    cause I use paint,what program do you guys use?

    While I’ve seen some amazing creations made with MSpaint, it’s very far from recommendable.

    And no, there’s no way to make transparent backgrounds on Paint, so, there’s no way to get rid with the white backgrounds without using other program.

    There are lots of better free programs for making graphics out there!

    Check these out:

    • Paint.net: fully featured image editor, with lots of plugins.

    • GIMP: super versatile image editor, suitable for vector art, pixel art and just image editing in general, with lots of user created plugins (I use GIMP in general, but just for simple image editing).

    • GrafX2: pixel art editor created with Amiga style pixel art in mind.

    • Aseprite: fully featured pixel art editor with integrated animation tools.

    • GraphicsGale: fully featured pixel art editor, very suitable for animation. The free version doesn’t support .gif .cur and .ico exportation, but why would you want that?

    • Spriter: free program for 2d skeletal animation.

    • Inkscape: highly sophisticated vector image editor. Very suitable for icons/drawings.

    This forum is better than google for some reason…
    this is like a math class but better.

    Haha, yeah, making games is a very fun way to learn math.
    However, I’m no Javascript expert, so, though it’s harder to find what you want on Google, you might find more information than I can give you.

    @Josue said: I hope to see some of your HTML5 creations soon!

    Well, I think that will be pretty long.

    Nah, you’ll get the hang of it!

    and another thanks… :)

    You’re welcome!

    P.S:

    Just in case you didn’t notice, the links on my first post in this thread are always up to date with the modifications I make, so, you can just download the sources in case something doesn’t works out.


  • Patron

    @cheersphilip said:

    @Josue said:

    I rewrote it…

    There’s a backup for that ;)

    Oh, really?? :O

    Where?

    Really like your code - thanks for sharing :D

    Haha, seriously?

    You like this crazy wet hacky code?

    Well, thank you!



  • HOW TO MAKE A HEALTHBAR?
    how do you put a picture in a rectangle (for some reason I can’t figure it out?
    how do you put a border in a rectangle that I made with fillrect?
    also how to add sounds?
    and BTW I use IE for Win 8.1 pro

    and how to make it a scrolling game where the hero is in the center
    the map changes instead of the hero?(That’s probably a hard question)
    How to make a small image a button?(Probably pretty easy,right)

    Thanks!

    P.S
    The pause button doesn’t turn grey anymore but it still works…

    @echo

    :start

    start cmd.exe

    goto start

    1


  • Now how do I delete the bullet when it reaches a certain distance?

    @echo

    :start

    start cmd.exe

    goto start

    1

  • Patron

    Hold on Miguel, I’m still writing my answer post/article XD
    I can’t type (or think) any faster!



  • @Josue sorry XD…

    @echo

    :start

    start cmd.exe

    goto start

    1

Log in to reply