香草 jboss 工具_香草JavaScript中的记忆游戏

news/2024/7/5 2:25:48

香草 jboss 工具

by Marina Ferreira

通过玛丽娜·费雷拉(Marina Ferreira)

香草JavaScript中的记忆游戏 (Memory Game in Vanilla JavaScript)

在30分钟内构建一个记忆游戏,学习JS,CSS和HTML! (Learn JS, CSS and HTML by building a memory game in 30 minutes!)

This tutorial explains some basic HTML5, CSS3 and JavaScript concepts. We will discuss data attribute, positioning, perspective, transitions, flexbox, event handling, timeouts and ternaries. You are not expected to have much prior knowledge in programming. If you know what HTML, CSS and JS are for, it’s more than enough!

本教程介绍了一些基本HTML5,CSS3和JavaScript概念。 我们将讨论数据属性,位置,透视图,过渡,flexbox,事件处理,超时和三元。 您不会在编程方面有很多先验知识。 如果您知道HTML,CSS和JS的用途,那就足够了!

  • ?Demo: Memory Game Project

    演示: 内存游戏项目

档案结构 (File Structure)

Let’s start creating the files in the terminal:

让我们开始在终端中创建文件:

? mkdir memory-game ? cd memory-game ? touch index.html styles.css scripts.js ? mkdir img

HTML (HTML)

The initial template linking both css and js files.

The initial template linking both css and js files.

The game has 12 cards. Each card consists of a container div named .memory-card, which holds two img elements. The first one represents the card front-face and the second its back-face.

The game has 12 cards. Each card consists of a container div named .memory-card , which holds two img elements. The first one represents the card front-face and the second its back-face .

You can download the assets for this project at: Memory Game Repo.

You can download the assets for this project at: Memory Game Repo .

The set of cards will be wrapped in a section container element. The final result:

The set of cards will be wrapped in a section container element. The final result:

CSS (CSS)

We will use a simple but yet very useful reset, applied to all items:

We will use a simple but yet very useful reset, applied to all items:

The box-sizing: border-box property includes padding and border values into element’s total width and height, so we can skip the math.

The box-sizing: border-box property includes padding and border values into element's total width and height, so we can skip the math.

By setting display: flex to the body and margin: auto to the .memory-game container, it will be centered both vertically and horizontally.

By setting display: flex to the body and margin: auto to the .memory-game container, it will be centered both vertically and horizontally.

.memory-game will also be a flex-container. By default, the items are set to shrink in width to fit the container. By setting flex-wrap to wrap, flex-items wrap along multiple lines, accordingly to their size.

.memory-game will also be a flex-container . By default, the items are set to shrink in width to fit the container. By setting flex-wrap to wrap , flex-items wrap along multiple lines, accordingly to their size.

Each card width and height is calculated with calc() CSS function. Let’s make three rows, four card each by setting width to 25% and height to 33.333% minus 10px from margin.

Each card width and height is calculated with calc() CSS function. Let's make three rows, four card each by setting width to 25% and height to 33.333% minus 10px from margin .

To position .memory-card children, let’s add position: relative so we can position the children absolutely, relative to it.

To position .memory-card children, let's add position: relative so we can position the children absolutely, relative to it.

The property position: absolute set to both front-face and back-face, will remove the elements from the original position, and stack them on top of each other.

The property position: absolute set to both front-face and back-face , will remove the elements from the original position, and stack them on top of each other.

The template should be looking like this:

The template should be looking like this:

Let’s also add a click effect. The :active pseudo class will be triggered every time the element gets clicked. It will apply a .2s transition to its size:

Let's also add a click effect. The :active pseudo class will be triggered every time the element gets clicked. It will apply a .2s transition to its size:

Flip Card (Flip Card)

To flip the card when clicked, a class flip is added to the element. For that, let’s select all memory-card elements with document.querySelectorAll. Then loop through them with forEach and attach an event listener. Every time a card gets clicked flipCard function will be fired. The this variable represents the card that was clicked. The function accesses the element’s classList and toggles the flip class:

