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 on
image
Road 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 layer
The character is always on the floor
- Construction layer
Overlays 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