Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.


preface

I have been playing a domestic game on Switch recently, called “Land of the Wind”, which I highly recommend to digg friends who like to play games. If you prefer gameplay and innovation to graphics, trust me with my recommendations

After all, this is a developer community, and this article is intended to teach you how to learn game development.

The Land of the Wind is a pixel-inspired action role-playing game (ARPG) set in a world where the human population is decimating and civilization is about to collapse.

There will be about three tutorials in this series

  • Map chapter: Based onimageRoad wall system (GraphicBased)
  • Movement: Characters move relative to the map
  • Interactive: Interact with elements on the map

Will you finish to see the response: P

Map paper

Maps determine the range and area of movement that the player can control in the game, and there are many ways to implement maps in game development. But in both 3D and 2D games, the underlying map system is generally based on 2D graphics. Take, for example, the following scene in The Land of the Wind game

The red brush is the area where the player can move the character. How do we do that? Start by layering the scene map

  • The floor layerThe character is always on the floor
  • Construction layerOverlays each other based on the position of the characters

Because I don’t have the art resources of the Land of the Wind

So I this funeral hall level painter….

Hand-drawn a game map

It’s no different from the original

which

Here we will use the pixi.js engine to build the game system. It is important to note that I want you to understand that this article is about the principle, not necessarily using a specific engine.

The following code allows the player to move the person up, down, left, and right.

<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
<script type="text/javascript">
        // Initialize the PIXI
        const app = new PIXI.Application({
                backgroundColor:0xffffff
        });

        window.onload=function(){
                // Add the render view of the PIXI to the page body
                document.body.appendChild(app.view);

                app.renderer.autoResize = true;
                app.renderer.resize(window.innerWidth, window.innerHeight);

                // Load image resources
                app.loader.
                add('player'.'player.png').
                add('floor'.'floor.jpg').
                load((loader, resources) = > {
                    // Add the image resource to the scene
                    const floor = new PIXI.Sprite(resources.floor.texture);
                    app.stage.addChild(floor);

                    const player = new PIXI.Sprite(resources.player.texture);
                    app.stage.addChild(player);

                    // Set the origin of the player's shape as the center point
                    player.anchor.x = 0.5;
                    player.anchor.y = 0.5;


                    app.ticker.add(() = > {
                        // Frame synchronization event callback
                    });

                    // Press the up, down, left and right keys to move the role
                    window.onkeydown=function (e) {
                            if(e.keyCode==37) {
                                 player.x-=2;
                            }else if(e.keyCode==39){
                                player.x+=2;
                            }

                            if(e.keyCode==38){
                                player.y-=2;
                            }else if(e.keyCode==40){
                                player.y+=2; }}}); }</script>
Copy the code

TADA! Now our characters are moving

Now the movement is not very smooth and cannot respond to the two keys pressing at the same time, so we adjust the code this way

app.ticker.add(() = > {
    var nextX = player.x+moveDelta.x;
    var nextY = player.y+moveDelta.y;

    player.x=nextX;
    player.y=nextY;
});

window.onkeyup=function(e){
    if(e.keyCode==37||e.keyCode==39) {
        moveDelta.x=0;
    }else if(e.keyCode==38||e.keyCode==40){
        moveDelta.y=0; }}window.onkeydown=function (e) {
    if(e.keyCode==37) {
        moveDelta.x=-2;
    }else if(e.keyCode==39){
        moveDelta.x=2;
    }

    if(e.keyCode==38){
        moveDelta.y=-2;
    }else if(e.keyCode==40){
        moveDelta.y=2; }}Copy the code

It’s much smoother, and it’s moving in eight!

Road wall system

There are places a character can go and places he can’t. How does that work? In most games, there are roughly two ways of implementation. The first is based on tiles, which is to divide the map into different grids and use two-dimensional arrays to determine which places are roads and which places are walls. For example, in the following two-dimensional array, 1 represents the wall and 0 represents the road. If you use the same size floor material, you can easily build a road wall system.

roadarea=[
    1.1.1.1.1.1.1.1.1.0.0.0.0.0.0.1.1.0.0.0.0.0.0.1.1.1.1.1.1.1.1.1
]
Copy the code

However, this approach is more suitable for games with fixed tile tiles, and I will write a series of articles on tile game system construction. In this paper, we use graphic-based road wall system. First we need a map of the road wall area. If you look at the picture below, the areas where you can’t walk are shown in red.

I think you get the idea of what we’re going to do!

We just need to predict whether the pixel under the moving target position is red and then stop moving…

Let’s take a look at the code. Note that in order not to be too long, the code posted here is in fragments. Read the comments carefully to understand or compare the source code I provided

// Load the road wall map shown above into the system
add('roadarea'.'roadarea.jpg')

const roadarea = new PIXI.Sprite(resources.roadarea.texture);
app.stage.addChild(roadarea);

// Get the full array of pixels for the wall map
// format [r,g,b,a], so the array length is the width of the wall map x height x4
roadareaPixels = app.renderer.extract.pixels(roadarea);

// Determine whether the pixels in the x and y coordinates are the marking colors of the wall
function isHitWall(x,y){
    var width = 1728;// The width of the road wall map
    var position = (width * y + x) * 4;// Restore the pixel number

    // get the values r,g,b,a
    var r=roadareaPixels[position],g=roadareaPixels[position+1],b=roadareaPixels[position+2],a=roadareaPixels[position+3];
    // The color will be slightly lost after output in JPEG format
    // Check whether the color in x and y coordinates is red
    if(r==255&&g<50) {console.log("hit the wall");
            return true;
    }else{
            return false;
    } 
}

app.ticker.add(() = > {
    var nextX = player.x+moveDelta.x;
    var nextY = player.y+moveDelta.y;

    // Move is allowed only if the target coordinate is not a wall color
    if(! isHitWall(player.x,nextY)){ player.y=nextY; }if(!isHitWall(nextX,player.y)){
        player.x=nextX;
    }
});
Copy the code

Look carefully at the GIF. When it hits a wall, the debug message hits the wall

If you can’t see this part of the code, you can take a closer look at the article # Javascript BadApple Character art Video, which uses the same technique.

Details of the optimization

The x and y we determine now come from the center of the character, and we count the radius of the character. And hide the wall sign. We don’t need to see it.

// app.stage.addChild(roadarea);

// Add the radius of the control character to the determination of the moving target position, which is approximately 45
if(! isHitWall(player.x,nextY+45*moveDelta.y)){
    player.y=nextY;
}

if(! isHitWall(nextX+45*moveDelta.x,player.y)){
    player.x=nextX;
}
Copy the code

That’s the end of this article, and I’ll tell you about it in the next one

  • Movement: Characters move relative to the map

The source code

Github.com/ezshine/web…

If you like da Shuai’s tutorial, please bookmark, like and follow it

  • Billie Billie:A guard old ape
  • Wechat Official Account:A guard old ape