当前位置: 首页 > 工具软件 > melonJS > 使用案例 >

dig工具使用_让我们使用MelonJS构建Dig Dug游戏

狄峰
2023-12-01

dig工具使用

by Yazed Jamal

由Yazed Jamal

让我们使用MelonJS构建Dig Dug游戏 (Let’s build the Dig Dug game using MelonJS)

Recently I had the chance to watch Stranger Things Season 2. After watching it, I was very excited to see one of my favorite game during my childhood, “Dig Dug”, featured in the series. At the same time, I was searching for a game that I could build to practice my game development skills. So today I have decided that Dig Dug is the game.

最近,我有机会观看《陌生事物第二季》。看完之后,我很兴奋地看到了我童年时期最喜欢的游戏之一“挖挖”,该游戏是该系列的特色。 同时,我正在寻找可以用来练习游戏开发技能的游戏。 因此,今天我决定把Dig Dug当作游戏。

This Dig Dug version is not a complete version. It is only the basic mechanism of the game, which can be expand to a full working Dig Dug version later on.

此Dig Dug版本不是完整版本。 这只是游戏的基本机制,以后可以扩展到完整的Dig Dug版本。

MelonJS is the chosen framework, not because of any particular reason. I just picked it randomly from the many frameworks out there.

MelonJS是选择的框架,并非出于任何特殊原因。 我只是从那里的许多框架中随机选择了它。

Below are the steps that I will go through for this game development:

以下是我将进行此游戏开发的步骤:

  1. Setting up the framework

    建立框架
  2. Creating the ground

    创造基础
  3. Creating the digger

    创建挖掘者
  4. Creating the Monster

    创造怪物
  5. Creating the collision logic

    创建碰撞逻辑
  6. Adding Head Unit Display

    添加主机显示
  7. Adding sound effects and background music

    添加声音效果和背景音乐
  8. Adding the Intro screen

    添加介绍屏幕
  9. Final adjustment

    最终调整
  10. What’s next

    下一步是什么

第1步-设置框架 (Step 1 — Setting up the framework)

MelonJS recommends using the boilerplate provided by them, to start a game development. First, I need to download the boilerplate from GitHub.

MelonJS建议使用他们提供的样板开始游戏开发。 首先,我需要从GitHub下载样板。

I am going to clone the boilerplate to my local directory of choice:

我将样板克隆到我选择的本地目录中:

#terminalgit clone https://github.com/melonjs/boilerplate.git mylocalfolder

Then I will need to setup my own remote repository for the game by using this guide. It is also advisable to go through their tutorial to familiarize yourself with the usage of the framework.

然后,我将需要使用本指南为游戏设置自己的远程存储库。 建议您阅读他们的教程以熟悉框架的用法。

Next, I will need to download the game assets provided by MelonJS on their tutorial pages. This may be useful if you need some images or tiles and have no time to design and create them. These assets can be downloaded on either of the MelonJS tutorial pages here and here.

接下来,我需要在其教程页面上下载MelonJS提供的游戏资源。 如果您需要一些图像或图块并且没有时间设计和创建它们,这可能会很有用。 这些资产可以在此处此处的任何MelonJS教程页面上下载。

Now I would like to discuss a bit about some important skeleton files provided in the boilerplate. MelonJS is using the Jay Extend inheritance library. So I need also to familiarize myself with the files.

现在,我想讨论一下样板中提供的一些重要骨架文件。 MelonJS正在使用Jay Extend继承库。 因此,我还需要熟悉这些文件。

js/game.js:

js/game.js :

Here is the global namespace of my game which happens to be defined as game (which can be anything I like).

这是我的游戏的全局名称空间,碰巧被定义为game (可以是我喜欢的任何名称)。

From lines 1 to 8, I can define any information I require as an object.

从第1行到第8行,我可以定义我需要作为对象的任何信息。

Then from lines 12 to 25 is where I can setup the resolution of the game, how the screen behaves, and load all the game resources like image and sounds.

然后从第12行到第25行,我可以在其中设置游戏的分辨率,屏幕的行为方式,并加载所有游戏资源,例如图像和声音。

I need to change some details, like the screen resolution and scale method for the game performance on line 14.

我需要更改一些细节,例如第14行的游戏性能的屏幕分辨率和缩放方法。

Lastly, lines 28 to 37 is when the game will run everything.

最后,第28至37行是游戏将运行所有内容的时间。

js/screen/play.js:

js/screen/play.js :

