easel.js
by Yazed Jamal
由Yazed Jamal
如何在空闲时间使用Easel.js构建匹配的游戏 (How to build a matching game in your free time with Easel.js)
Part of my journey in the programming world is learning about game development. I have tried several languages such as Java and C++, but in the end I would like to go with Javascript. I have built one game before using JS. The game is called Pong Ping, which is the clone for the game Pong. This game was built purely using native Javascript.
我在编程界的旅程的一部分是学习游戏开发。 我尝试了多种语言,例如Java和C ++,但最后我还是想使用Javascript。 在使用JS之前,我已经构建了一款游戏。 该游戏称为Pong Ping ,它是Pong游戏的副本。 该游戏完全是使用本机Javascript构建的。
But today I would like to build a game based on a Javascript game framework called Easel.js. The game that I am going to build is actually a very simple game: we flip squares over, and if they are the same color, they will disappear. The game will finish when every color is matched. Here’s an example of the game in the video below, but they are using pictures.
但是今天,我想基于称为Easel.js的Javascript游戏框架构建游戏。 我要构建的游戏实际上是一个非常简单的游戏:我们将方块翻转过来,如果它们具有相同的颜色,它们将会消失。 当每种颜色都匹配时,游戏将结束。 这是下面视频中的游戏示例,但他们使用的是图片。
Step 1
第1步
I will create the index.html file and make a reference to the easel.js library. I choose to use CDN (Content Deliver Network) for this purpose. I will also need to make reference to main.js where all my Javascript code will be.
我将创建index.html文件,并引用easyl.js库。 为此,我选择使用CDN(内容传送网络)。 我还需要引用main.js,所有我的Javascript代码都将在其中。
#index.html<!DOCTYPE html><html><head> <title>Pairing Game</title> <script src="https://code.createjs.com/easeljs-0.8.2.min.js"></script><script src="js/main.js"></script></head><body onload="init()"> <canvas id="myCanvas" width="960" height="600"></canvas></body></html>
I need to make sure all the DOM elements are fully loaded before the Javascripts could be executed, so I am using the onload method to bind the Javascript through the function init().
在执行Javascript之前,我需要确保所有DOM元素都已完全加载,因此我正在使用onload方法通过函数init()绑定Javascript。
Step 2
第2步
I will then create the main.js file and setup the easel.js environment.
然后,我将创建main.js文件并设置easyl.js环境。
#js/main.jsvar squarHeight = 200;var squareWidth = 200;
function init() { var stage = new createjs.Stage("myCanvas"); var square = drawSquare();
stage.addChild(square); stage.update();}
Easel is using a Class called Stage as a container to display any element to the canvas defined. Now I will draw a square through the function drawSquare. I will utilize all the available APIs from easel.js
画架正在使用一个称为Stage的类作为容器,以显示所定义画布上的任何元素。 现在,我将通过drawSquare函数绘制一个正方形。 我将利用easyl.js提供的所有可用API
#js/main.jsfunction drawSquare() { var graphics = new createjs.Graphics().setStrokeStyle(5).beginStroke("rgba(20,20,20,1)") graphics.beginFill(randomColor()).rect(5,5,squareWidth,squareHeight); var shape = new createjs.Shape(graphics); return shape;}
function randomColor() { var num1 = Math.floor(Math.random()*255); var num2 = Math.floor(Math.random()*255); var num3 = Math.floor(Math.random()*255); return "rgba("+num1+","+num2+","+num3+",1)"; }
First I will define the stroke size I would like to use. Then I’ll apply the stroke with a specific color, define the color of the square, and create the square. The color of the square is a random color generated from the function randomColor. Below is how it will look in the browser.
首先,我将定义要使用的笔划大小。 然后,我将笔划应用特定的颜色,定义正方形的颜色,然后创建正方形。 正方形的颜色是从函数randomColor生成的随机颜色。 下面是它在浏览器中的外观。
Step 3
第三步
After I have successfully rendered a square with a random color, I need to design how many rows and columns there will be for the squares to fill in. I’ll also need to design the algorithm to render one square in each column and rows
成功绘制具有随机颜色的正方形后,我需要设计要填充的行数和列数。我还需要设计算法以在每一列和每一行中渲染一个正方形
#js/main.js##upated codesvar squarHeight = 200;var squareWidth = 200;var squareGap = 10;var column = 3;var row = 2;
function init() { var stage = new createjs.Stage("myCanvas"); var square;
for(i=0; i < column*row; i++) { square = drawSquare(); square.x = (squareWidth+squareGap)*(i%column); square.y = (squarHeight+squareGap)*Math.floor(i/column); stage.addChild(square); stage.update(); }
}
function drawSquare() { var graphics = new createjs.Graphics().setStrokeStyle(5).beginStroke("rgba(20,20,20,1)") graphics.beginFill(randomColor()).rect(5,5,squarHeight,squareWidth); var shape = new createjs.Shape(graphics); return shape;}
function randomColor() { var num1 = Math.floor(Math.random()*255); var num2 = Math.floor(Math.random()*255); var num3 = Math.floor(Math.random()*255); return "rgba("+num1+","+num2+","+num3+",1)"; }
From the above codes, I will get a rendered HTML something like this:
从上面的代码中,我将得到如下所示的呈现HTML:
There are many ways of implementing the square rendering. We could use looping in a multi-dimensional array, or we could manipulate the square size with some mathematical function. In this case, I’ll use the later. But here is the algorithm if you would like to use the multi-dimensional method:
有多种实现方形渲染的方法。 我们可以在多维数组中使用循环,也可以通过一些数学函数来控制平方大小。 在这种情况下,我将使用后者。 但是,如果您想使用多维方法,则可以使用以下算法:
#alternativevar positionX =0; var positionY = 0;
for(i=0;i<row;i++) { for(j=0;j<column;j++) { square = drawSquare(); square.x = positionX; square.y = positionY; stage.addChild(square); stage.update(); positionX += squareWidth+squareGap; console.log(positionX); } positionX = 0; positionY += squarHeight+squareGap; }
Step 4
第4步
Again, the objective of this game is to match a pair of colors together. So I need to modify the code in order for it to generate groups of colors in pairs. To do that, I will use an if else logic to make sure the two similar colors are used during the square rendering.
同样,该游戏的目标是将一对颜色匹配在一起。 因此,我需要修改代码以使其成对生成颜色组。 为此,我将使用if if逻辑来确保在正方形渲染期间使用两种相似的颜色。
#js/main.jsvar temp;var genOnce = false;
function drawSquare() {var color = randomColor();var graphics = new createjs.Graphics().setStrokeStyle(5).beginStroke("rgba(20,20,20,1)")
if(!genOnce) { graphics.beginFill(color).rect(5,5,squarHeight,squareWidth); temp = color; genOnce = true; }else { graphics.beginFill(temp).rect(5,5,squarHeight,squareWidth); genOnce = false; }
var shape = new createjs.Shape(graphics); return shape;}
This will render a group of squares something like this:
这将使一组正方形如下所示:
Step 5
第5步
Next, I want each of the squares to be rendered in a random position so the pairs are separated from each other. This can be achieved by first creating an array consisting of all indices of the squares, then shuffling the array so the index number is randomly placed.
接下来,我希望每个正方形都在一个随机位置进行渲染,以使两对彼此分离。 这可以通过首先创建一个由平方的所有索引组成的数组,然后对数组进行混洗,以便将索引号随机放置来实现。
#js/main.jsvar squarePlacement = [];
##function to generate array with all the squares indexfunction randomDoubleColor() { for(i=0; i<totalTiles;i++) { squarePlacement.push(i); } squarePlacement = shuffleArray(squarePlacement); return squarePlacement;
}
##function of the array random shufflingfunction shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array;}
Then I’ll need to change how I render the square. Instead of iterating through the length of total squares, I will iterate through the randomly shuffled array.
然后,我需要更改渲染正方形的方式。 我将遍历随机混洗的数组,而不是遍历整个平方的长度。
#js/main.jsfunction init() { var stage = new createjs.Stage("myCanvas"); var square; randomDoubleColor();
for(i=0; i < squarePlacement.length; i++) { square = drawSquare(); square.x = (squareWidth+squareGap)*(squarePlacement[i]%column); square.y = (squarHeight+squareGap)*Math.floor(squarePlacement[i]/column); stage.addChild(square); stage.update(); }
}
This will get me a group of squares like this:
这将使我得到一组这样的正方形:
I can see the effect better if more squares are rendered:
如果渲染更多正方形,我可以更好地看到效果:
Step 6
第6步
My goal is now to create a function that will compare two squares which will be selected subsequently.
我现在的目标是创建一个将两个正方形进行比较的函数,然后再选择两个正方形。
#js/main.jsvar highlight = createjs.Graphics.getRGB(255, 0, 0);var tileChecked;
I will start with defining a variable highlight. This will be used to highlight the first selected squares and a variable tileChecked to store the same square.
我将从定义变量突出显示开始。 这将用于突出显示第一个选定的正方形,并使用一个变量tileChecked来存储相同的正方形。
#js/main.jsfor(i=0; i < squarePlacement.length; i++) { square = drawSquare(); square.x = (squareWidth+squareGap)*(squarePlacement[i]%column); square.y = (squarHeight+squareGap)*Math.floor(squarePlacement[i]/column); stage.addChild(square); square.addEventListener("click", handleOnPress); stage.update(); }
}
I will then create an event listener which will respond to a mouse click and trigger the function defined, handleOnPress. Now I will define the function as follows:
然后,我将创建一个事件侦听器,该事件侦听器将响应鼠标单击并触发定义的函数handleOnPress。 现在,我将定义函数如下:
function handleOnPress(e) { var tile = e.target; if(!!tileChecked === false) { tile.graphics.setStrokeStyle(5).beginStroke(highlight).rect(5, 5, squareWidth, squarHeight); tileChecked = tile; }else { if(tileChecked.graphics._fill.style === tile.graphics._fill.style && tileChecked !== tile) { tileChecked.visible = false; tile.visible = false; }else { console.log("not match"); tileChecked.graphics.setStrokeStyle(5).beginStroke("rgba(20,20,20,1)").rect(5, 5, squareWidth, squarHeight); } tileChecked = null; } stage.update();
}
Basically the function will first check the variable tileChecked. If it is undefined, the selected square will be highlighted. The selected square object will be saved in the variable tileChecked. Otherwise (which I expect to happen on the second click), the color between the current selected square and the one which is stored in the variable tileChecked will be compared.
基本上,该函数将首先检查变量tileChecked。 如果未定义,则所选正方形将突出显示。 所选方形对象将保存在变量tileChecked中。 否则(我希望在第二次单击时发生),将比较当前所选方块和存储在变量tileChecked中的方块之间的颜色。
In this second comparison, if the color is a match, I will make both the squares disappear. If it is not a match, I will remove the highlight and reset the variable tileChecked to undefined.
在第二次比较中,如果颜色匹配,我将使两个正方形都消失。 如果不匹配,我将删除突出显示并将变量tileChecked重置为未定义。
Step 7
步骤7
To create a real puzzle game, all of the colors should not be displayed. I will make the squares covered by grey squares, and when each is clicked, then it will reveal the color. So when it is not a match, the grey square will cover the box again.
要创建一个真正的益智游戏,不应显示所有颜色。 我将使正方形覆盖为灰色正方形,然后单击每个正方形,它将显示颜色。 因此,如果不匹配,则灰色方块将再次覆盖该框。
To make it more playable, I will make sure other squares are not clickable during the comparison. I will also put some delay between when the second color is displayed and when both squares disappear or turn to grey. Some modification needs to be done in order for everything to work properly
为了使其更具可玩性,我将确保在比较期间其他正方形均不可单击。 在显示第二种颜色与两个正方形都消失或变为灰色之间,我还会稍加延迟。 为了使一切正常工作,需要进行一些修改
function init() { var stage = new createjs.Stage("myCanvas"); randomDoubleColor();
for(i=0; i < squarePlacement.length; i++) { var color =randomColor(); console.log(color); var square = drawSquare(color); console.log(square); square["color"] = square.graphics._fill.style; square.graphics._fill.style = "rgb(140, 136, 136)"; square.x = (squareWidth+squareGap)*(squarePlacement[i]%column); square.y = (squareHeight+squareGap)*Math.floor(squarePlacement[i]/column); stage.addChild(square); square.addEventListener("click", handleOnPress); stage.update(); } function handleOnPress(e) { var tile = e.target;
tile.graphics.beginFill(tile.color).rect(5,5,squareHeight,squareWidth); console.log(tile.mouseEnabled); tile.mouseEnabled = false; console.log(tile.mouseEnabled);
if(!!tileChecked === false) { tileChecked = tile; }else {
stage.mouseChildren = false; tile.graphics.beginFill(tile.color).rect(5,5,squareHeight,squareWidth);
setTimeout(function() { console.log("in"); console.log(tile); console.log(tileChecked); if(tileChecked.color === tile.color && tileChecked !== tile) { tileChecked.visible = false; tile.visible = false; }else { console.log("not match"); tile.graphics.beginFill("rgb(140, 136, 136)").rect(5,5,squareHeight,squareWidth); tileChecked.graphics.beginFill("rgb(140, 136, 136)").rect(5,5,squareHeight,squareWidth);
} tile.mouseEnabled = true; tileChecked.mouseEnabled = true; stage.mouseChildren = true; tileChecked = null;
stage.update(); }, 1000); } stage.update();
}
}
function drawSquare(color) { var graphics = new createjs.Graphics().setStrokeStyle(5).beginStroke("rgba(20,20,20,1)")
if(!genOnce) { graphics.beginFill(color).rect(5,5,squareHeight,squareWidth); temp = color; genOnce = true; }else { graphics.beginFill(temp).rect(5,5,squareHeight,squareWidth); genOnce = false; } var shape = new createjs.Shape(graphics); return shape;}
Below is a video of the game in action:
以下是比赛中的视频:
This game can be enhanced further by adding the winning or losing rules, or maybe by adding a timer to record each player’s finishing time. At the moment I will stop development up until this point. The full code can be found on GitHub below, and anybody is free to use it for any other project.
可以通过添加获胜或失败规则,或者可以添加计时器来记录每个玩家的完成时间来进一步增强游戏效果。 此刻,我将停止开发。 完整的代码可以在下面的GitHub上找到,任何人都可以自由地将其用于其他任何项目。
muyaszed/Matching-game-using-Easel.jsContribute to Matching-game-using-Easel.js development by creating an account on GitHub.github.com
muyaszed / Matching-game-using-Easel.js 通过在GitHub上创建一个帐户来促进Matching-game-using-Easel.js的开发。 github.com
Notes: There are probably many ways to implement this feature, but this way 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/matching-game-with-easel-js-free-time-series-cf803c094a9f/
easel.js