Creating Sprite (character) Movement with Javascript and jQuery Ver. 1.2

See Digipiph Game Manager, a HTML5 framework to create character based, moveable sprites and much more!

Skip the theory and walk through and learn by example. Click here to see the demo.

NOTICE: These are updates to the previous version, see version 1.1

Issues Addressed from version 1.1:

  • Added a Character Environment (stage + map) - because using the whole browser window for movement isn't very logical, this version we will place the character inside an enclosed environment or stage.
  • Update the Movement Animation - with the addition of the new environment we have placed the character in, we will need to update our code to either move the character or move the map during movement.

Added a Character Environment

Our first step for creating an environment, which is a stage (or enclosed area which our character will be restrained to) and map (the background of which our character will travel over), is to adjust our html. We will need to place our "character" div object inside a new "stage" div object. Then we will also need to the the "map" div object below the "character". See the adjusted html below:

<div id="stage">
  <div id="character"></div>
  <div id="map"></div>
</div>

The second step is to adjust our CSS by setting the "stage" and "map" CSS and adjusting our "character" object CSS as the "character" object will now reside inside the "stage" object and will need to have its "zindex" set to appear above the "map". See below:

<style type="text/css">
  #character {
	  position: absolute;
	  top: 192px; /*starting pos*/
	  left: 128px; /*starting pos*/
	  width: 32px;
	  height: 32px;
	  z-index: 1;
	  background: url('character.png') no-repeat;
  }
 
  #stage {
	  position: relative;
	  width: 640px;
	  height: 480px;
	  margin: auto auto;
	  border: solid 2px #000;
	  overflow: hidden;
  }
 
  #map {
	  position: absolute;
	  width: 800px;
	  height: 800px;
	  background: url('map.jpg') no-repeat 0px 0px;
  }
</style>

With the new objects added to positioned, it is time to adjust our code to detect the edge of the stage. We will start off by adding to our global javascript variables, we will define the stage width and height and map width and height.

  var currentKey;      //records the current keypressed
  var charStep = 2;    //1=1st foot, 2=stand, 3=2nd foot, 4=stand
  var charSpeed = 400; //how fast the char moves
  var stageWidth = 640;
  var stageHeight = 480;
  var mapWidth = 800;
  var mapHeight = 800;

Time to create a "chkMove" function that will detect if our character can move to the next space or not. It will return false if the "character" or "map" object is at the bottom, top, or sides of the stage and can not be moved. It will return "map" if the "map" should be the object moving and will return "character" if the "character" should be the object moving. We can't move the "character" object the whole time for if our "map" is larger than the "stage" the "map" will need to scroll.

function chkMove(dir) {
  switch(dir) {
    case'front':
      // if the character is greater than or equal to 64px from the bottom of the stage
      // AND the character is not less than or equal to 64px from the top of the stage
      // AND the "map" graphic is not at the bottom
      if ($('#character').position().top <= (stageHeight - 64) 
        && $('#character').position().top >= 64
        && (Math.abs($('#map').position().top) + stageHeight) < mapHeight) {
          return 'map';
      } 
      else if ($('#character').position().top + 32 < stageHeight) { 
        return 'character';
      } 
      else {
        return false;
      }
    break;
    case'back':
      // if the character is greater than or equal to 64px from the bottom of the stage
      // AND the character is not less than or equal to 64px from the top of the stage
      // AND the "map" graphic is not at it's top
      if ($('#character').position().top >= 64 
        && $('#character').position().top < (stageHeight - 64)
        && $('#map').position().top < 0) {
          return 'map';
      } 
      else if ($('#character').position().top - 32 >= 0) { 
        return 'character';
      } 
      else {
        return false;
      }
    break;
    case'left':
      // if the character is greater than or equal to 64px from the left of the stage
      // AND the character is not less than or equal to 64px from the right of the stage
      // AND the "map" graphic is not at the right
      if ($('#character').position().left < (stageWidth - 64) 
        && $('#character').position().left >= 64
        && $('#map').position().left < 0) {
          return 'map';
      } 
      else if ($('#character').position().left - 32 >= 0) { 
        return 'character';
      } 
      else {
        return false;
      }
    break;
      case'right':
      // if the character is greater than or equal to 64px from the left of the stage
      // AND the character is not less than or equal to 64px from the right of the stage
      // AND the "map" graphic is not at the left
      if ($('#character').position().left <= (stageWidth - 64) 
        && $('#character').position().left >= 64
        && (Math.abs($('#map').position().left) + stageWidth) < mapWidth) {
          return 'map';
      } 
      else if ($('#character').position().left + 32 < stageWidth) { 
        return 'character';
      } 
      else {
      return false;
      }
    break;
  }

With the chkMove() function created, we can now determine if we will be moving the character or the map, so it is time to implement the chkMove() function into our move the character process. See below:

  //move the char
  switch(dir) {
    case'front':
      if (chkMove(dir) == 'map') {
        $('#map').animate({top: '-=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
    else if (chkMove(dir) == 'character') {
      $('#character').animate({top: '+=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
  break;
  case'back':
    if (chkMove(dir) == 'map') {
      $('#map').animate({top: '+=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
    else if (chkMove(dir) == 'character') {
      $('#character').animate({top: '-=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
  break;
  case'left':
    if (chkMove(dir) == 'map') {
      $('#map').animate({left: '+=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
    else if (chkMove(dir) == 'character') {
      $('#character').animate({left: '-=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
  break;
  case'right':
    if (chkMove(dir) == 'map') {
      $('#map').animate({left: '-=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
    else if (chkMove(dir) == 'character') {
      $('#character').animate({left: '+=32'}, charSpeed, "linear", function() {
        if (currentKey == currentKeyCheck) moveChar(dir);
      });
    }
  break;

Click here to see the demo of version 1.2.

Comments

my english is bad. Forgive!!!Have the above article, what is done with the mouse?clicked character to move to any location coordinates ..I wish you good work thank you for your interest.

Hey Murat, what I was working with does not account for the mouse as that would require different programming to detect mouse positioning and detecting clicks. This can all still be done, I would suggest checking http://api.jquery.com/mousemove/. You could run the mousemove function everytime someone would click on the "stage". 

$("#other").click(function() {
  $("#target").mousemove();
});

I have not finished these tutorials yet as I have basically made all these into a jQuery function Spritify. I will add mouse detection in the near future.

Best of luck!

~dc