Browse Source

记忆翻牌

master
jiannibang 6 years ago
parent
commit
11932b1e71
  1. 7
      Game.vue
  2. BIN
      h5/flipper/a.png
  3. BIN
      h5/flipper/b.png
  4. BIN
      h5/flipper/back.png
  5. BIN
      h5/flipper/bg.jpg
  6. BIN
      h5/flipper/c.png
  7. BIN
      h5/flipper/d.png
  8. BIN
      h5/flipper/e.png
  9. BIN
      h5/flipper/f.png
  10. 80
      h5/flipper/flipper.css
  11. BIN
      h5/flipper/font.ttf
  12. BIN
      h5/flipper/g.png
  13. 155
      h5/flipper/game.js
  14. BIN
      h5/flipper/h.png
  15. 1
      phaser.js

7
Game.vue

@ -3,7 +3,8 @@
</template> </template>
<script> <script>
import phaserGames from "./phaser"; import phaserGames from "./phaser";
const games = phaserGames;
import flipper from "./h5/flipper/game";
const games = { ...phaserGames, flipper };
const STATE_RUNNING = 0; const STATE_RUNNING = 0;
const STATE_LOSE = 1; const STATE_LOSE = 1;
const STATE_WON = 2; const STATE_WON = 2;
@ -44,10 +45,8 @@ export default {
}, },
dispose() { dispose() {
this.game.dispose(); this.game.dispose();
this.game.destroy(false);
const container = document.getElementById("gameContainer"); const container = document.getElementById("gameContainer");
const canvas = this.game.canvas;
if (canvas.parentNode === container) container.removeChild(canvas);
container.innerHTML = "";
}, },
reload(name) { reload(name) {
this.game = new games[name]({ this.game = new games[name]({

BIN
h5/flipper/a.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
h5/flipper/b.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
h5/flipper/back.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
h5/flipper/bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 KiB

BIN
h5/flipper/c.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
h5/flipper/d.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
h5/flipper/e.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
h5/flipper/f.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

80
h5/flipper/flipper.css

@ -0,0 +1,80 @@
@font-face {
font-family: "flipper";
src: url("font.ttf") format("truetype");
}
.flipper {
position: relative;
width: 100%;
height: 100%;
background-image: url(./bg.jpg);
background-size: cover;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-auto-rows: 22%;
grid-gap: 1.25%;
padding: 26.48148148148148% 16.34259259259259% 0 16.34259259259259%;
}
.flipper .meta {
position: absolute;
top: 16.6%;
font-family: flipper;
font-weight: bolder;
color: #4294dd;
}
.flipper .meta.l {
left: 33%;
}
.flipper .meta.r {
left: 76%;
}
.flipper.no-event {
pointer-events: none;
}
.flipper .card {
position: relative;
cursor: pointer;
-webkit-perspective: 700px;
perspective: 700px;
width: 100%;
height: 100%;
}
.flipper .card.flipped,
.flipper .card.has-match {
pointer-events: none;
}
.flipper .card.flipped .back,
.flipper .card.has-match .back {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
.flipper .card.flipped .front,
.flipper .card.has-match .front {
-webkit-transform: rotateY(360deg);
transform: rotateY(360deg);
}
.flipper .card .back,
.flipper .card .front {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transition: -webkit-transform 400ms;
transition: transform 400ms;
transition: transform 400ms, -webkit-transform 400ms;
}
.flipper .card .back {
z-index: 1;
background-image: url(./back.png);
background-size: cover;
}
.flipper .card .front {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
background-size: cover;
}

BIN
h5/flipper/font.ttf

Binary file not shown.

BIN
h5/flipper/g.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

155
h5/flipper/game.js

@ -0,0 +1,155 @@
import "./flipper.css";
function importAll(r) {
let obj = {};
r.keys().forEach((key) => {
obj[key.replace("./", "").replace(".png", "")] = r(key);
});
return obj;
}
const images = importAll(require.context("./", false, /\.(png|jpe?g|svg)$/));
const cardNames = "abcdefghabcdefgh";
export default class Game {
duration = 1000;
constructor({ containerId, onLose, onWon }) {
Object.assign(this, {
container: document.getElementById(containerId),
onLose,
onWon,
});
this.addBg();
this.init();
}
init() {
Object.assign(this, {
steps: 25,
score: 0,
});
this.shuffleCards();
this.update();
}
update() {
this.scoreEl.textContent = this.score;
this.stepEl.textContent = this.steps;
}
setSize() {
Object.assign(this, {
width: this.container.clientWidth,
height: this.container.clientHeight,
});
this.scoreEl.style.fontSize = (this.width / 2160) * 100 + "px";
this.scoreEl.style.lineHeight = (this.width / 2160) * 116 + "px";
this.stepEl.style.fontSize = (this.width / 2160) * 100 + "px";
this.stepEl.style.lineHeight = (this.width / 2160) * 116 + "px";
}
addBg() {
this.scoreEl = document.createElement("div");
this.scoreEl.className = "meta l";
this.stepEl = document.createElement("div");
this.stepEl.className = "meta r";
const bg = document.createElement("div");
bg.className = "flipper";
this.cardsContainer = bg;
this.container.appendChild(bg);
this.setSize();
bg.appendChild(this.scoreEl);
bg.appendChild(this.stepEl);
this.resizeListener = window.addEventListener("resize", () => {
this.setSize();
});
this.cards = Array.from(cardNames).map((name) => {
const url = images[name];
const card = document.createElement("div");
card.className = "card";
card.setAttribute("data-name", name);
const front = document.createElement("div");
front.className = "front";
front.style.backgroundImage = `url(${url})`;
card.appendChild(front);
const back = document.createElement("div");
back.className = "back";
card.appendChild(back);
return card;
});
this.cards.forEach((card) => {
this.cardsContainer.appendChild(card);
});
this.cards.forEach((card) => {
card.addEventListener("click", this.flip.bind(this, card));
});
}
pause() {}
resume() {}
restart() {
this.init();
}
dispose() {
window.removeEventListener("resize", this.resizeListener);
}
shuffleCards() {
this.cards.forEach((card) => {
const randomNumber = Math.floor(Math.random() * this.cards.length) + 1;
card.classList.remove("has-match");
card.classList.remove("flipped");
setTimeout(() => {
card.style.order = `${randomNumber}`;
}, 400);
});
}
checkAllCards() {
if (this.cards.every((card) => card.classList.contains("has-match"))) {
this.onWon && this.onWon();
setTimeout(() => {
this.restart();
}, this.duration);
}
}
stopEvent() {
this.cardsContainer.classList.add("no-event");
setTimeout(() => {
this.cardsContainer.classList.remove("no-event");
}, this.duration);
}
checkIfMatched(firstCard, secondCard) {
if (firstCard.dataset.name === secondCard.dataset.name) {
this.score += 20;
firstCard.classList.remove("flipped");
secondCard.classList.remove("flipped");
firstCard.classList.add("has-match");
secondCard.classList.add("has-match");
this.checkAllCards();
} else {
setTimeout(() => {
firstCard.classList.remove("flipped");
secondCard.classList.remove("flipped");
}, this.duration);
}
}
flip(selectedCard) {
this.steps--;
if (this.steps < 0) {
this.onLose && this.onLose();
this.restart();
}
selectedCard.classList.add("flipped");
const flippedCards = this.cards.filter((card) =>
card.classList.contains("flipped")
);
if (flippedCards.length === 2) {
this.stopEvent();
this.checkIfMatched(flippedCards[0], flippedCards[1]);
}
this.update();
}
}

BIN
h5/flipper/h.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

1
phaser.js

@ -23,6 +23,7 @@ const attachMethods = (fn) => (...p) =>
this.scene.keys[key] = undefined; this.scene.keys[key] = undefined;
} }
} }
this.destroy(false);
}, },
}); });
const games = Object.entries({ const games = Object.entries({

Loading…
Cancel
Save