js画布贪吃蛇转向函数
by Adam Recvlohe
通过亚当·雷夫洛厄(Adam Recvlohe)
I started working in the web development field about 6 months ago after spending most of my career in education. The transition has been great and I am very thankful for the opportunity to work on real-world web applications.
在将大部分职业用于教育之后,大约六个月前,我开始在Web开发领域工作。 过渡非常好,我非常感谢有机会在现实世界的Web应用程序上工作。
I very happy working in the industry but from my perspective, there is still plenty to learn. Therefore, from the day I started as a JavaScript Developer I have continued to spend time studying each evening to level up my skills.
我很高兴在这个行业工作,但是从我的角度来看,还有很多东西要学习。 因此,从我开始担任JavaScript开发人员的那一天起,我一直每天晚上都花时间学习以提高我的技能。
Along with studying, I recently began teaching an ‘Intro to JavaScript Course’ to Tampa Bay teenagers (at The Iron Yard in St.Pete, Florida). This has been a great experience for many reasons. First, it has challenged me to learn more about the intricacies and nuances of the JavaScript language.
在学习的同时,我最近开始为坦帕湾的青少年(在佛罗里达州圣佩特的铁场)教授“ JavaScript入门课程”。 由于许多原因,这是一个很棒的经验。 首先,它挑战了我学习更多关于JavaScript语言的复杂性和细微差别的挑战。
Second, I have gotten a chance to teach again, which is one of my passions. And third, I got to reexamine how I learned to program and how that differs drastically from beginners who aren’t even sure if they like coding and in some cases couldn’t care less about what I have to say.
其次,我有机会再次教书,这是我的爱好之一。 第三,我必须重新审视如何学习编程以及与初学者之间的巨大差异。初学者甚至不确定他们是否喜欢编码,在某些情况下甚至不太在乎我要说些什么。
You see, the curriculum that I originally thought would be great for this class was JavaScript in three ways: JS in the DOM, JS on the server, and functional JS programming.
您会发现,我原本认为适合该课程的课程可以通过三种方式使用JavaScript:DOM中的JS,服务器上的JS和功能性JS编程。
After the first day, and a good talking to from my Teaching Assistants, I realized I was totally off base. These topics may interest me, but certainly don’t entertain a youth who just wants to play add-sponsored games in the browser. I totally reevaluated what I would teach, and in the process began to have fun!
在第一天之后,并与我的助教进行了很好的交谈,我意识到自己完全不在基地了。 这些主题可能会让我感兴趣,但是肯定不会让只想在浏览器中玩附加赞助游戏的年轻人感到不快。 我完全重新评估了我会教的内容,并在此过程中开始玩得开心!
Below is the first lesson I gave to the students where I start out discussing functions and end up creating a smiley face emoji. Enjoy!
下面是我给学生们的第一堂课,在那里我开始讨论功能并最终创建一个笑脸表情符号。 请享用!
If you want to follow along as we talk about functions, open up a browser and go to repl.it and under popular languages choose NodeJS. A REPL (Read Evaluate Print Loop) should open up for you and you can follow along with the code.
如果您想在讨论功能时继续学习,请打开浏览器并转到repl.it,然后在流行语言下选择NodeJS 。 应该为您打开一个REPL(读取评估打印循环),您可以按照代码进行操作。
To understand how we will use HTML5 canvas we have to understand a little bit about functions.
要了解我们将如何使用HTML5 canvas,我们必须了解一些有关功能的知识。
“Functions are self-contained modules of code that accomplish a specific task. Functions usually “take in” data, process it, and “return” a result. Once a function is written, it can be used over and over again.”
“功能是完成特定任务的独立代码模块。 函数通常“获取”数据,对其进行处理并“返回”结果。 编写函数后,就可以反复使用它。”
Now let me give you a few examples of the type of functions we will be dealing with.
现在让我给您一些我们将要处理的函数类型的例子。
We declare a basic function using the JavaScript keyword function.
我们使用JavaScript关键字function声明一个基本函数 。
function sayHelloTo(name) { return ‘Hello ‘ + name;}sayHelloTo(‘Adam’);
This function takes one parameter called name. It is a variable that is passed to the sayHelloTo function. Therefore, when the program executes it will pass in what is provided. In my case it is Adam, so in the console you will see Hello Adam.
此函数采用一个名为name的参数。 它是一个传递给sayHelloTo函数的变量。 因此,程序执行时将传递所提供的内容。 在我的情况下是Adam ,因此在控制台中您会看到Hello Adam 。
We can also create a function using the constructor pattern.
我们还可以使用构造函数模式创建一个函数。
function Person(name) { this.name = name; this.sayHello = function() { return “Hello, my name is “ + this.name; }}var me = new Person(“Adam”);me.sayHello();
The Javascript keyword this refers to the function. What that means is when we pass in a variable like name, just as we did before, we can assign it to the function and any instance of that function. To create an instance we use the JavaScript keyword new. When this new instance of the function is created it also has as its properties a this.name value and a this.sayHello method. When we created the instance of the method we passed in our name: var me = new Person(‘Adam’). When you look at the sayHello method, it uses that name, that is now part of that instance, to create a sentence. If you execute this code in the NodeJS REPL on repl.it you should see it output Hello, my name is Adam.
JavaScript的关键字this指的是功能。 这就是说,当我们像以前那样传入像name这样的变量时,可以将其分配给该函数以及该函数的任何实例。 要创建实例,我们使用JavaScript关键字new 。 创建此函数的新实例时,它还具有this.name值和this.sayHello方法作为其属性。 当我们创建方法的实例时,我们传入了我们的名字: var me = new Person('Adam') 。 当您查看sayHello方法时,它使用该名称 (现在是该实例的一部分)来创建一个句子。 如果在repl.it上的NodeJS REPL中执行此代码,则应该看到它输出Hello,我的名字是Adam 。
Now that we got the boring stuff out the way, let’s draw on some canvas. The way I taught this next section was using codepen.io. What I suggest is if you want to follow along, go to codepen.io, create an account, then create a new pen and you should be set. Be sure to activate you account if you want to save your work.
既然我们已经解决了无聊的事情,那么让我们来画些画布。 下一节的教学方式是使用codepen.io。 我的建议是,如果您想继续学习,请转至codepen.io,创建一个帐户,然后创建一支新笔,然后进行设置。 如果要保存工作,请确保激活您的帐户。
First, we need to create the canvas to be able to draw on it. In your HTML create a canvas tag.
首先,我们需要创建画布以能够在其上进行绘制。 在HTML中创建一个canvas标记。
Now it’s JavaScript from here on!
现在是这里JavaScript!
We need to grab our canvas element from the DOM and declare it as a variable. This will allow us to set its context. We aren’t that skilled with ‘3d’ yet, so we will stick with a ‘2d’ context.
我们需要从DOM中获取canvas元素并将其声明为变量。 这将使我们能够设置其上下文。 我们还不是熟练使用“ 3d”的人,因此我们将坚持使用“ 2d”上下文。
var canvas = document.getElementById(“canvas”);var context = canvas.getContext(“2d”);
We can also give the canvas its width and height properties.
我们还可以为画布赋予其width和height属性。
var canvas = document.getElementById(“canvas”);canvas.width = 800;canvas.height = 800;var context = canvas.getContext(“2d”);
I want to point out here that the canvas is acting exactly like an object. It has properties and methods just like we saw from our constructor function above. Slightly different in how we declared it but functionally it operates very similar. So you see that it has height and width properties as well as a getContext method.
我想在这里指出, 画布的行为完全像一个对象。 它具有属性和方法,就像我们从上面的构造函数中看到的一样。 我们声明它的方式略有不同,但功能上却非常相似。 因此,您将看到它具有height和width属性以及一个getContext方法。
Now let’s put all of that into a function so that you can get somewhat familiar with functional programming.
现在,将所有这些内容都放入函数中,以便您对函数式编程有所了解。
function draw() { var canvas = document.getElementById(“canvas”); canvas.width = 800; canvas.height = 800; var context = canvas.getContext(“2d”);}
Nothing will show up on the screen just yet, we will use the fillRect method to help us with that.
屏幕上什么都不会显示,我们将使用fillRect方法来帮助我们。
function draw() { var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 800; var context = canvas.getContext("2d"); context.fillRect(10,10, 100, 200);}
If you haven’t guessed it, the fillRect method takes four parameters: x coordinate, y coordinate, width, and height. On canvas, the x-axis starts at 0 on the left and to infinity going right. The y-axis starts at 0 from the top and to infinity going down. So when we start at (10, 10) we are placing the imaginary cursor on point (x = 10, y = 10) and going 100 to the right and 200 down from that point.
如果您还没猜到,则fillRect方法采用四个参数:x坐标,y坐标,宽度和高度。 在画布上,x轴从左侧的0开始,向右移动至无穷大。 y轴从顶部开始从0开始,向下一直到无穷大。 因此,当我们从(10,10)开始时,将假想光标放在点(x = 10,y = 10)上,然后向右移动100,从该点向下移动200。
As you may have noticed, it still hasn’t been added to the page yet. Add a simple window.onload function and have it equal our finished draw function.
您可能已经注意到,它仍未添加到页面中。 添加一个简单的window.onload函数,使其等于我们完成的绘制函数。
function draw() { var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 800; var context = canvas.getContext("2d"); context.fillRect(10,10, 100, 200);}window.onload = draw;
You might be wondering why the draw function was executed even though we didn’t execute it with parens ( ). That’s because window.onload is a function. That’s the same as saying:
您可能想知道为什么即使未使用parens ()执行draw函数,也是如此。 那是因为window.onload是一个函数。 就是说:
window.onload = function() {// Do stuff here like what we put in draw();}
That means window.onload executes a function when the window is loaded, so what ends up happening is window.onload with its magical powers puts invisible parens around draw, thus executing it. A lot of magic is involved. But now you know the hocus pocus.
这意味着window.onload在加载窗口时执行一个函数,所以最终发生的事情是window.onload具有神奇的力量,在绘制周围放置了不可见的括号,从而执行了它。 涉及很多魔术。 但是现在您知道了病因。
Let’s add some color for fun! Here we use the fillStyle method for that. It needs to come before fillRect or it won’t show.
让我们添加一些有趣的颜色! 在这里,我们使用fillStyle方法。 它需要在fillRect之前出现,否则将不会显示。
function draw() { var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 800; var context = canvas.getContext("2d"); context.fillStyle = "blue"; context.fillRect(10,10, 100, 200);}window.onload = draw;
Here is a sample of that on codepen:
这是在Codepen上的示例:
That was pretty simple. Let’s draw some other shapes now. Just as we did before we will create a function and instantiate our canvas with a width, height, and context.
那很简单。 现在让我们绘制其他形状。 就像我们之前所做的那样,我们将创建一个函数并使用width , height和context实例化画布。
function triangle() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400;}
So we don’t forget, change the onload function to take the triangle function now.
因此,我们不要忘记,现在将onload函数更改为采用三角形函数。
window.onload = triangle;
Now that we have our canvas, let’s start to draw lines on the canvas to create our triangle.
现在我们有了画布,让我们开始在画布上绘制线条以创建三角形。
function triangle() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400; context.beginPath(); context.moveTo(75, 50);}
Here we are starting our path and moving the cursor to point (x = 75, y = 50).
在这里,我们开始我们的路径并将光标移动到点(x = 75,y = 50)。
Now let’s go to town drawing some lines.
现在让我们去画些线。
function triangle() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400; context.beginPath(); context.moveTo(75, 50); context.lineTo(100, 75); context.lineTo(100, 25); context.stroke();}
This created the first two lines that we needed. To finish it off we go back to where we started.
这创建了我们需要的前两行。 为了完成它,我们回到开始的地方。
function triangle() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400; context.beginPath(); context.moveTo(75, 50); context.lineTo(100, 75); context.lineTo(100, 25); context.lineTo(75, 50); // Back to where we started context.stroke();}
To fill in the triangle we can use the fill method.
要填充三角形,我们可以使用fill方法。
function triangle() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400; context.beginPath(); context.moveTo(75, 50); context.lineTo(100, 75); context.lineTo(100, 25); context.lineTo(75, 50); context.stroke(); context.fill();}
Here is what that looks like in the wild:
这是野外的样子:
We can do the same thing now and easily create a giant pyramid.
我们现在可以做同样的事情,轻松地创建一个巨大的金字塔。
function pyramid() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400;}
Remember to change the onload function to pyramid.
切记将onload函数更改为pyramid。
window.onload = pyramid;
Let’s now move the cursor to where we want it to be.
现在,将光标移动到我们想要的位置。
function pyramid() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 400; canvas.height = 400; context.beginPath(); context.moveTo(200, 0);}
I want my pyramid to take up as much space as possible, so I am starting out at the very top of my canvas and exactly in the middle of the x-axis.
我希望我的金字塔占用尽可能多的空间,因此我从画布的顶部开始,并且恰好在x轴的中间。
Now we can begin drawing our shape and filling it in.
现在我们可以开始绘制形状并将其填充。
context.lineTo(0, 400);context.lineTo(400, 400);context.lineTo(200, 0);context.stroke();context.fillStyle = “orange”;context.fill();
Done! You should now have a nice orange pyramid on your screen because of course you are part the Illuminati. Don’t lie!
做完了! 现在,您应该在屏幕上看到一个漂亮的橙色金字塔,因为您当然是Illuminati的一员。 别说谎
Here is the finished product that you can play with:
这是您可以玩的成品:
Now for what you came for: Emojis!
现在为您而来:表情符号!
Just as we did before we set up our canvas.
就像我们在设置画布之前所做的一样。
function smileyFaceEmoji() { var canvas = document.getElementById(“canvas”); var context = canvas.getContext(“2d”); canvas.width = 500; canvas.height = 500;}
Remember to change onload to this function.
切记将onload更改为此功能。
window.onload = smileyFaceEmoji;
Now let’s draw our face.
现在让我们画脸。
context.beginPath();context.arc(250, 250, 100,0,Math.PI*2, true);context.stroke();
I kind of switched things up here using the arc function. The arc function takes quite a few arguments: x coordinate, y coordinate, radius, starting point in radians, ending point in radians, and whether it is drawn clockwise (we said true). As opposed to how a rectangle is made starting at one point and moving to the next, the point (x = 250, y = 250) is actually the middle of the circle and then extending out 100 pixels.
我有点在这里使用arc函数切换了东西。 弧函数有很多参数:x坐标,y坐标,半径,以弧度表示的起点,以弧度表示的终点以及是否按顺时针方向绘制(我们说是正确的)。 与如何从一个点开始并移动到下一个点来制作矩形不同,该点(x = 250,y = 250)实际上是圆的中间,然后延伸出100个像素。
Cool huh?! Next comes the eyes.
酷吧?! 接下来是眼睛。
context.moveTo(235, 225);context.arc(225, 225, 10, 0, Math.PI*2, true);context.moveTo(285, 225);context.arc(275, 225, 10, 0, Math.PI*2, true);context.stroke();
Then the mouth.
然后的嘴。
context.moveTo(250, 275);context.arc(250, 275, 50, 0, Math.PI, false); // Why is this last value false? Why did you just use Math.PI?context.moveTo(250, 275);context.lineTo(200, 275);context.stroke();
Here is what the finished product looks like:
这是成品的外观:
You did it, you just made a smiley face emoji! Gosh darn it I am proud of you! If you want to take your canvas skills to the next level try out one of the exercises below.
做到了,您刚刚制作了笑脸表情符号! 天哪,我为你感到骄傲! 如果您想将自己的画布技能提高到一个新的水平,请尝试以下练习之一。
In this lesson you learned about functions: how to create functions, execute functions, and use functions to build small programs that draw lines on a canvas. We learned that functions take many forms and can be given properties and methods. I hope you enjoyed this lesson as it was my intention to show you the power of functions without bogging you down with jargon, instead using visual stimuli to bring them to life!
在本课程中,您学习了函数:如何创建函数,执行函数以及使用函数来构建在画布上绘制线条的小程序。 我们了解到函数可以采用多种形式,并且可以赋予其属性和方法。 我希望您喜欢这一课,因为我的目的是向您展示功能的强大功能,而又不让您陷入术语行列,而是使用视觉刺激使它们栩栩如生!
If you want to see all the code for this lesson go to my codepen here.
如果您想查看本课程的所有代码,请在此处转到我的codepen。
翻译自: https://www.freecodecamp.org/news/javascript-functions-af6f9186a553/
js画布贪吃蛇转向函数