之前做的一个多米诺骨牌游戏

开始准备用canvas来做,性能会好一点,但后来项目催的比较紧,设计稿又给的比较晚,所以无奈还是用的dom操作

项目中遇到了几个问题
1、移动端所有的浏览器都不支持js动态设置animation-play-state,这个比较恶心,最后只能不停的获取transform和设置transform,而且每次停顿都需要取消掉运动效果(transition:none);
2、快速设置innerHTML或者innerText性能超级差,移动端完全没办法用,我这里用到间隔一秒设置一次,这样的频率都很不流畅,最后改用input value
3、由于运动效果全是由css3实现,所以进度有点难掌握,控制不够灵活,导致多次停顿的时候,会有画布的偏移

以上问题如果改用canvas就都会避免了,总之做游戏还是别用dom~

下面放一下主要源码

define(function(require, exports) {
	var dominos = document.querySelector('.dominos');
	var spaceship = document.querySelector('.spaceship');
	var dominosLen = 50;
	var distanceCounter = document.querySelector('.distance-counter input');
	var timerCounter = document.querySelector('.timer-counter input');
	var showGame = document.querySelector('#show-game');
	
	var shareinfo = {
		title : 'u53d8u8eabu76d6u661fu4ebau0020u597du793cu7b49u60a8u62ff',
		url : 'http://m.zol.com.cn/topic/galaxy_game',
		pic : 'http://icon.zol-img.com.cn/m/images/topic/galaxy_game/sharepic.jpg',
	}
	
	dominos.timerCounter = 20;
	dominos.positionTop = 0
	dominos.items = null;
	dominos.timer = null;
	
	var timerCount = null;
	var timer = 20;
	
	var lastDownTime = null;
	var action = {
		animate: {
			stop: function(obj) {
				obj.style.webkitAnimationPlayState = 'paused';
				obj.style.animationPlayState = 'paused';
			},
			moving: function(obj) {
				obj.style.webkitAnimationPlayState = 'running';
				obj.style.animationPlayState = 'running';
			}
		}
	}

	window.addEventListener('load', indexInit);
	
	var moving = false;
	
	window.WeixinShareData = {
		icon: shareinfo.pic,
		title: 'u53d8u8eabu76d6u661fu4ebau0020u597du793cu7b49u60a8u62ff'
	};

	function indexInit() {
		var indexPage = document.querySelector('#index');
		var game = document.querySelector('#game');
		var loading = document.querySelector('.loading');
		loading && (loading.style.display = 'none');
		var btn = indexPage.querySelector('#index .btn');
		btn && btn.addEventListener('tap', function() {
			indexPage.classList.add('hide');
			setTimeout(function(){
				indexPage.style.display = 'none';
				game.style.display = 'block';
				initGame();
			},500);
		});
	}

	function initGame() {
		var temp = '';
			distanceCounter.value = 20;
			timerCounter.value = 20;
		for (i = 1; i <= dominosLen; i++) {
			temp += '<span data-stage="1" data-index="' + (i - 1) + '" class="item" style="-webkit-transform:translate3d(0,-' + (dominosLen - i) * 3000 / dominosLen + 'px,0);transform:translate3d(0,-' + (dominosLen - i) * 3000 / dominosLen + 'px,0);"></span>';
		}
		dominos.innerHTML = temp;
		makePhones();
		spaceship.addEventListener(Event.Touch.down, downFn);
		dominos.items = dominos.querySelectorAll('.item');

		dominos.nowItem = dominos.items.lastItem;
		dominos.nowIndex = dominosLen - 1;

		showGame && showGame.addEventListener('tap', function() {
			this.parentNode.classList.add('hide');
		})
	}

	function makePhones() {
		var tempArr = dominos.querySelectorAll('.item');
		var rand = 0;
		for (var i = 0; i < 5; i++) {
			rand = getRand(tempArr.length-10) + 5;
			tempArr[rand].classList.add('phone');
		}
	}

	function getRand(toLength) {
		return Math.round(Math.random() * toLength);
	}
	
	var gameIntro = document.querySelector('.game-intro');
	function falldown() {
		if(gameIntro.style.display !== 'none'){
			gameIntro.style.display = 'none';
			console.log(gameIntro.style.display)
		}
		if (dominos.nowIndex >= -2) {



			if (dominos.nowIndex >= 0) {

				dominos.nowItem = dominos.items[dominos.nowIndex];

				if (dominos.nowItem.classList.contains('phone')) {

					destroyActions();

					lose();

					return;

				}

			}
			dominos.timerCounter = dominos.timerCounter - 0.4;
			distanceCounter.value = parseInt(dominos.timerCounter);
			if (dominos.timerCounter <= 10) {

				if (!distanceCounter.halfDis) {

					distanceCounter.halfDis = 1;

					var leftPlu = document.querySelector('.left-plugin');

					var rightPlu = document.querySelector('.right-plugin');

					leftPlu.style.webkitTransition = rightPlu.style.webkitTransition = 'transform 500ms';

					leftPlu.style.webkitTransition = rightPlu.style.transition = 'transform 500ms';

					leftPlu.style.webkitTransform = 'translate3d(-104px,0,0)';

					leftPlu.style.transform = 'translate3d(-104px,0,0)';

					rightPlu.style.webkitTransform = 'translate3d(104px,0,0)';

					rightPlu.style.transform = 'translate3d(104px,0,0)';

					setTimeout(function(){

						leftPlu && (leftPlu.style.backgroundPosition = '-128px 0');

						rightPlu && (rightPlu.style.backgroundPosition = '-394px 0');

						leftPlu.style.webkitTransform = rightPlu.style.webkitTransform = 'translate3d(0,0,0)';

						leftPlu.style.transform = rightPlu.style.transform = 'translate3d(0,0,0)';

					},500);

				}

			}

			



			if(!moving){

				moving = true;

				startMove();

				action.animate.moving(spaceship);

			}



			switch (dominos.nowIndex) {

				case dominosLen - 1:

					fall(dominos.items[dominos.nowIndex], 2);

					break;

				case dominosLen - 2:

					fall(dominos.items[dominos.nowIndex], 2);

					fall(dominos.items[dominos.nowIndex + 1], 3);

					break;

				case -1:

					fall(dominos.items[dominos.nowIndex + 1], 3);

					fall(dominos.items[dominos.nowIndex + 2], 4);

					break;

				case -2:

					fall(dominos.items[dominos.nowIndex + 2], 4);

					destroyActions();

					success();

					break;

				default:

					fall(dominos.items[dominos.nowIndex], 2);

					fall(dominos.items[dominos.nowIndex + 1], 3);

					fall(dominos.items[dominos.nowIndex + 2], 4);

					break;

			}



			dominos.nowIndex--;
			dominos.timer = setTimeout(falldown, 200);
		}

	}

	function success() {

		if(timerCount){clearInterval(timerCount);}
		var loading = document.querySelector('.loading');
		loading&&(loading.style.display = 'block');
		var result = document.querySelector('#result');
		var resultIframe = result.querySelector('#resultIframe');
		var game = document.querySelector('#game');
		if (!result) {
			return;
		}
		$.ajax({
			url:'http://m.zol.com.cn/topic/services/token.php',
			dataType:'jsonp',
			type:'get',
			success:function(request){
				if (request) {
					window.token = request['token'];
					result.querySelector('#resultIframe').src = 'success.html';
					game.style.display = 'none';
					result.style.display = 'block';
					resultIframe.addEventListener('load',function(){
						loading.style.display = 'none';
					})
				}
				else{
					alert('u672au77e5u9519u8bef');
				}
			},
			error:function(){
				alert('u7f51u7edcu9519u8bef');
			}
		})
	}

	function lose() {
		if(timerCount){clearInterval(timerCount);}
		var loading = document.querySelector('.loading');
		loading&&(loading.style.display = 'block');
		var result = document.querySelector('#result');
		var resultIframe = result.querySelector('#resultIframe');
		var game = document.querySelector('#game');
		if (!result) {
			return;
		}
		result.querySelector('#resultIframe').src = 'lose.html';
		game.style.display = 'none';
		result.style.display = 'block';
		resultIframe.addEventListener('load',function(){
			loading.style.display = 'none';
		})

	}

	function fall(obj, stage) {
		lastDownTime = new Date();
		obj.style.backgroundPosition = -((stage - 1) * 104) + 'px bottom';
	}

	function downFn(e) {
		Event.preventDefault(e);
		if(!timerCount){

			

			timerCount = setInterval(function(){

				timerCounter.value = timer;

				if(timer <= 0){

					clearInterval(timerCount);

					lose();

					return;

				};

				timer--;

			},1000);

		}
		clearTimeout(dominos.timer);
		dominos.timer = setTimeout(falldown, 200);
		window.addEventListener(Event.Touch.move, Event.preventDefault)
		window.addEventListener(Event.Touch.up, upFn)
		window.addEventListener(Event.Touch.cancel, upFn);
	}

	function upFn(e) {
		Event.preventDefault(e);
		destroyActions();
		var prev = dominos.nowItem.previousSibling;
		if(prev && prev.classList.contains('phone') ){
			prev.classList.add('flash');
			setTimeout(function(){
				prev.classList.remove('phone');
			},500);
		}
		
		
	}
	function startMove() {
		startFlag = true;
		dominos.style.webkitTransition = 'all ' + parseFloat(dominos.timerCounter) / 2 + 's linear';
		dominos.style.transition = 'all ' + parseFloat(dominos.timerCounter) / 2 + 's linear';
		dominos.style.webkitTransform = 'translate3d(0,3000px,0)';
		dominos.style.transform = 'translate3d(0,3000px,0)';
	}

	function stopMove() {
		var dominosPosition = parseFloat(window.getComputedStyle(dominos, null).webkitTransform.split(',')[5]);
		dominos.style.webkitTransition = 'none';
		dominos.style.transition = 'none';
		dominos.style.webkitTransform = 'translate3d(0,' + dominosPosition + 'px,0)';
		dominos.style.transform = 'translate3d(0,' + dominosPosition + 'px,0)';
	}

	function destroyActions() {
		clearTimeout(dominos.timer);
		stopMove();
		action.animate.stop(spaceship);
		moving = false;
		window.removeEventListener(Event.Touch.up, upFn);
		window.removeEventListener(Event.Touch.cancel, upFn);
		window.removeEventListener(Event.Touch.move, Event.preventDefault);
		
	}

})

以下是项目地址:http://m.zol.com.cn/topic/galaxy_game/

之前做的一个多米诺骨牌游戏