This file will be loaded by game.js which handles the play screen.

该文件将由处理播放屏幕的game.js加载。

From lines 5 to 13, all the execution happens when the game starts. This is where I will specify to render all the game entities later on.

从第5行到第13行,所有执行都在游戏开始时发生。 我将在此处指定稍后渲染所有游戏实体的位置。

But, lines 18 to 21 is where all the entities will be removed. I will be going to edit these two files a lot along the way.

但是,第18至21行是删除所有实体的位置。 在整个过程中,我将大量编辑这两个文件。

So before creating any other object, I need to install all the npm libraries required by running the command below:

因此,在创建任何其他对象之前,我需要通过运行以下命令来安装所需的所有npm库:

#terminalnpm install

and I need to install grunt-cli which is required:

并且我需要安装grunt-cli ,这是必需的:

npm install -g grunt-cli

Finally, to run the game, I can execute the command below and get to the local server to see the game running:

最后,要运行游戏,我可以执行以下命令并转到本地服务器以查看游戏的运行情况:

grunt serve

For now I can only see a black blank screen when the game is running.

现在,我只能在游戏运行时看到黑屏。

第2步-创建地面 (Step 2 — Creating the ground)

After knowing a bit about the boilerplate provided, now is the time to create my first entity, the ground. There are several types of objects that I could build from this framework.

在了解了所提供的样板之后,现在是时候创建我的第一个实体,即地面。 我可以从此框架中构建几种类型的对象。

So because this ground will collide with the digger and the monster in the game, I need to create an Entity object for the ground. The ground is the object where the game takes place and which the digger needs to dig out for the digger to pass through.

因此,由于该地面将与游戏中的挖掘者和怪物碰撞,因此我需要为该地面创建一个Entity对象。 地面是进行游戏的对象,而挖掘者则需要挖掘该对象以使挖掘者能够通过。

Originally, the ground is a small 15 x 15 pixel square drawing which can then be repeatedly rendered on the screen to make a larger area. I could use a software called Tile Map Editor for this purpose, but for this game I will be doing it manually.

最初,地面是一个15 x 15像素的方形小图,然后可以在屏幕上重复渲染以扩大面积。 为此,我可以使用名为Tile Map Editor的软件,但对于本游戏,我将手动进行。

So this is how I do it. First create a file in the js folder called ground.js. Then I will create a new object entity as below:

所以这就是我的方法。 首先在js文件夹中创建一个名为ground.js文件。 然后,我将创建一个新的对象实体,如下所示:

On line 2, I will crate a new object called game.Ground which extends from the Entity object provided by MelonJS.

在第2行上,我将创建一个名为game.Ground的新对象,该对象从MelonJS提供的Entity对象扩展而来。

On the next line, I will initialize the object through the parent object with all required arguments. This object will need x and y values as the location of the object.

在下一行,我将通过带有所有必需参数的父对象初始化该对象。 该对象将需要xy值作为对象的位置。

The width and height is defined on lines 37 and 38.

宽度和高度在第37和38行上定义。

To render something, I can use an image sprite for this purpose. But in this case, I will make use of the draw function from the HTML5 Canvas. This was done in lines 9 to 28. Here I will program to draw a rectangle with polka dots in it. The color of the square and dots will be defined by the variables declared on lines 5 and 6, respectively.

为了渲染某些东西,我可以为此使用图像精灵。 但是在这种情况下,我将使用HTML5 Canvas中的draw函数。 这是在第9到28行中完成的。在这里,我将编写一个绘制有波尔卡圆点的矩形的程序。 正方形和点的颜色将分别由第5行和第6行声明的变量定义。

On lines 30 to 35 is where the object’s update function is. Here I need to set the entity to update itself on line 32 each time the update function is called. And finally return a true value to make sure the entity is redrawn each time the game is updated.

在第30至35行是对象的update功能所在的位置。 在这里,我需要设置实体在每次调用update函数时在第32行进行自身update 。 最后返回一个真值,以确保每次游戏更新时都重新绘制实体。

In the next step, I will need to make a reference to this file on the index.html file on line 40 and:

下一步,我需要在第40行的index.html文件中引用此文件,并且:

register the entity to the pool in game.js on line 33. I will not need the code previously in game.js which registered the game.PlayerEntity because I will create the player entity manually later.

在第33行的game.js中将实体注册到池中。我将不需要先前在game.js中注册game.PlayerEntity的代码,因为稍后将手动创建玩家实体。

