cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              title Memory Card Game
		link(href="https://fonts.googleapis.com/css?family=PT+Sans:700i" rel="stylesheet")
		link(href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet")
		link(rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.5/sweetalert2.min.css")
		link(rel="stylesheet" type="text/css" href="/stylesheets/css/styles.css")

		script(src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js")
		script(src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.5/sweetalert2.common.js")
		script(src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.js")
		script(src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js")
		script(type="text/javascript" src="javascripts/scripts.js")
script.
	var scoreArray = "#{scoreArray}";
	scoreArray = scoreArray.split(',');
	var usernameArray = "#{usernameArray}";
	usernameArray = usernameArray.split(',');
	console.log(usernameArray);
	console.log(scoreArray);

body
	div.start-container
		h1 Overwatch Card Match
		p Click on a card to flip it over. If you turn over two matching cards, you get to keep them; if they don't match, they get flipped back. Every fifteen seconds, the cards will reshuffle. Match all sixteen cards to win! View in full-page mode to play.
		button#start Start
	div.game-container
		div.cards-container
			div.mg-contents
	div.menu-container
		div.score-container Score
			span.score
		div.time-container Time 
			span.time :
		div.reset-container
			button#reset Reset
		div.message-container
			div.message-text-box
				div.message-text
	div.scoreboard-container
		div.score-board
			table
				thead
					tr
						th Name
						th Score
				tbody.userdata
		div.username-container
			div.winning-msg
			form.name
				input.name-input(type="text" name="username" placeholder="Username")
				button.name-btn(type="button") Submit
			div.form-msg


	

            
          
!
            
              $card-size: 10rem;
$grey: #ebebeb;
$font: "brandon-grotesque", "Brandon Grotesque", "Brandon Text", "Futura", "Source Sans Pro", "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif;
*{
	box-sizing:border-box;
}
body{
	height:100vh;
	width:100vw;
	@extend .flex-box-center;
	font-family:$font;
	&.begin {
		.menu-container{
			opacity: 1;
		}
		.start-container{
			opacity: 0;
			z-index: -1000;
		}
		.game-container{
			opacity: 1;
			z-index: 1000;
		}
	}
}
img{
	max-width: 100%;
	height:auto;
}

.flex-box-center{
	display: flex;
	justify-content: center;
	align-items: center;
}
.start-container{
	position:absolute;
	@extend .flex-box-center;
	flex-direction: column;
	height:100vh;
	width:100vw;
	background-color: rgba($grey, .8);
	z-index:1000;
	p{
		width:50%;
	}
	button{
		cursor: pointer;
		border: 0;
		min-width: 180px;
		height:64px;
		font-family: $font;
		border-radius: 16px;
		font-size: 20px;
		background-color:#fc9c33;
	}
}
.game-container{
	@extend .flex-box-center;
	align-items:flex-start;
	opacity: 0.3;
	height: 80vh;
	width:80vw;
	transition: all 2s;
	.mg-contents{
		width:100%;
		height:100%;
		padding-left: 10%;
	}
}
.menu-container{
	margin-top: 1%;
	height: 100%;
	opacity: 0;
	z-index:1001;
	@extend .flex-box-center;
	flex-direction: column;
	justify-content: space-around;
	align-items:flex-start;
	#reset{
		cursor: pointer;
		background-color: #F2B880;
		border: 0;
		font-family: $font;
		border-radius: 16px;
		font-size: 20px;
		min-width: 100px;
		height:40px;
	}
}
.scoreboard-container{
	position:absolute;
	height:100vh;
	width:100vw;
	background-color: rgba($grey, .8);
	z-index:1000;
	display: none;
	// display:flex;
	flex-direction: column;
	align-items:center;
	.score-board{
		opacity: 0;
		margin-top: 15%;
		th{
			padding-right: 40%;
		}
	}	
	.username-container{
		// opacity: 0;
		.name{
			margin-bottom: 0.5em;
			input {
				margin-top: 5px;
				padding: 6px 15px;
				border:1px solid #999;
				border-radius: 16px;
				line-height: 20px;
				font-size: 14px;
				color: #222;
			}
  			button {
  				cursor: pointer;
				background-color: #F2B880;
				border: 0;
				font-family: $font;
				border-radius:16px;
				font-size: 14px;
				min-width: 80px;
				height:35px;
				margin-left: 5px;
  			}
  		}
	}
	&.start{
		display: none;
	}
	.won{
		display:flex;
	}
}
.cards-container{
	@extend .flex-box-center;
	height: 100%;
	width:100%;
	max-width:865px;
	flex-flow: row wrap;
	appearance: none;
}

.card {
	cursor: pointer;
    height: $card-size;
    width: $card-size;
    border: 2px solid black;
    perspective: 500px;
    background-color: $grey;
    border-radius: 5%;
    display: inline-block;
    margin:1%;
}

.card-holder {
    width: $card-size;
    height: $card-size;
    /*the children will be absolute. So make this relative so they can have an anchor*/
    position: relative;
    /*so that the children know they are in 3d land*/
    transform-style: preserve-3d;
    transition: 500ms all;
}

.card-front, .card-back{
    position: absolute;
    top: 0;
    left: 0;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

.card-front {
    height: $card-size;
    width: $card-size;
    transform: rotateY(-180deg);
    /*margin: auto;*/
    /*vertical-align: middle;*/

}

.card-back {
    background: url('back.png') no-repeat 50%; /*50% is background-location*/
    height: $card-size;
    min-width: $card-size;
}

.flip {
    transform: rotateY(180deg);
    /*margin: auto;*/
}

.matched {
    transform: rotateY(180deg);
}

            
          
!
            
              var cards = [];
cards = createCard();
var score = 200;
var theCards = cards.slice();
// var time = 0;
// var runtime = true;
// var changeTime = false;
var gridSize = 16;
var timerInterval = 0;
var won = false;
var GameT = new Timer(60);
var outTime = false;
var username;
var scoreBoard = [];
// All code will wait until the DOM is ready!
$(document).ready(function(){
	$('.scoreboard-container').addClass('start');
	displayCard();
	createScoreBoard()
	$cards = $('.mg-contents');
	// $cards.isotope({
	// 	itemSelector:'.card',
	// });
	$('#start').click(function(){
		$('body').addClass('begin');
		// $cards.isotope('shuffle');
	$('#reset').click(function(){
		reset();
		displayCard();
		// $cards.isotope('shuffle');
		addClicks()
	});

	addClicks()
	$('.name-btn').click(function(){
		username = $('.name-input').val();
		var spaceReg = /\s/g;
		var result = username.match(spaceReg);
		if(username.length <= 2 || result != null){
			textGenerater();
		}else{
			if(checkScore()){
				$.ajax({
					method: "POST",
					url: "userInput",
					data:{score: score, username: username},
					success: function(result){
					// console.log(result);
					}
				})
			}
			$('.score-board').css('opacity', '1');
			updateBoard();
		}
		// console.log(scoreBoard);
	});



});

function createCard(){
	// add function for different difficulty levels
	for (let i = 1; i < 9; i++){
		var card = `<img src="/images/easy/easy-${i}.png"/>`;
		cards.push(card);
		cards.push(card);
		}
	return cards;
}
function displayCard(){
	var card = 0;
	var cardBack = '<img src="/images/back.png">'
	var mgHTML = '';
	shuffleCard()
	for(let i = 0; i < gridSize; i++){
		card = theCards.shift();
		if (i % 4 == 0){
			mgHTML += '<div class="card">';
		}else{
			mgHTML += '<div class="card">';
		}
			mgHTML += `<div class="card-holder ${i}">`;
				mgHTML += '<div class="card-front">'+card+'</div>';
				mgHTML += '<div class="card-back">' + cardBack+ '</div>';
			mgHTML += '</div>';
		mgHTML += '</div>';
	}
	$('.mg-contents').html(mgHTML);
}
function shuffleCard(){
	var temp = 0;
	for (let i = 0; i < 500; i++){
		var random1 = Math.floor(Math.random()*16);
		var random2 = Math.floor(Math.random()*16);
		temp = theCards[random1];
		theCards[random1] = theCards[random2];
		theCards[random2] = temp;
	}
}

function showCard(cardsUp){
	// var classList = cardsUp.attr("class").split(" ");
	// var currentCard = Number(classList[1]);
	// console.log(currentCard);

	var showed = false;
	var i = 0;
	var nextCard = 0;
	var cardsUpTotal = $('.matched');
	if (cardsUpTotal.length >= 14) return 1;
	while (!showed) {
		i = Math.floor(Math.random()*16);
		nextCard = $(`.${i}`);
		if ((!nextCard.hasClass('flip')) && (!nextCard.hasClass('matched'))){
			nextCard.addClass('flip');
			setTimeout(()=>nextCard.removeClass('flip'), 500);
			showed = true;
		}
	}
}

function addClicks(){
	$('.card-holder').click(function(){

		if ((!won) && (!outTime)){
			GameT.start();
			$(this).toggleClass('flip');
			var cardsUp = $('.flip');
			if(cardsUp.length == 2){
				var card1 = cardsUp[0].children[0].children[0].src;
				// var card2 = cardsUp[1].find('.card-front img');
				var card2 = cardsUp[1].children[0].children[0].src;
				if (card1 === card2){
					cardsUp.removeClass('flip');
					cardsUp.addClass('matched');
					var matchedCards = $('.matched');
					ability(card1, cardsUp);
					if(matchedCards.length == gridSize){
						won = true;
						$('body').css({
							'transition': "all 2s",
						});
						$('.mg-contents').css('display', 'none');
						// $('.username-container').fadeIn();
						$(".scoreboard-container").removeClass('start');
						$(".scoreboard-container").addClass('won');
						textGenerater('YOU HAVE WON THE GAME!');
						setTimeout(victorySound, 5000);
					}
				}else {
					setTimeout(function(){
						cardsUp.removeClass('flip');
					}, 850);
					updateScore()
				}
			}else{
				setTimeout(()=>{
					cardsUp.removeClass('flip');
				}, 850);
				updateScore();
			}
		}
	});
}
function updateScore(){
	score--;
	$('.score').text(score);
}
function createScoreBoard(){
	for(let i = 0; i < usernameArray.length; i++){
		var userData={'username': usernameArray[i], 'score': scoreArray[i]};
		scoreBoard.push(userData);
	}
}
function checkScore(){
	var updated = false;
	scoreBoard.map(oldData=>{
		if(score >= oldData.score && !updated){
			updated = true;
			oldData.score = score;
			oldData.username = username;
			return true;
		}
	});
	if (scoreBoard.length < 10) return true;
	if (!updated && scoreBoard.length >= 10) return false;
};

function updateBoard(){
	scoreBoard.map(data=>{
		var newHTML = ''
		newHTML += '<tr>';
			newHTML += `<td>${data.username}</td>`;
			newHTML += `<td>${data.score}</td>`;
		newHTML += '</tr>';
		$('.userdata').append(newHTML);
	});
}
//
// }
// function highScores(){
// 	if (typeof(Storage) !== "undefined"){
// 		var scoreBoard = $('#score-board-body').html();
// 		var lastscore = localStorage["score"];
// 		var newHTML = ''
// 		if (lastscore){
// 			newHTML += '<tr>'
// 				newHTML += `<td>${}
// 		}
// 	}
// }
function reset(){
	cards = createCard();
	shuffleCard();
	score = 200;
	theCards = cards.slice();
	card = 0;
	mgHTML = '';
	timerInterval = 0;
	won = false;
	GameT.clearInterval();
	$('.time').html('');
	GameT = new Timer(60);
	outTime = false;
	$(".scoreboard-container").hide();
	$('.score').text('');
	$('.card-holder').removeClass('flip');
	$('.card-holder').removeClass('matched');
	$('.mg-contents').css('filter', 'none');
	$('.mg-contents').show();
	$('.message-container').hide();
}

function ability(card1, cardsUp){
	// display hero's line and ability
	// 1. mercy: Heros never die. Time + 5s
	if (card1.slice(-5,-4) == 4){
		GameT.addTime();
		textGenerater('Heros never die! +5s');
		playSound(card1);
	}
	// 2. Mei: Freeze, don't move
	else if(card1.slice(-5, -4) == 1){
		var nextLine = "<br/>";
		GameT.pauseT();
		textGenerater(`Freeze, don't move!${nextLine}Time pause for 5s`);
		playSound(card1);
		setTimeout(()=>GameT.resume(), 5000);
	}
	else if(card1.slice(-5, -4) == 3){
		GameT.lossTime();
		textGenerater('Die, Die, Die!Lost 5s');
		playSound(card1);
	}
	else if(card1.slice(-5, -4) == 2){
		textGenerater("No one can hide from my sight!");
		playSound(card1);
		showCard(cardsUp);
	}
}

function textGenerater(text){
	if ((won) || (outTime)){
		$('.mg-contents').css('filter', 'blur(5px)');
		swal({
			allowEscapeKey: false,
			allowOutsideClick: false,
			title: 'Congratulations! You Won!',
			text: 'With ' + moves + ' Moves and ' + score + ' Stars.\nBoom Shaka Lak!',
			type: 'success',
			confirmButtonColor: '#9BCB3C',
		});
	}
	setTimeout(()=>$('.message-container').show(), 500);
	$('.message-text').html(text);
	setTimeout(()=>$('.message-container').hide(), 3000);
	$('.form-msg').html("Please enter an username without any space in it...");
}

function playSound(card1){
	const currentCard = card1.slice(-5, -4);
	const audio = $(`.sound-${currentCard}`);
	if(!audio) return;
	audio[0].currentTime = 0;
	audio[0].play();
}

function victorySound(){
	if (won){
		const victory = $('.victory');
		victory[0].currentTime = 0;
		victory[0].play();
	}
}
function Timer(seconds){
	this.seconds = seconds;
	this.currentTime = 0;
	this.timeOut = 0;
	this.pauseTime = 0
	this.running = false;
	this.timeInterval = 0;
	this.pause = false;
	this.addedT = false;
	this.lostT = false;
}

Timer.prototype.start = function(){
	if(!this.running){
		this.currentTime = Date.parse(new Date());
		this.timeInterval = setInterval(()=>this.updateTime(0), 1000);
		this.running = true;
	}
};
Timer.prototype.resume = function(){
	this.pause = false;
	clearInterval(this.timeInterval);
	if (this.addedT){
		this.currentTime += 6000;
	}
	if (this.lostT){
		this.currentTime -= 4000;
	}
	this.currentTime += 6000;
	this.timeInterval = setInterval(()=>this.updateTime(), 1000);

};
Timer.prototype.addTime = function(){
	if (!this.pause){
		this.currentTime += 6000;
		clearInterval(this.timeInterval);
		this.timeInterval = setInterval(()=>this.updateTime(), 1000);
	}else {
		this.addedT = true;
	}
}
Timer.prototype.lossTime = function(){
	if (!this.pause){
		this.currentTime -= 4000;
		clearInterval(this.timeInterval);
		this.timeInterval = setInterval(()=>this.updateTime(), 1000);
	}else {
		this.lostT = true;
	}

}
Timer.prototype.pauseT = function(){
	this.pause = true;
	this.pauseTime = this.timeOut
	clearInterval(this.timeInterval);
};

Timer.prototype.display = function(){
	if (this.timeOut > 0){
		$('.time').html(`${this.timeOut/1000}`);
	}else {
		outTime = true;
		$('.time').html('0');
		clearInterval(this.timeInterval);
	}
	if (outTime){
		textGenerater('YOU HAVE RAN OUT OF TIME!')
	}
	if (won){
		$('.time').html('0');
		clearInterval(this.timeInterval);
	}
}
Timer.prototype.updateTime = function(){
	this.timeOut = this.currentTime + this.seconds*1000 - Date.parse(new Date());
	if (!this.pause){
		this.display()
	}else{
		$('.time').html(`${this.pauseTime/1000}`);
	}
};

Timer.prototype.clearInterval = function(){
	clearInterval(this.timeInterval);
}
            
          
!
999px
Loading ..................

Console