ผลต่างระหว่างรุ่นของ "01219245/cocos2d/Maze"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
แถว 115: แถว 115:
 
});
 
});
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Then, you can create it in <tt>GameLayer.init</tt>:
 +
 +
<syntaxhighlight lang="javascript">
 +
        this.pacman = new Pacman( 10*40 + 20, 6*40 + 20 );
 +
        this.maze.addChild( this.pacman );
 +
</syntaxhighlight>
 +
 +
'''Notes:''' The pacman is added, as a child, to the maze, so that its position is relative to the maze.  We do this because it will be easy to move the whole maze around.
  
 
=== Movements: idea ===
 
=== Movements: idea ===

รุ่นแก้ไขเมื่อ 02:53, 19 กุมภาพันธ์ 2557

This is part of 01219245.

In previous tutorials, we developed games with objects moving freely in the screen. In this tutorial, we will create a game where objects moves in the scene defined by game data. We will re-create a simpler version of Pac-Man. The game screen is shown below.

Pacman-maze.png

Steps

Maze & maze data

Notes: Cocos2d-html5 supports TMX tilemap (read more), however in this program, we shall do it manually.

Our maze consists of a set of smaller 40x40 sprites. Let's create an image for the wall try to show that on the screen.

Create a 40x40 block image and save it in res/images/wall.png. Note that in this program, we will place all resources in res directory. You should preload this image to make the game run smoothly. Follow the steps described in Flappy dot to preload this image as a resource.

Let's create a Maze class that keeps the maze information and also displays the maze as a set of sprites.

The key question here is how to keep the maze information. In a simple game with one maze like this, we can simply store the maze as a constant in our code. However, if you have many maze levels, you might want to load the data from files. (We shall discuss that later, hopefully.)

The code below shows Maze class in src/Maze.js. Note that since our screen is of size 800 x 600 and our wall image is of size 40 x 40, we can have 20 x 15 units. In our case, we leave the top row and the bottom row out, so the height of the maze is only 13 units.

var Maze = cc.Node.extend({
    ctor: function() {
        this._super();
        this.WIDTH = 20;
        this.HEIGHT = 13;
        this.MAP = [
            '####################',
            '#..................#',
            '#.###.###..###.###.#',
            '#.#...#......#...#.#',
            '#.#.###.####.###.#.#',
            '#.#.#..........#.#.#',
            '#.....###. ###.....#',
            '#.#.#..........#.#.#',
            '#.#.###.####.###.#.#',
            '#.#...#......#...#.#',
            '#.###.###..###.###.#',
            '#..................#',
            '####################'
        ];

        // ...  code for drawing the maze has be left out

    }
}

Notes: You might wonder why we put the constants here in the object. (We usually place these constants outside as class variables.) Can you guess why?

We will put all sprites (including the pacman and the dots) as the maze's children. The co-ordinate system that we use will be relative to the anchor point of the maze (which will be lower-left corner). The figure below shows the co-ordinate system.

Maze-co-ordinates.png

To draw the maze, we create appropriate sprites on the screen.

	for ( var r = 0; r < this.HEIGHT; r++ ) {
	    for ( var c = 0; c < this.WIDTH; c++ ) {
		if ( this.MAP[ r ][ c ] == '#' ) {
		    var s = cc.Sprite.create( 'res/images/wall.png' );
		    s.setAnchorPoint( cc.p( 0, 0 ) );
		    s.setPosition( cc.p( c * 40, r * 40 ) );
		    this.addChild( s );
		}
	    }
	}

Note that we use function cc.p(...) as a short cut for new cc.Point(...). Also, note how we put anchor points at the lower-left corners of all wall sprites and place all sprites in appropriate locations.

We also put the anchor point for the maze at its lower-left corner as well. (Put this code also in method Maze.ctor.)

	this.setAnchorPoint( cc.p( 0, 0 ) );

To use this Maze in GameLayer we simply create it in GameLayer.init:

	this.maze = new Maze();
	this.maze.setPosition( cc.p( 0, 40 ) );
        this.addChild( this.maze );

We are ready to see our map. Let's load the game.

Gitmark.png Don't forget to commit this nice scene.

Moving the pac-man (blocky movement)

This is the important part of this tutorial. We want our PacMan to move freely in the maze as the user plays the game. The hard part is to make sure the PacMan does not get into the walls while ensuring the player feels that the controlling is smooth.

In our first attempt, we will make the PacMan moves not so freely, but all movements will stop the PacMan at the center of some block. For example, if the user just hits the left arrow key and quickly pulls off, the PacMan still move the whole step. It will not jump, though; it will move smoothly from one block to another. This approach is much easier to write and is not that bad. If you actually play it, the game feels OK, but the movement control clearly can later be improved.

Showing the character

Create a 40x40 pixels image for the PacMan. Save the file as res/images/pacman.png. Don't forget to add this file to the preloaded resource list.

It is easy to show the PacMan. This is the code for Pacman class in Pacman.js. Note that we keeps the current position of the Pacman in the object as well. This initial position is passed to the constructor ctor when the object is created.

var Pacman = cc.Sprite.extend({
    ctor: function( x, y ) {
        this._super();
        this.initWithFile( 'res/images/pacman.png' );
        
        this.x = x;
        this.y = y;
        this.updatePosition();
    },

    updatePosition: function() {
        this.setPosition( cc.p( this.x, this.y ) );
    }
});

Then, you can create it in GameLayer.init:

        this.pacman = new Pacman( 10*40 + 20, 6*40 + 20 );
        this.maze.addChild( this.pacman );

Notes: The pacman is added, as a child, to the maze, so that its position is relative to the maze. We do this because it will be easy to move the whole maze around.

Movements: idea

Movements: code

Eating dots

Showing scores

Adding challenges

Improvements