Since the ground needs to be drawn quite a few times, it is good for me to create a container for all the ground which will handle all the work. To create a container, I will need to create a new object and extend the container object provided by MelonJS.

由于需要多次绘制地面,因此对所有地面创建一个容器可以处理所有工作,这对我有好处。 要创建一个容器,我将需要创建一个新对象并扩展MelonJS提供的容器对象。

I will name this container game.LevelManager.

我将这个容器game.LevelManager

As before, I will need to initialize the arguments. Define the name of this object, and define the data that will be used to place all the squares on the screen at lines 2 to 21.

和以前一样,我将需要初始化参数。 定义该对象的名称,并定义将用于在屏幕上第2至21行放置所有正方形的数据。

Then I will create a custom function that executes the rendering work based on the data on lines 24 to 37. On line 30 is how I add the square to this container, and after all squares are rendered I need to update the container boundary area in line 36.

然后,我将创建一个自定义函数,该函数基于第24到37行上的数据执行渲染工作。第30行是如何将正方形添加到此容器中,并且在渲染完所有正方形之后,我需要在其中更新容器边界区域第36行。

Finally, I will need to render the container on the play screen, so everything under this container will be rendered as well.

最后,我将需要在播放屏幕上渲染该容器,因此该容器下的所有内容也将被渲染。

Before doing that, I will need to create an instance of the levelManager object at lines 9 to 11 below:

在此之前,我将需要在下面的第9至11行创建一个levelManager对象的实例:

I also need to remember to always make a reference to the new object created in the index.html file.

我还需要记住要始终引用index.html文件中创建的新对象。

Now if i run the server, I should get a view like this:

现在,如果我运行服务器,则应获得如下视图:

第3步-创建挖掘者 (Step 3 — Creating the digger)

First I will need an image sprite for my digger. At first I was going to use the game assets provided by MelonJS, but luckily my son created a pixel image for me to use for the digger:

首先,我需要为挖掘者准备一个图像精灵。 最初,我将使用MelonJS提供的游戏资源,但幸运的是,我的儿子为我创建了一个像素图像供挖掘者使用:

I then need to place this image in the data/img folder of the boilerplate directory. When I run the server now, Grunt will automatically build and append the resource file in build/js folder with the image data above.

然后,我需要将此图像放置在样板目录的data/img文件夹中。 现在运行服务器时,Grunt将自动构建资源文件并将其与上面的图像数据一起附加到build/js文件夹中。

To create the Digger object, I will again need to extend the Entity object.

要创建Digger对象,我将再次需要扩展Entity对象。

I will create a new file called digger.js in the js folder and make the reference in index.html.

我将在js文件夹中创建一个名为digger.js的新文件,并在index.html.进行引用index.html.

In line 3, I load the image from the resource file I made earlier and assign it to a variable. On line 5, I initialize the object with the required arguments and settings. For the digger, I will assign the image with the image defined earlier.

在第3行中,我从之前制作的资源文件中加载图像并将其分配给变量。 在第5行,我使用所需的参数和设置初始化对象。 对于挖掘者,我将为图像分配之前定义的图像。

Next, on line 12, I flip the sprite when it is rendered the first time.

接下来,在第12行,我在第一次渲染精灵时翻转它。

I will also need to make the gravity to 0 in line 13 because this is not a platform game which requires gravity for the character to act properly. In this case, the digger will be floating.

我还需要在第13行中将gravity设为0 ,因为这不是一个平台游戏,游戏需要重力才能使角色正常操作。 在这种情况下,挖掘机将处于浮动状态。

In line 14, the velocity of the digger is initialized so it can be moved later. I define the collision type for this entity for the use of the collision logic later on.

在第14行中,挖掘器的速度已初始化,因此以后可以移动。 我为该实体定义了碰撞类型,以供稍后使用碰撞逻辑。

From lines 17 to 22, I define and manage the sprite animation. The numbers in the array of the addAnimation function are to determine which particular frame in the image is to be used for the animation. The number next to it is to define the speed. Finally, I set up the initial animation to be used when the play screen starts.

从第17到22行,我定义和管理Sprite动画。 addAnimation函数数组中的addAnimation将确定图像中哪个特定的帧用于动画。 旁边的数字是定义速度。 最后,我设置了播放屏幕开始时要使用的初始动画。

Now I will need to define the digger movement. I notice in the original Dig Dug game that each time the digger turns up or down, it will always rotate its character appropriately base on the ground. I need to take note of this to implement it properly in my digger. This will be quite a long section of code.

