记忆游戏在获胜后不会重启

时间:2017-11-13 16:27:06

标签: javascript jquery

我正试图重塑由Nate Wiley开发的这款酷记忆游戏。

我遇到了问题。当你获胜时,它允许你重新启动,但当卡片再次出现时游戏变得无法播放。

重启按钮代码调用此函数:

reset: function(){
    this.hideModal();
    this.shuffleCards(this.cardsArray);
    this.setup();
    this.$game.show();
},

这会正确隐藏模态,随机播放卡片,运行设置功能,然后再次显示游戏。

Setup Function如下所示:

setup: function(){
    this.html = this.buildHTML();
    this.$game.html(this.html);
    this.$memoryCards = $(".card");
    this.paused = false;
    this.guess = null;
},

我在控制台中没有收到任何错误。在这种情况下,我该如何诊断错误?

我创建了一个只有2对匹配的codepen,以便更快地进行测试,但我对如何解决这个问题感到茫然。

https://codepen.io/nolaandy/pen/wPeGgo

2 个答案:

答案 0 :(得分:3)

<强> Udpated Codepen

您需要做的就是使用事件委派on绑定点击事件,例如:

$('body').on("click", ".card", this.cardClicked);

而不是:

this.$memoryCards.on("click", this.cardClicked);

因此,当您从reset()函数动态重置卡片时,点击事件将会持续存在并可以处理新的card元素。

希望得到这个帮助。

答案 1 :(得分:3)

当您在控制台中没有错误时,您需要考虑您希望代码执行什么以及从那里开始工作。在你的例子中,当我点击卡片时,我希望游戏能够做某些事情,但事实并非如此,所以我在点击处理程序中添加了console.log(),我注意到没有记录任何内容在控制台中,所以我虽然&#34;可能卡片元素从头开始重建,所以它失去了它的事件监听器&#34;,所以我尝试将事件委托给身体,用

$('body').on("click", ".card", this.cardClicked);

我注意到现在点击事件有效,所以我知道我到了某个地方。我仍然希望保持点击代码的方式,所以我注意到在setup函数中他没有调用binding函数,这是将点击事件附加到元素的函数,所以我试着在设置功能中调用this.binding();,确定它有效。

PS:在我看来,在setup()函数中调用buinding()函数是有意义的,因为我可能希望每次设置游戏时都将我的点击事件附加到按钮上,但我保留了这就是让代码尽可能与原始代码保持相似的方式。

&#13;
&#13;
// Memory Game
// © 2014 Nate Wiley
// License -- MIT
// best in full screen, works on phones/tablets (min height for game is 500px..) enjoy ;)
// Follow me on Codepen

