HTML5 Game Development by Example:Beginner's Guide(Second Edition)
上QQ阅读APP看书,第一时间看更新

Time for action – moving DOM objects by mouse input

We are going to create a traditional Ping Pong game. There is a paddle on both the left and right sides of the playground. A ball is placed in the middle of the playground. Players can control the right paddle and move it up and down by using the mouse. We will focus on the mouse input and leave the ball movement for a later section:

  1. Let's continue with our pingpong directory.
  2. Next, add a playground object inside the pingpong data object in the js/pingpong.js file. This stores variables that are related to playground:
    // data definition
    var pingpong = {
      paddleA: {
        x: 50,
        y: 100,
        width: 20,
        height: 70
      },
      paddleB: {
        x: 320,
        y: 100,
        width: 20,
        height: 70
      },
      playground: {
        offsetTop: $("#playground").offset().top,
      }
    };
  3. Then, create the following function that handles the mouse's enter, move, and leave events, and place it inside the js/pingpong.js file:
    function handleMouseInputs() {
      // run the game when mouse moves in the playground.
      $('#playground').mouseenter(function(){
        pingpong.isPaused = false;
      });
    
      // pause the game when mouse moves out the playground.
      $('#playground').mouseleave(function(){
        pingpong.isPaused = true;
      });
    
      // calculate the paddle position by using the mouse position.
      $('#playground').mousemove(function(e){
        pingpong.paddleB.y = e.pageY - pingpong.playground.offsetTop;  
      });
    }
  4. We had the renderPaddles function in the previous section. In this section, we are defining a render function and calling the paddles rendering logic. We then call the render function on the next browser redraw via the requestAnimationFrame function.
    function render() {
      renderPaddles();
      window.requestAnimationFrame(render);
    }
  5. Finally, we create an init function to execute the initial logic.
    function init() {
      // view rendering
      window.requestAnimationFrame(render);
    
      // inputs
      handleMouseInputs();
    }
  6. Finally, you need to call the init function that starts our game logic:
    (function($){
      // All our existing code
    
      // Execute the starting point
      init();
    })(jQuery);
  7. Let's test the paddle control of the game. Open the index.html page in the web browser. Try moving the mouse up and down within the playground area. The right paddle should follow your mouse's movement.

What just happened?

We handled the mouse events to move the paddle based on the mouse position. You can play the current work-in-progress version of the game at http://makzan.net/html5-games/pingpong-wip-step3/.

Getting the mouse event

jQuery provides several handy mouse events, and the most basic ones are click, mouse down and mouse up. We track the mouse enter and mouse leave event to start and pause the game. We also use the mouse move event to get the mouse position and update the paddle position based on the mouse position on the playground section.

We need to get the y position of the cursor based on the playground's top left edge. The value of Y in the mouse event is the mouse cursor from the page's top left edge. We then subtract the position of the playground via $("#playground").offset().top.

We update the data of paddle's Y value by using the mouse's X and Y values. This value will eventually reflect on the screen when the paddle view is updated in the render function during the browser redraw.

RequestAnimationFrame

The time interval is used to execute the game loop. The game loop calculates the game logic, which calculates the movement of the game objects.

The requestAnimationFrame feature is used to update the view according to the data. We use the requestAnimationFrame feature to update the view because the view only needs to update in an optimal scenario, where the browser decides.

The interval of requestAnimationFrame is not fixed. When the browser is at the front end, the requestAnimationFrame feature would run often. When the battery is low or the browser is in the background, the browser would slow down the frequency of execution of the requestAnimationFrame feature.

We are using RequestAnimationFrame only on view-related logic. In a later section, we will need to handle game data calculation. For data calculation, we will use setInterval because the setInterval function always executes in a fixed time interval. That's why we use the setInterval function for the game logic calculation and animation frame for view rendering.

Checking the console window

We are writing more complicated logic code now. It is good practice to keep an eye on the console of the Developers Tools. You may toggle between the developer tools by pressing F12 in Windows or command + option + I on Mac OS. If the code contains any error or warning, the error message will appear there. It reports any found error and the line of code that contains the error. It is very useful and important to have the console window open when testing HTML5 games. I have often seen people get stuck and have no idea as to why the code is not working. The reason for this is that they have a typo or syntax error, and they did not check the console window before fighting with the code for hours.

The following screenshot shows that there is an error in the twenty-fifth line of the js/pingpong.js file. The error message is Invalid left-hand side in assignment. After inspecting the code, I found that I wrongly used an equal sign (=) when setting the CSS top property in jQuery:

$("#paddleA").css("top"=top+5);

// instead of the correct code:
// $("#paddleA").css("top", top+5);

The error is displayed as follows:

Moving a DOM object with JavaScript Interval

Imagine now we can make the little red ball move around the playground. The ball will bounce away when it hits the paddles. The player will win a score when the ball passes the opponent's paddle and hits the playground edge behind the paddle. All these actions manipulate the position of the DIVs inside the HTML page by jQuery. To complete this Ping Pong game, our next step is to move the ball.