Tự Code một Game lật hình giống nhau

4

Tôi tự hỏi không biết trước kia bạn đã từng chơi Game Pikachu chưa. Cái thủa mà internet không được phổ biến rộng rãi như bây giờ. Lúc đó tôi mới sắm được một PC chạy chip intel celeron. Nhà thì làm gì có mạng và Pikachu là một trong những tựa Game tôi thích nhất lúc bấy giờ. Về cơ bản thì trong máy tính của tôi lúc đó chỉ có vài Game dạng như thế  :mrgreen: Tự Code - Tự Code một Game lật hình giống nhau

Tự Code một Game lật hình giống nhau Tự Code - Tự Code một Game lật hình giống nhau
Tự Code một Game lật hình giống nhau

Và hôm nay chúng ta sẽ trở về quá khứ bằng việc tạo ra một ứng dụng web từ những dòng Code. Cụ thể, chúng ta sẽ tự code một game lật hình mà bạn có thể dễ dàng áp dụng trên website của mình để người dùng có chỗ giải trí nếu bạn muốn. Sau khi người chơi chiến thắng họ có thể chơi lại hoặc chia sẻ lên mạng xã hội.

Đầu tiên chúng ta sẽ cần những dòng Code bên dưới.

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet prefetch' href='http://fonts.googleapis.com/css?family=Anton'>

Bạn lưu ý thẻ viewport được sử dụng bên trên là để gán Responsive trên các thiết bị di động.

Và bạn cũng cần gọi thư viện jquery về bằng Link sau:

<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>

Và đây là HTML Code:

<div class="wrap">
<div class="game"></div>
	
	<div class="modal-overlay">
		<div class="modal">
			<h2 class="winner">Thắng Rồi</h2>
			<button class="restart">Chơi Lại</button>
			<p class="message">Developed on <a href="http://www.laivanduc.com/">Lại Văn Đức</a> Chi tiết tại <a href=" http://www.laivanduc.com/chia-se-code/javascript/tu-code-mot-game-lat-hinh-giong-nhau.html">www.laivanduc.com</a></p>
			<p class="share-text">Chia sẻ chiến thắng</p>
			<ul class="social">
				<li><a target="_blank" class="twitter" href="http://twitter.com/share?url=http://codepen.io/laivanduc/pen/mJappx"><span class="brandico-twitter-bird"></span></a></li>
				<li><a target="_blank" class="facebook" href="http://www.facebook.com/sharer.php?u=http://codepen.io/laivanduc/pen/mJappx"><span class="brandico-facebook"></span></a></li>
				<li><a target="_blank" class="google" href="https://plus.google.com/share?url=http://codepen.io/laivanduc/pen/mJappx"><span class="brandico-googleplus-rect"></span></a></li>
			</ul>
		</div>
	</div>
  <footer>
		<p class="disclaimer">Tất cả các Logo được sử dụng trong Game này do sở hữu của các tổ chức tương ứng.</p>
	</footer>
  </div><!-- End Wrap -->

Tiếp theo chúng ta sẽ cần tới đoạn Code CSS như sau:

@import url(http://weloveiconfonts.com/api/?family=Arial);

/* brandico */
[class*="brandico-"]:before {
  font-family: 'Arial', sans-serif;
}

* {
	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%;
}

@mixin width($max){
	@media (max-width: $max){
		@content;
	}
}

@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);  
	@include width(800px){
		width: 25%;
		height: 16.666%;
	}
	.inside {
		width: 100%;
		height: 100%;
		display: block;
		transform-style: preserve-3d;
		transition: .4s ease-in-out;
		background: white;

		&.picked, &.matched {
			transform: rotateY(180deg);
		}
		&.matched {
			animation: 1s matchAnim ease-in-out;
			animation-delay: .4s;
		}
	}

  .front, .back {
  	border: 1px solid black;
  	backface-visibility: hidden;
  	position: absolute;
  	top: 0;
  	left: 0;
  	width: 100%;
  	height: 100%;
  	padding: 20px;

  	img {
  		max-width: 100%;
  		display: block;
  		margin: 0 auto;
  		max-height: 100%;
  	}
  }
  .front {
  	transform: rotateY(-180deg);
  	@include width(800px){
  		padding: 5px;
  	}
  }
  .back{
		@include width(800px){
  		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;
	.winner {
		font-size: 80px;
		text-align: center;
		font-family: "Arial", sans-serif;
		color: #4d4d4d;
		text-shadow: 0px 3px 0 black;
		@include width(480px){
			font-size: 60px;
		}
	}
	.restart {
		font-family: "Arial", 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;
		&:hover {
			background: linear-gradient(#222, black);
		}
	}
	.message {
		text-align: center;
		a {
			text-decoration: none;
			color: #28afe6;
			font-weight: bold;
			&:hover {
				$c: lighten(#28afe6, 10%);
				color: $c;
				border-bottom: 1px dotted $c;
			}
		}
	}
	.share-text {
		text-align: center;
		margin: 10px auto;
	}
	.social {
		margin: 20px auto;
		text-align: center;
		li {
			display: inline-block;
			height: 50px;
			width: 50px;
			margin-right: 10px;
			&:last-child {
				margin-right: 0;
			}
			a {
				display: block;
				line-height: 50px;
				font-size: 20px;
				color: white;
				text-decoration: none;
				border-radius: 5px;
				&.facebook {
					background: #3b5998;
					&:hover {
						background: lighten(#3b5998, 10%);
					}
				}
				&.google {
					background: #D34836;
					&:hover {
						background: lighten(#D34836, 10%);
					}
				}
				&.twitter {
					background: #4099FF;
					&:hover {
						background: lighten(#4099FF, 10%);
					}
				}
			}
		}
	}
}

footer {
	height: 20px;
	position: absolute;
	bottom: 0;
	width: 100%;
  z-index: 0;
	.disclaimer {
		line-height: 20px;
		font-size: 12px;
		color: #727272;
		text-align: center;
		@include width(767px){
			font-size: 8px;
		}
	}
}

Và cuối cùng là linh hồn của Game này bằng JavaScript:

(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();
		},

		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);
			this.$restartButton.on("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("slow");
		},

		// Fisher--Yates Algorithm -- http://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="http://www.laivanduc.com/wp-content/uploads/2015/08/Logo-laivanducblog.png"\
				alt="laivanduc" /></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
		},
		{
			name: "html5",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/html5-logo.png",
			id: 3
		},
		{
			name: "jquery",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/jquery-logo.png",
			id: 4
		}, 
		{
			name: "javascript",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/js-logo.png",
			id: 5
		},
		{
			name: "node",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/nodejs-logo.png",
			id: 6
		},
		{
			name: "photoshop",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/photoshop-logo.png",
			id: 7
		},
		{
			name: "python",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/python-logo.png",
			id: 8
		},
		{
			name: "rails",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/rails-logo.png",
			id: 9
		},
		{
			name: "sass",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/sass-logo.png",
			id: 10
		},
		{
			name: "sublime",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/sublime-logo.png",
			id: 11
		},
		{
			name: "wordpress",
			img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/wordpress-logo.png",
			id: 12
		},
	];
    
	Memory.init(cards);


})();

Các bạn để ý đoạn Code bên trên gồm rất nhiều link hình ảnh được sử dụng. Các bạn có thể thay đổi hình ảnh khác của bạn nhưng hãy để kích thước vuông để hiển thị cho đẹp mắt.

Rồi, ngay bây giờ mời bạn cùng chơi Game với tôi và hãy cho mọi người biết bạn đã phải mất bao nhiêu thời gian để chiến thắng nhé.  😆

See the Pen Self Code a similar flip the Game by Lại Văn Đức (@laivanduc) on CodePen.16775