(function(){
	
	var Memory = {

		init: function(cards){
			this.$game = $(".game");
			this.$modal = $(".modal");
			this.$overlay = $(".modal-overlay");
			this.$restartButton = $("button.restart");
			this.cardsArray = $.merge(cards, cards);
			this.shuffleCards(this.cardsArray);
			this.setup();
			this.binding();
		},

		shuffleCards: function(cardsArray){
			this.$cards = $(this.shuffle(this.cardsArray));
		},

		setup: function(){
			this.html = this.buildHTML();
			this.$game.html(this.html);
			this.$memoryCards = $(".card");
			this.binding();
			this.paused = false;
     	this.guess = null;
		},

		binding: function(){
			this.$memoryCards.on("click", this.cardClicked);
			$("button.restart").unbind().click( $.proxy(this.reset, this));
		},
		// kinda messy but hey
		cardClicked: function(){
			var _ = Memory;
			var $card = $(this);
			if(!_.paused && !$card.find(".inside").hasClass("matched") && !$card.find(".inside").hasClass("picked")){
				$card.find(".inside").addClass("picked");
				if(!_.guess){
					_.guess = $(this).attr("data-id");
				} else if(_.guess == $(this).attr("data-id") && !$(this).hasClass("picked")){
					$(".picked").addClass("matched");
					_.guess = null;
				} else {
					_.guess = null;
					_.paused = true;
					setTimeout(function(){
						$(".picked").removeClass("picked");
						Memory.paused = false;
					}, 600);
				}
				if($(".matched").length == $(".card").length){
					_.win();
				}
			}
		},

		win: function(){
			this.paused = true;
			setTimeout(function(){
				Memory.showModal();
				Memory.$game.fadeOut();
			}, 1000);
		},

		showModal: function(){
			this.$overlay.show();
			this.$modal.fadeIn("slow");
		},

		hideModal: function(){
			this.$overlay.hide();
			this.$modal.hide();
		},

		reset: function(){
			this.hideModal();
			this.shuffleCards(this.cardsArray);
			this.setup();
			this.$game.show();
		},
 
		// Fisher--Yates Algorithm -- https://bost.ocks.org/mike/shuffle/
		shuffle: function(array){
			var counter = array.length, temp, index;
	   	// While there are elements in the array
	   	while (counter > 0) {
        	// Pick a random index
        	index = Math.floor(Math.random() * counter);
        	// Decrease counter by 1
        	counter--;
        	// And swap the last element with it
        	temp = array[counter];
        	array[counter] = array[index];
        	array[index] = temp;
	    	}
	    	return array;
		},

		buildHTML: function(){
			var frag = '';
			this.$cards.each(function(k, v){
				frag += '<div class="card" data-id="'+ v.id +'"><div class="inside">\
				<div class="front"><img src="'+ v.img +'"\
				alt="'+ v.name +'" /></div>\
				<div class="back"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/codepen-logo.png"\
				alt="Codepen" /></div></div>\
				</div>';
			});
			return frag;
		}
	};

	var cards = [
		{
			name: "php",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/php-logo_1.png",
			id: 1,
		},
		{
			name: "css3",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/css3-logo.png",
			id: 2
		},
	];
    
	Memory.init(cards);


})();
&#13;
* {
  box-sizing: border-box;
}
html, body {
  height: 100%;
}
body {
  background: black;
  min-height: 100%;
  font-family: "Arial", sans-serif;
}
.wrap {
  position: relative;
  height: 100%;
  min-height: 500px;
  padding-bottom: 20px;
}
.game {
  transform-style: preserve-3d;
  perspective: 500px;
  min-height: 100%;
  height: 100%;
}
@keyframes matchAnim {
  0% {
    background: #bcffcc;
  }
  100% {
    background: white;
  }
}
.card {
  float: left;
  width: 16.66666%;
  height: 25%;
  padding: 5px;
  text-align: center;
  display: block;
  perspective: 500px;
  position: relative;
  cursor: pointer;
  z-index: 50;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
@media (max-width: 800px) {
  .card {
    width: 25%;
    height: 16.666%;
  }
}
.card .inside {
  width: 100%;
  height: 100%;
  display: block;
  transform-style: preserve-3d;
  transition: 0.4s ease-in-out;
  background: white;
}
.card .inside.picked, .card .inside.matched {
  transform: rotateY(180deg);
}
.card .inside.matched {
  animation: 1s matchAnim ease-in-out;
  animation-delay: 0.4s;
}
.card .front, .card .back {
  border: 1px solid black;
  backface-visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 20px;
}
.card .front img, .card .back img {
  max-width: 100%;
  display: block;
  margin: 0 auto;
  max-height: 100%;
}
.card .front {
  transform: rotateY(-180deg);
}
@media (max-width: 800px) {
  .card .front {
    padding: 5px;
  }
}
.card .back {
  transform: rotateX(0);
}
@media (max-width: 800px) {
  .card .back {
    padding: 10px;
  }
}
.modal-overlay {
  display: none;
  background: rgba(0, 0, 0, .8);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.modal {
  display: none;
  position: relative;
  width: 500px;
  height: 400px;
  max-height: 90%;
  max-width: 90%;
  min-height: 380px;
  margin: 0 auto;
  background: white;
  top: 50%;
  transform: translateY(-50%);
  padding: 30px 10px;
}
.modal .winner {
  font-size: 80px;
  text-align: center;
  font-family: "Anton", sans-serif;
  color: #4d4d4d;
  text-shadow: 0px 3px 0 black;
}
@media (max-width: 480px) {
  .modal .winner {
    font-size: 60px;
  }
}
.modal .restart {
  font-family: "Anton", sans-serif;
  margin: 30px auto;
  padding: 20px 30px;
  display: block;
  font-size: 30px;
  border: none;
  background: #4d4d4d;
  background: linear-gradient(#4d4d4d, #222);
  border: 1px solid #222;
  border-radius: 5px;
  color: white;
  text-shadow: 0px 1px 0 black;
  cursor: pointer;
}
.modal .restart:hover {
  background: linear-gradient(#222, black);
}
.modal .message {
  text-align: center;
}
.modal .message a {
  text-decoration: none;
  color: #28afe6;
  font-weight: bold;
}
.modal .message a:hover {
  color: #56c0eb;
  border-bottom: 1px dotted #56c0eb;
}
.modal .share-text {
  text-align: center;
  margin: 10px auto;
}
.modal .social {
  margin: 20px auto;
  text-align: center;
}
.modal .social li {
  display: inline-block;
  height: 50px;
  width: 50px;
  margin-right: 10px;
}
.modal .social li:last-child {
  margin-right: 0;
}
.modal .social li a {
  display: block;
  line-height: 50px;
  font-size: 20px;
  color: white;
  text-decoration: none;
  border-radius: 5px;
}
.modal .social li a.facebook {
  background: #3b5998;
}
.modal .social li a.facebook:hover {
  background: #4c70ba;
}
.modal .social li a.google {
  background: #d34836;
}
.modal .social li a.google:hover {
  background: #dc6e60;
}
.modal .social li a.twitter {
  background: #4099ff;
}
.modal .social li a.twitter:hover {
  background: #73b4ff;
}
footer {
  height: 20px;
  position: absolute;
  bottom: 0;
  width: 100%;
  z-index: 0;
}
footer .disclaimer {
  line-height: 20px;
  font-size: 12px;
  color: #727272;
  text-align: center;
}
@media (max-width: 767px) {
  footer .disclaimer {
    font-size: 8px;
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="game"></div>
	
	<div class="modal-overlay">
		<div class="modal">
			<h2 class="winner">You Rock!</h2>
			<button class="restart">Play Again?</button>
			<p class="message">Developed on <a href="https://codepen.io">CodePen</a> by <a href="https://codepen.io/natewiley">Nate Wiley</a></p>
			<p class="share-text">Share it?</p>
			<ul class="social">
				<li><a target="_blank" class="twitter" href="https://twitter.com/share?url=https://codepen.io/natewiley/pen/HBrbL"><span class="fa fa-twitter"></span></a></li>
				<li><a target="_blank" class="facebook" href="https://www.facebook.com/sharer.php?u=https://codepen.io/natewiley/pen/HBrbL"><span class="fa fa-facebook"></span></a></li>
				<li><a target="_blank" class="google" href="https://plus.google.com/share?url=https://codepen.io/natewiley/pen/HBrbL"><span class="fa fa-google"></span></a></li>
			</ul>
		</div>
	</div>
  <footer>
		<p class="disclaimer">All logos are property of their respective owners, No Copyright infringement intended.</p>
	</footer>
  </div><!-- End Wrap -->
&#13;
&#13;
&#13;