To flip the card when clicked, a class flip is added to the element. For that, let's select all memory-card elements with document.querySelectorAll . Then loop through them with forEach and attach an event listener. Every time a card gets clicked flipCard function will be fired. The this variable represents the card that was clicked. The function accesses the element's classList and toggles the flip class:

In the CSS the flip class rotates the card 180deg:

In the CSS the flip class rotates the card 180deg:

To produce the 3D flip effect, we will add the perspective property to .memory-game. That property sets how far in the z plane the object is from the user. The lower the value the bigger the perspective effect. For a subtle effect, let’s apply 1000px:

To produce the 3D flip effect, we will add the perspective property to .memory-game . That property sets how far in the z plane the object is from the user. The lower the value the bigger the perspective effect. For a subtle effect, let's apply 1000px :

To the .memory-card elements let’s add transform-style: preserve-3d, to position them in the 3D space created in the parent, instead of flattening it to the z = 0 plane (transform-style).

To the .memory-card elements let's add transform-style: preserve-3d , to position them in the 3D space created in the parent, instead of flattening it to the z = 0 plane ( transform-style ).

Now, a transition has to be applied to the transform property to produce the movement effect:

Now, a transition has to be applied to the transform property to produce the movement effect:

So, we got the card to 3D flip, yay! But why isn’t the card face showing up? Right now, both .front-face and .back-face are stacked up onto each other, because they are absolutely positioned. Every element has a back face, which is a mirror image of its front face. The property backface-visibility defaults to visible, so when we flip the card, what we get is the JS badge back face.

So, we got the card to 3D flip, yay! But why isn't the card face showing up? Right now, both .front-face and .back-face are stacked up onto each other, because they are absolutely positioned. Every element has a back face , which is a mirror image of its front face . The property backface-visibility defaults to visible , so when we flip the card, what we get is the JS badge back face.

To reveal the image underneath it, let’s apply backface-visibility: hidden to .front-face and .back-face.

To reveal the image underneath it, let's apply backface-visibility: hidden to .front-face and .back-face .

If we refresh the page and flip a card, it’s gone!

If we refresh the page and flip a card, it's gone!

Since we’ve hidden both images back face, there is nothing in the other side. So now we have to turn the .front-face 180 degrees:

Since we've hidden both images back face, there is nothing in the other side. So now we have to turn the .front-face 180 degrees:

And now, there’s the desired flip effect!

And now, there's the desired flip effect!

Match card (Match card)

Now that we have flipping cards, let’s handle the matching logic.

Now that we have flipping cards, let's handle the matching logic.

When we click the first card, it needs to wait until another card is flipped. The variables hasFlippedCard and flippedCard will manage the flip state. In case there is no card flipped, hasFlippedCard is set to true and flippedCard is set to the clicked card. Let’s also switch the toggle method to add:

When we click the first card, it needs to wait until another card is flipped. The variables hasFlippedCard and flippedCard will manage the flip state. In case there is no card flipped, hasFlippedCard is set to true and flippedCard is set to the clicked card. Let's also switch the toggle method to add :

So now, when the user clicks the second card, we will fall into the else block in our condition. We will check to see if it’s a match. In order to do that, let’s identify each card.

So now, when the user clicks the second card, we will fall into the else block in our condition. We will check to see if it's a match. In order to do that, let's identify each card.

Whenever we feel like adding extra information to HTML elements, we can make use of data attributes. By using the following syntax: data-*, where, * can be any word, that attribute will be inserted in the element’s dataset property. So, let’s add a data-framework to each card:

Whenever we feel like adding extra information to HTML elements, we can make use of data attributes . By using the following syntax: data-* , where, * can be any word, that attribute will be inserted in the element's dataset property. So, let's add a data-framework to each card:

So now we can check for a match by accessing both cards dataset. Let’s extract the matching logic to its own method checkForMatch() and also set hasFlippedCard back to false. In case of a match, disableCards() is invoked and the event listeners on both cards are detached, to prevent further flipping. Otherwise, unflipCards() will turn both cards back by a 1500ms timeout that removes the .flip class:

So now we can check for a match by accessing both cards dataset. Let's extract the matching logic to its own method checkForMatch() and also set hasFlippedCard back to false. In case of a match, disableCards() is invoked and the event listeners on both cards are detached, to prevent further flipping. Otherwise, unflipCards() will turn both cards back by a 1500ms timeout that removes the .flip class:

Putting all together:

Putting all together:

A more elegant way of writing the matching condition is to use a ternary operator. It’s composed by three blocks. The first block is the condition to be evaluated. The second block is executed if the condition returns true, otherwise the executed block is the third:

A more elegant way of writing the matching condition is to use a ternary operator . It's composed by three blocks. The first block is the condition to be evaluated. The second block is executed if the condition returns true, otherwise the executed block is the third:

Lock Board (Lock Board)

So now that we have the matching logic covered, we need to lock the board. We lock the board to avoid two sets of cards being turned at the same time, otherwise the flipping will fail.

So now that we have the matching logic covered, we need to lock the board. We lock the board to avoid two sets of cards being turned at the same time, otherwise the flipping will fail.

Let’s declare a lockBoard variable. When the player clicks the second card, lockBoard will be set to true and the condition if (lockBoard) return; will prevent any card flipping before the cards are hidden or match:

Let's declare a lockBoard variable. When the player clicks the second card, lockBoard will be set to true and the condition if (lockBoard) return; will prevent any card flipping before the cards are hidden or match:

Same Card Click (Same Card Click)

The is still the case where the player can click twice on the same card. The matching condition would evaluate to true, removing the event listener from that card.

The is still the case where the player can click twice on the same card. The matching condition would evaluate to true, removing the event listener from that card.

To prevent that, let’s check if the current clicked card is equal to the firstCard and return if positive.

To prevent that, let's check if the current clicked card is equal to the firstCard and return if positive.

The firstCard and secondCard variables need to be reset after each round, so let’s extract that to a new method resetBoard(). Let’s place the hasFlippedCard = false; and lockBoard = false there too. The es6 destructuring assignment [var1, var2] = ['value1', 'value2'], allows us to keep the code super short:

The firstCard and secondCard variables need to be reset after each round, so let's extract that to a new method resetBoard() . Let's place the hasFlippedCard = false; and lockBoard = false there too. The es6 destructuring assignment [var1, var2] = ['value1', 'value2'] , allows us to keep the code super short:

The new method will be called both from disableCards() and unflipCards():

The new method will be called both from disableCards() and unflipCards() :

Shuffling (Shuffling)

Our game looks pretty good, but there is no fun if the cards are not shuffled, so let’s take care of that now.

Our game looks pretty good, but there is no fun if the cards are not shuffled, so let's take care of that now.

When display: flex is declared on the container, flex-items are arranged by the following hierarchy: group and source order. Each group is defined by the order property, which holds a positive or negative integer. By default, each flex-item has its order property set to 0, which means they all belong to the same group and will be laid out by source order. If there is more than one group, elements are firstly arranged by ascending group order.

When display: flex is declared on the container, flex-items are arranged by the following hierarchy: group and source order. Each group is defined by the order property, which holds a positive or negative integer. By default, each flex-item has its order property set to 0 , which means they all belong to the same group and will be laid out by source order. If there is more than one group, elements are firstly arranged by ascending group order.

There is 12 cards in the game, so we will iterate through them, generate a random number between 0 and 12 and assign it to the flex-item order property:

There is 12 cards in the game, so we will iterate through them, generate a random number between 0 and 12 and assign it to the flex-item order property:

In order to invoke the shuffle function, let’s make it a Immediately Invoked Function Expression (IIFE), which means it will execute itself right after its declaration. The scripts should look like this:

In order to invoke the shuffle function, let's make it a Immediately Invoked Function Expression (IIFE) , which means it will execute itself right after its declaration. The scripts should look like this:

And that’s all folks!

And that's all folks!

You can also find a video explanation at ? Code Sketch Channel.

