Build the brick field - Game development 编辑

This is the 9th step out of 16 of the Gamedev Phaser tutorial. You can find the source code as it should look after completing this lesson at Gamedev-Phaser-Content-Kit/demos/lesson09.html.

Building the brick field is a little bit more complicated than adding a single object to the screen, although It's still easier with Phaser than in pure JavaScript. Let's explore how to create a group of bricks and print them on screen using a loop.

Defining new variables

First, let's define the needed variables — add the following below your previous variable definitions:

var bricks;
var newBrick;
var brickInfo;

The bricks variable will be used to create a group, newBrick will be a new object added to the group on every iteration of the loop, and brickInfo will store all the data we need.

Rendering the brick image

Next, let's load the image of the brick — add the following load.image() call just below the others:

function preload() {
    // ...
    game.load.image('brick', 'img/brick.png');
}

You also need to grab the brick image from Github and save it in your /img directory.

Drawing the bricks

We will place all the code for drawing the bricks inside an initBricks function to keep it separated from the rest of the code. Add a call to initBricks at the end of the create() function:

function create(){
    // ...
    initBricks();
}

Now onto the function itself. Add the initBricks() function at the end of our games code, just before the closing </script> tag, as shown below. To begin with we've included the  brickInfo object, as this will come in handy very soon:

function initBricks() {
    brickInfo = {
        width: 50,
        height: 20,
        count: {
            row: 3,
            col: 7
        },
        offset: {
            top: 50,
            left: 60
        },
        padding: 10
    };
}

This brickInfo object will hold all the information we need: the width and height of a single brick, the number of rows and columns of bricks we will see on screen, the top and left offset (the location on the canvas where we shall start to draw the bricks) and the padding between each row and column of bricks.

Now, let's start creating the bricks themselves — add an empty group first to contain the bricks, by adding the following line at the bottom of the initBricks() function:

bricks = game.add.group();

We can loop through the rows and columns to create new brick on each iteration — add the following nested loop below the previous line of code:

for(c=0; c<brickInfo.count.col; c++) {
    for(r=0; r<brickInfo.count.row; r++) {
        // create new brick and add it to the group
    }
}

This way we will create the exact number of bricks we need and have them all contained in a group. Now we need to add some code inside the nested loop stucture to draw each brick. Fill in the contents as shown below:

for(c=0; c<brickInfo.count.col; c++) {
    for(r=0; r<brickInfo.count.row; r++) {
        var brickX = 0;
        var brickY = 0;
        newBrick = game.add.sprite(brickX, brickY, 'brick');
        game.physics.enable(newBrick, Phaser.Physics.ARCADE);
        newBrick.body.immovable = true;
        newBrick.anchor.set(0.5);
        bricks.add(newBrick);
    }
}

Here we're looping through the rows and columns to create the new bricks and place them on the screen. The newly created brick is enabled for the Arcade physics engine, it's body is set to be immovable (so it won't move when hit by the ball), and we're also setting the anchor to be in the middle and adding the brick to the group.

The problem currently is that we're painting all the bricks in one place, at coordinates (0,0). What we need to do is draw each brick at its own x and y position. Update the brickX and brickY lines as follows:

var brickX = (c*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
var brickY = (r*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;

Each brickX position is worked out as brickInfo.width plus brickInfo.padding, multiplied by the column number, c, plus the brickInfo.offset.left; the logic for the brickY is identical except that it uses the values for row number, r, brickInfo.height, and brickInfo.offset.top. Now every single brick can be placed in its correct place, with padding between each brick, and drawn at an offset from the left and top Canvas edges.

Checking the initBricks() code

Here is the complete code for the initBricks() function:

function initBricks() {
    brickInfo = {
        width: 50,
        height: 20,
        count: {
            row: 3,
            col: 7
        },
        offset: {
            top: 50,
            left: 60
        },
        padding: 10
    }
    bricks = game.add.group();
    for(c=0; c<brickInfo.count.col; c++) {
        for(r=0; r<brickInfo.count.row; r++) {
            var brickX = (c*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
            var brickY = (r*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
            newBrick = game.add.sprite(brickX, brickY, 'brick');
            game.physics.enable(newBrick, Phaser.Physics.ARCADE);
            newBrick.body.immovable = true;
            newBrick.anchor.set(0.5);
            bricks.add(newBrick);
        }
    }
}

If you reload index.html at this point, you should see the bricks printed on screen, at an even distance from one another.

Compare your code

You can check the finished code for this lesson in the live demo below, and play with it to understand better how it works:

Next steps

Something is missing though. The ball goes through the bricks without stopping — we need proper collision detection.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:76 次

字数:8508

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文