现在,我将需要定义挖掘机运动。 我在原始的Dig Dug游戏中注意到,每次挖掘者向上或向下转动时,它总是会在地面上适当地旋转其角色。 我需要记下这一点,以便在我的挖掘机中正确实现它。 这将是一长段代码。

I discover that in order for the digger to act properly each time I rotate the sprite, I will need to adjust the boundary of the entity and also the shape of the collision box.

我发现,为了使挖掘器每次旋转精灵时都能正常工作,我将需要调整实体的边界以及碰撞盒的形状。

Initially the digger sprite is 48 x 24 in size. This is because of the picture of the digger firing its weapon. However, during normal movement, I will only need the digger to be 24 x 24 in size.

最初,挖矿精灵的大小为48 x 24。 这是因为挖掘机正在发射武器的图片。 但是,在正常运动期间,我只需要将挖掘器的尺寸设置为24 x 24。

This is handled by changing the collision shape initially to be 24 x 24 and having it transform to 48 x 24 when the digger fires its weapon, at lines 17 to 19 below:

这可以通过以下方式解决:首先将碰撞形状更改为24 x 24,然后在挖掘者开火时将其转换为48 x 24,在下面的第17至19行:

From lines 28 to 33, I define several boolean flags that I will use in the movement function.

从第28行到第33行,我定义了几个将在移动功能中使用的布尔标志。

Starting on line 36 is the digger update function which also contains the digger movement logic based on the keyboard input from lines 40 to 134.

从第36行开始的是digger update功能,该功能还包含基于从第40到134行的键盘输入的digger移动逻辑。

In this logic, I need to consider a lot of things like what happens when the movement key is pressed or released, the last position of the digger before a direction or fire button is pressed and released, and the different state of animation required. It is not a complex function, but the logic is a bit lengthy (although basically straightforward).

在这种逻辑下,我需要考虑很多事情,例如按下或释放移动键时发生的情况,按下和释放方向键或火力按钮之前挖掘器的最后位置以及所需的不同动画状态。 它不是一个复杂的函数,但是逻辑有点冗长(尽管基本上很简单)。

From lines 143 to 283 is the movement function for up, down, left and right.

从线143到283是向上,向下,向左和向右的movement功能。

To render the digger to the screen and make the movement possible, I need to add the digger object to game.world container at line 12 and register the keyboard key from lines 19 to 23 for the movement in play.js below. I will also need to unbind when the game leaves the play screen for other uses if required at lines 30 to 34.

为了将挖掘器呈现到屏幕上并使移动成为可能,我需要在第12 game.world对象添加到game.world容器中,并在下面的play.js中从第19行到第23行注册键盘键以进行移动。 如果在第30至34行需要,我还需要在游戏离开播放屏幕以用于其他用途时取消绑定。

If I run the server now, I can see the digger in action and move him up, down, left and right.

如果现在运行服务器,则可以看到挖掘器的运行情况,并将其上下左右移动。

However, I can see a trailing image when the digger is moving, as well as the line of the MelonJS startup image.

但是,当挖掘器移动时,我可以看到尾随的图像,以及MelonJS启动图像的行。

The trailing image is because of the drawing executed each time the game loop updates. This can be solved by adding a layer of drawing before each time the digger is redrawn at line 12 below:

尾随图像是由于每次游戏循环更新时都会执行绘图。 这可以通过在每次在下面的第12行重新绘制挖掘器之前添加一层工程图来解决:

第4步-创建怪物 (Step 4 — Creating the Monster)

Done with the digger for now, I will create the monsters next. It will be basically the same process for the monsters. I will need to create an object Entity for the monsters, add the monsters to the levelManager container, and finally render it to the screen.

现在已经完成了挖掘工作,接下来我将创建怪物。 对于怪物来说,基本上是相同的过程。 我将需要为怪物创建一个对象Entity ,将怪物添加到levelManager容器中,最后将其呈现到屏幕上。

Below is the object Entity for the monster:

以下是怪物的对象Entity

I will first initialize the object on lines 5 to 9. This time, I will just use a sprite provided by MelonJS from it’s platform game tutorial which I modified to add more frames below.

我将首先在第5到9行上初始化对象。这次,我将仅使用MelonJS从其平台游戏教程中提供的精灵,对其进行了修改,以在下面添加更多帧。

This sprite needs to be in the same folder as the digger sprite:

该精灵必须与diger精灵位于同一文件夹中:

Then I name the object on line 11, define the collision type on line 12, reset the collision square and make it smaller at lines 14 to 15, and set velocity and gravity of the monster at lines 17 to 18. I also define the animation group to be used before setting up the initial animation to be used on lines 20 to 22.

然后,我在第11行上命名该对象,在第12行上定义碰撞类型,在第14到15行上重置碰撞正方形并使它变小,并在第17到18行上设置怪物的速度和重力。我还定义了动画设置要在第20到22行使用的初始动画之前要使用的组。

Next, I define a function for the monster’s movement. It is a very basic movement algorithm manipulating the object’s velocity value X for horizontal movement and Y for vertical movement on lines 26 to 43. Finally, I create the object’s update function which will contain only the body update for now on lines 45 to 52.

接下来,我为怪物的运动定义一个函数。 这是一种非常基本的运动算法,它在第26至43行上操纵对象的速度值X以进行水平移动,并为Y进行垂直运动。最后,我创建对象的update函数,该函数现在仅包含第45至52行上的物体更新。

Before proceeding any further, again I need to always remind myself to make a reference in index.html and a registration in game.js for any new entity object created.

在继续进行任何操作之前,我再次需要始终提醒自己在index.html进行引用,并在game.js对创建的任何新实体对象进行注册。

After creating the object, I will need to update the LevelManager container to include the monster’s data and also the creation function.

创建对象之后,我将需要更新LevelManager容器以包含怪物的数据以及creation函数。

Below is the updated code:

下面是更新的代码:

From lines 21 to 28 is the data for the monster’s location. The function for the monster creation or adding to this container is added on lines 48 to 56. Lastly, to make it appear on the screen, some lines need to be added in play.js.

从第21行到第28行是怪物位置的数据。 在第48至56行中添加了用于创建怪物或将其添加到该容器的功能。最后,要使其出现在屏幕上,需要在play.js添加一些行。

Below is the addition on line 11 which calls the function to create all the monsters:

下面是第11行的添加,它调用了创建所有怪物的函数:

Now if I run the server, I can see two little cute monsters appear on the the specific location on the screen. At the moment they will not move.

现在,如果我运行服务器,则可以看到两个小可爱的怪兽出现在屏幕上的特定位置。 目前他们不会动。

第5部分-创建碰撞逻辑 (Part 5 — Creating the collision logic)

I will start with the digger collision logic with the ground and the monster. In order for the framework to check for any collision on the entity object, I need to include the collision check method in the update function. After that, now I can include the onCollision function which provides the information about the specific objects that are colliding together.

我将从地面与怪物的挖掘机碰撞逻辑开始。 为了使框架检查实体对象上是否存在任何冲突,我需要在update函数中包括冲突检查方法。 之后,现在我可以包含onCollision函数,该函数提供有关碰撞在一起的特定对象的信息。

Below is the updated digger object codes:

以下是更新的挖掘机目标代码:

In line 138, the code check for any collision occurs for this object.

在第138行,此对象的代码检查是否发生任何冲突。

In lines 144 to 166, a function provides a response when the objects collide. When the digger collides with the ground at lines 147 to 150, the specific ground entity will be removed from the levelManager container.

在第144到166行中,函数在对象碰撞时提供响应。 当挖掘器在第147至150行与地面碰撞时,特定的地面实体将从levelManager容器中移除。

However, I don’t want the ground to disappear when the digger is firing its weapon, so I put an exception on line 148.

但是,我不希望在挖掘者发射武器时地面消失,因此我在第148行放了一个例外。

Next is the logic for collision with the monsters. If the digger collides with a monster while firing its weapon, the monster will flicker and be removed. Other than that the digger will flicker, be removed, and the game will reset from lines 151 to 163. Returning true in the collision function will make other objects that collide with the digger solid. In other words, the digger will not pass through another object during collision. For this case, I want it to return false.

接下来是与怪物碰撞的逻辑。 如果挖掘者在射击武器时与怪物发生碰撞,则该怪物会闪烁并被移除。 否则,挖掘机将闪烁,将其移除,然后游戏将从151行恢复到163行。在collision功能中返回true将使与该挖掘机碰撞的其他对象变得牢固。 换句话说,在碰撞过程中,挖掘者将不会穿过另一个物体。 对于这种情况,我希望它返回false。

To finish this up, I will then create the logic for the boundaries. Currently, the digger is allowed to travel off the screen. To do this I will define the maximum distance the digger is allowed to travel on the x and y axis in the object init function at lines 16 to 17 below.