You can also find a video explanation at ? C ode Sketch Channel.

References (References)

  • Marina Ferreira — Flexbox Fundamentals

    Marina Ferreira — Flexbox Fundamentals

  • MDN Web Docs — Main Axis

    MDN Web Docs — Main Axis

  • MDN Web Docs — Cross Axis

    MDN Web Docs — Cross Axis

  • MDN Web Docs — calc

    MDN Web Docs — calc

  • MDN Web Docs — perspective

    MDN Web Docs — perspective

  • MDN Web Docs — transform-style

    MDN Web Docs — transform-style

  • MDN Web Docs — backface-visibility

    MDN Web Docs — backface-visibility

  • MDN Web Docs — Using data attributes

    MDN Web Docs — Using data attributes

  • MDN Web Docs — order

    MDN Web Docs — order

  • MDN Web Docs — IIFE

    MDN Web Docs — IIFE

  • MDN Web Docs — ternary operator

    MDN Web Docs — ternary operator

  • MDN Web Docs — destructuring assignment

    MDN Web Docs — destructuring assignment

Originally published at marina-ferreira.github.io.

Originally published at marina-ferreira.github.io .

翻译自: https://www.freecodecamp.org/news/vanilla-javascript-tutorial-build-a-memory-game-in-30-minutes-e542c4447eae/

香草 jboss 工具


http://lihuaxi.xjx100.cn/news/239176.html

相关文章

织梦 新建 php arclist,织梦arclist按照自定义字段来调用相关文章

织梦arclist按照自定义字段来调用相关文章,这对于想要在首页调用某个自定义字段的文章的同学来讲,非常不错,接下来看教程打开 include aglibrclist.lib.php 找到://时间限制(用于调用最近热门文章、热门评论之类),这里…

CES上百度无人车队炫技,陆奇要用“China speed”改变世界

本文由 「AI前线」原创,原文链接:CES上百度无人车队炫技,陆奇要用“China speed”改变世界编辑|EmilyAI 前线导读:“美国当地时间 1 月 8 日,百度在拉斯维加斯举办了主题为“AI is Changing the World, Chi…

卸载linux系统装win,如何在计算机上删除 Linux 并安装 Windows

多个 IDE 驱动器Device Boot Start End Blocks Id System/dev/hda1 * 1 500 4016218 83 Linux native (IDE hard drive 1, partition 1)/dev/hda2 501 522 176715 82 Linux swap (IDE hard drive 1, partition 2)/dev/hdb1 1 500 4016218 83 Linux native (IDE hard drive 2, p…

latex 插图解释_大O符号-只需插图和视频即可解释

latex 插图解释Big O notation is used to communicate how fast an algorithm is. This can be important when evaluating other people’s algorithms, and when evaluating your own! In this article, I’ll explain what Big O notation is and give you a list of the m…

IntelliJ IDEA控制台输出中文乱码问题解决

如果还不行,那么再极端的设置,在IDEA启动的时候强制设置为UTF-8: 打开增加-Dfile.encodingUTF-8,重启Intellij IDEA 再或者直接在项目运行的时候加入UTF-8的设置 如果还是不行,那么你可能装了一个假的IDEA。

[算法] [常微分方程] [欧拉法 改进欧拉法 经典R-K算法]

1 #include<iostream>2 #include<cmath>3 #include<cstdio>4 #include<iomanip>5 using namespace std;6 double h0.1;//步差7 double xi[11]{0};8 double ol_yi[11]{1};9 double gol_yi[11]{1}; 10 double rk_yi[11]{1}; 11 double real_yi[11]{1}; 1…

linux 端口 流量统计,Linux下如何对端口流量进行统计

在不修改源代码的情况下对程序暴露端口流量进行监控统计&#xff0c;可以利用Linux中自带的Iptable添加简单的规则让其起到端口流量统计的作用。但是需要注意的是在服务器重启、Iptable服务重启的时候统计数据会被重置清零。添加需要统计的端口1、输入监控下面示例是监控目标端…