为了完成这一步,我将为边界创建逻辑。 当前,允许挖掘者离开屏幕。 为此,我将在下面的第16至17行的对象初始化函数中定义允许挖掘机在xy轴上移动的最大距离。

Then in the update function, I will set the boundaries by using the built-in clamp method at lines 105–106.

然后,在update功能中,我将在第105-106行使用内置的clamp方法设置边界。

Now for the monsters. After making the collision check on monster, I need to define the collision logic with the ground and also the boundary. This logic must also include some sort of Artificial Intelligence (AI) for the monster to chase the digger.

现在为怪物。 在对怪物进行碰撞检查之后,我需要定义与地面以及边界的碰撞逻辑。 该逻辑还必须包括某种人工智能(AI),以使怪物追逐挖掘者。

The monster will not able to dig the ground, so it will bounce to the direction where the digger is when it hits the ground or boundary. In order for the boundary collision to work, I need to define the maximum distance movement for the monster and set it up. I do not have to define the collision logic with the digger because it is already being handled by the Digger object. I also made the monster move to the right when the game starts.

怪物将无法挖掘地面,因此当撞击地面或边界时,它将反弹至挖掘者所在的方向。 为了使边界碰撞起作用,我需要定义怪物的最大距离运动并进行设置。 我不必使用挖掘器定义碰撞逻辑,因为Digger对象已经在处理它。 游戏开始时,我还使怪物向右移动。

Below is the latest Monster object:

以下是最新的Monster对象:

From lines 138 to 159 is a function I defined that will be executed when the monster collides with the ground in the onCollision function. The logic is to make the monster move toward the digger when it hits the ground.

从第138行到第159行是我定义的函数,当怪物在onCollision函数中与地面碰撞时将执行该函数。 逻辑是当怪物撞到地面时使其朝挖掘者移动。

From lines 76 to 136 I defined a function that represents the monster collision logic with the boundary, which is called in the update function on line 57.

我从第76行到第136行定义了一个函数,该函数代表具有边界的怪物碰撞逻辑,该函数在第57行的update函数中被调用。

Whenever the monster is not hitting the boundary, it will always check the digger’s location and move towards it. Then if the monster hits the boundary, it will turn toward the digger and continue chasing it. I did not come up with the AI algorithm myself — it is a combination from scripts I found on the internet with my own. Also in this function, I am required to access the digger’s object properties like the X and Y position. To gain this access, I need to make some changes on how the digger is rendered to the play screen.

每当怪物没有到达边界时,它将始终检查挖掘者的位置并向其移动。 然后,如果怪物撞到边界,它将转向挖掘者并继续追赶它。 我自己没有提出AI算法-它是我在网上找到的脚本与我自己的脚本的结合。 同样在此函数中,我需要访问挖掘者的对象属性,例如XY位置。 要获得此访问权限,我需要对将挖掘器渲染到播放屏幕的方式进行一些更改。

On line 13 I declare a game property that represents the registered digger from the pool before adding it to the play screen. This property will be used to access the digger properties inside the monster object.

在第13行中,我声明了一个game属性,该属性代表从池中注册的挖掘者,然后将其添加到游戏屏幕。 此属性将用于访问怪物对象内的挖掘者属性。

Finally, I will include the code that will reset the game if all the monsters collided with the digger in firing mode. In other words, if the digger manages to killed all the monsters. This checking will be done in the levelManager container.

最后,我将包含代码,如果所有怪物在发射模式下与挖掘者相撞,它将重置游戏。 换句话说,如果挖掘者设法杀死所有的怪物。 该检查将在levelManager容器中完成。

I will check the array containing all the monsters from lines 60 to 62. If the array is empty, I will reset the game.

我将检查包含第60至62行中所有怪物的数组。如果数组为空,我将重置游戏。

But before that, I must also create a boolean flag at line 56 which will confirm that the monster is already created when I start the game. If not, the game will keep on resetting before the monsters can be created.

但是在此之前,我还必须在第56行创建一个布尔标志,该标志将在我开始游戏时确认已经创建了该怪物。 如果没有,游戏将继续进行重置,然后再创建怪物。

步骤6 —添加主机显示 (Step 6 — Adding Head Unit Display)

First I need to create a font folder in the data directory:

首先,我需要在数据目录中创建一个字体文件夹:

data/fnt

then use the font provided by MelonJS in the game assets downloaded earlier:

然后在之前下载的游戏资源中使用MelonJS提供的字体:

PressStart2P.pngPressStart2P.fnt

and put them in the new folder.

并将它们放在新文件夹中。

Then, I need to add some script in the gruntfile in order for it to generate the resource data for the font below on lines 22 to 28:

然后,我需要在gruntfile中添加一些脚本,以便它为下面的第22至28行的字体生成资源数据:

When I run the server, the font will be in the resource data:

当我运行服务器时,字体将在资源数据中:

By default, the Head Unit Display (HUD) object is already created in the boilerplate. I can access the file in js/entities/HUD.js. I just need to define the font added earlier and create a draw function for it.

默认情况下,已经在样板中创建了主机显示(HUD)对象。 我可以访问js/entities/HUD.js的文件。 我只需要定义先前添加的字体并为其创建draw函数。

Below is the updated code:

下面是更新的代码:

I define and initialize the font on lines 42 to 48, then I create the draw function which will render the game score on the specific location as defined on line 71.

我在第42至48行定义并初始化字体,然后创建draw函数,该函数将在第71行定义的特定位置渲染游戏得分。

Lastly, I will add a high score display and its logic. The logic is just saving and adding up the current score to the highScore property each time game resets. Either the digger kills all the monsters or the digger is killed.

最后,我将添加一个高分显示及其逻辑。 逻辑是每次游戏重置时,将当前分数保存并加到highScore属性中。 挖掘者杀死所有怪物,或者杀死挖掘者。

First I created the highScore property on line 9:

首先,我在第9行创建了highScore属性:

Then, in the onCollision function of the digger I will increase the point each time a monster is killed at line 14 and add up the current points to the high score if the digger is killed at line 26.

然后,在diggeronCollision函数中,每次在第14行杀死一个怪物时,我都会增加分数,如果在第26行杀死了挖掘器,则将当前分数加到最高分。

I will also make a bit of an adjustment to what will happen when the monster hits the fire. I will make the monster stop moving, right after it hits the fire, to avoid any unnecessary collisions afterwards at line 11.

我还将对怪物着火时会发生的情况进行一些调整。 我会让怪物在着火后立即停止移动,以免之后在第11行发生任何不必要的碰撞。

第7步-添加声音效果和背景音乐 (Step 7 — Adding sound effects and background music)

Setting this up is a breeze. All the required code is already there in the boilerplate. What I’ll need to do is put the required music or sound file to the relevant folder and do something with the music.

进行设置很容易。 所有必需的代码已经在样板中。 我需要做的是将所需的音乐或声音文件放入相关文件夹,并对音乐进行处理。

Based on the original game when the digger moves, the background music will be played. A simple logic needs to be implemented so the background music will not try to start repeatedly when a direction key is pressed.

根据挖掘者移动时的原始游戏,将播放背景音乐。 需要实现一个简单的逻辑,以便在按下方向键时背景音乐不会尝试重复开始。

Below is the digger updated object:

以下是挖掘者更新的对象:

On line 37 I create a boolean flag to be used in the movement and background music logic.

在第37行,我创建了一个布尔标志,用于运动和背景音乐逻辑。

On lines 45 to 47 is the logic so that the background music doesn’t repeatedly start if a direction key is pressed continuously.

第45至47行是逻辑,因此如果连续按下方向键,背景音乐不会重复开始。

Respectively on lines 114, 200, 224, 249 and 288, the flag is set in order for the logic to work properly.

分别在线114、200、224、249和288上设置标志,以使逻辑正常工作。

The background music was made to stop when the digger stops at line 115.

当挖掘机在第115行停止时,背景音乐就停止了。

As for the other sounds, I also add a sound for the digger in firing mode and a pop sound when the monster dies. In line 69 I activate the sound when fire key is pressed, and stop it when the the fire key is released in line 140. The pop sound will be activated when the monster collides with the digger during firing mode just after it is removed from the screen in line 174.

至于其他声音,我还在射击模式下为挖掘者添加声音,在怪物死亡时添加爆破声。 在第69行中,我按下火键时激活了声音,而在第140行中释放了火键时,它停止了声音。当怪物从射击模式中移开后,在射击模式下怪物与挖掘机碰撞时,将激活弹出声。屏幕在第174行。

步骤8 —添加“简介”屏幕 (Step 8 — Adding the Intro screen)

First, I will open game.js and modify one piece of code. Instead of changing the game state to PLAY, I will change the state to MENU in line 40.

首先,我将打开game.js并修改一段代码。 而不是将游戏状态更改为“ PLAY”,我将在第40行中将状态更改为“ MENU”。

This will load the title.js file when the game is loaded:

加载游戏后,将加载title.js文件:

Next I will edit the file title.js in js/screens folder:

接下来,我将在js/screens文件夹中编辑title.js文件:

Here, in the onResetEvent I play the background music when the screen appears in line 8.

在这里,当屏幕出现在第8 onResetEvent ,在onResetEvent我播放背景音乐。

Next, I cover the viewport with brown colored layer at line 10.

接下来,在第10行,用棕色图层覆盖视口。

Then, I create a Renderable object which contains the title and some wordings from line 13 to 43.

然后,我创建一个Renderable对象,其中包含标题和第13至43行的一些措辞。

This Renderable object will be scrolled upwards from outside to the middle of the screen using Tween at lines 22 to 23.

使用Tween在第22至23行,此可Renderable对象将从屏幕外部向外滚动到屏幕中间。

Finally I will need to bind the ENTER key to trigger an event which will start the game at lines 47 to 57.

最后,我将需要绑定ENTER键来触发一个事件,该事件将在第47至57行开始游戏。

第9步-最终调整 (Step 9 — Final adjustment)

I will not do much for the final adjustment. I will just add another background sound to the monster and I will position the digger similarly to the original game. First I will add another Tween for the digger to move to the center of the screen when the game starts.

我不会为最终调整做太多事情。 我将向怪物添加另一个背景声音,并且将挖掘器的位置与原始游戏类似。 首先,当游戏开始时,我将为挖掘者添加另一个Tween ,以将其移动到屏幕中央。

I will include the new sound file to the right folder then I will update the digger file.

我将新的声音文件包含在正确的文件夹中,然后更新digger文件。

I will declare a few more boolean flags to be used in lines 38 to 40, play the background music at the beginning of the game in line 30, and execute the initial digger movement by calling the defined function in line 29.

我将在第38至40行中声明一些布尔值标志,在第30行的游戏开始时播放背景音乐,并通过在第29行调用定义的函数来执行初始挖掘者运动。

Below is the new function:

以下是新功能:

From line 4, I will define the Tween animation with a callback function which stops the background music, sets some flags for the logic, and moves the binding key registration here from the play.js to avoid any additional movement by any key press during the tweening.

从第4行开始,我将使用回调函数定义Tween动画,该函数将停止背景音乐,为逻辑设置一些标志,并将绑定键注册从play.js移至此处,以避免在播放过程中通过任何按键进行任何其他移动。补间。

Finally, below is the function to create the monster sound every 5 seconds. This function will be called in the update function of the digger object.

最后,下面是每5秒创建一次怪兽声音的功能。 该函数将在digger对象的update函数中调用。

步骤10 –下一步 (Step 10 — What’s next)

Below are the items I could continue to develop for this game:

以下是我可以继续为该游戏开发的物品:

  1. Create the ghost version of the monster that goes through ground.

    创建穿过地面的怪物的幻影版本。
  2. Create a second and next level for the game.

    为游戏创建第二个和下一个级别。
  3. Create additional items where digger could gain more points.

    创建其他项目,使挖掘者可以获得更多积分。
  4. Create a local database with cookies where the game will remember the player’s high score.

    用cookie创建一个本地数据库,游戏将在其中记住玩家的高分。
  5. Refactor, refactor and refactor.

    重构,重构和重构。
  6. Improve the game performance.

    改善游戏性能。

Thank you for reading until this end. If you have any more suggestion on the above list, feel free to comment on this post below.

感谢您的阅读,直到此为止。 如果您在上面的列表中还有其他建议,请在下面的这篇文章中发表评论。

The full code can be pulled from GitHub.

完整的代码可以从GitHub提取。

Feel free to try the demo of the game.

随意尝试游戏演示

Notes: There are probably many ways to implement this feature, but this was easiest for me. Anybody is free to comment on any mistakes or improvements that I can apply. This guide is initially for me to learn and remember what I have done. Nonetheless anybody is welcome to follow this guide if you find it is helpful.

注意 :可能有很多方法可以实现此功能,但这对我来说是最简单的。 任何人都可以对我可以应用的任何错误或改进发表评论。 本指南最初供我学习和记住我所做的事情。 但是,如果发现有帮助,欢迎任何人遵循本指南。

翻译自: https://www.freecodecamp.org/news/lets-build-the-dig-dug-game-using-melonjs-5fc0c9fd7132/

dig工具使用

 类似资料: