飞镖2d小游戏

网上无聊看到一个类似飞镖的游戏,就想到动手做一个2d的版本.后续看看3d的版本如何实现

html文件

<!DOCTYPE html>
<html>
<head>
	<title>飞镖游戏</title>
	<meta charset="utf-8">
	<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />
	<style type="text/css"></style>
	<link rel="stylesheet" type="text/css" href="feibiao-game.css">
</head>
<body>
	<figure>
		<div class="circle" id="circle">
		</div>
		<div class="arrow" id="arrow">
		</div>
		<div class="buttonBar">
			<div class="shoot" id="shoot">Begin</div>
		</div>
		<div class="arrow-bag" id="arrow-bag">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
			<img src="arrow.png">
		</div>
	</figure>
	<script type="text/javascript" src="feibiao-game.js"></script>
</body>
</html>复制代码


css文件

* {
	margin: 0;
	padding: 0;
}


figure {
	width: 600px;
	height: 600px;
	margin: auto;
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
}

.circle {
	width: 200px;
	height: 200px;
	margin: 50px auto;
	border-radius: 50%;
	background-image: url(target.jpg);
	background-repeat:no-repeat;
	background-size:100% 100%;
	position: absolute;
	left: 50%;
	transform: translate(-50%);
	transform-origin: 50% 50%;
}


.embed-arrow {
	width: 20px;
	height: 50px;
	text-align: center;
	position: absolute;
	margin: 0 auto;
	transform-origin: 0px 130px ;
	left: 50%;
	top: -30px;
}


.embed-arrow img {
	width: 60px;
	height: 50px;
	transform: rotate(-117deg);
}

.arrow-bag {
	color: purple;
	position: absolute;
	width: 120px;
	height: 300px;
	bottom: 10px;
	left: 20%;
	font-weight: bold;
	font-size: 0;
}

.arrow-bag img {
	width: 60px;
	height: 50px;
	transform: rotate(50deg);
}

.arrow {
	position: absolute;
	bottom: 150px;
	left: 50%;
	transform: translate(-50%);
}

@keyframes shoot {
	0% {
		bottom: 150px;
	}

	100% {
		bottom: 300px;
	}
}

.arrow img {
	width: 60px;
	height: 50px;
	transform: rotate(50deg);
}


.shoot {
	position: absolute;
	width: 100px;
	height: 100px;
	bottom: 40px;
	left: 50%;
	transform: translate(-50%);
	background-color: blue;
	color: #fff;
	font-weight: bold;
	font-size: 24px;
	text-align: center;
	line-height: 100px;
	border-radius: 50%;
	-webkit-user-select:none;
	-moz-user-select:none;
	-ms-user-select:none;
	user-select:none;
}

.shoot:hover {
	box-shadow: 0 0 20px blue, 0 0 30px purple;
}



@keyframes circle-run {
	0% {
		transform: translate(-50%) rotate(0deg);
	}

	100% {
		transform: translate(-50%) rotate(360deg);
	}
}
















复制代码


js文件

let docCircle = document.getElementById('circle');
let arrow = document.getElementById('arrow');
let shoot = document.getElementById('shoot');
let arrowBag = document.getElementById('arrow-bag');
let beginDeg = 180; //因从180度开始射箭
let targetArrow = []; //已经射中的角度
let target = false; //是否命中目标
let remainArrowNum = 10; //初始10只箭
let body = document.body || document.documentElement;
let style = body.style;
let animationEndName = (function() {
	let animEndEventNames = {
		WebkitAnimation: 'webkitAnimationEnd',
		animation: 'animationend'
	};
	for (var name in animEndEventNames) {
		if (typeof style[name] === "string") {
			return animEndEventNames[name]
		}
	}
})();
let arrowImgUrl = 'arrow.png';
let gameStartTime = 0;

//事件绑定
let addHandler = function(element, type, handler) {
	if (element.addEventListener) {
		element.addEventListener(type, handler, false);
	} else if (element.attachEvent) {
		element["e" + type] = function() {
			handler.call(element)
		};
		element.attachEvent("on" + type, element["e" + type]);
	} else {
		element["on" + type] = handler;
	}
};

//事件解绑
let removeHandler = function(element, type, handler) {
	if (element.removeEventListener) {
		element.removeEventListener(type, handler, false);
	} else if (element.detachEvent) {
		element.detachEvent("on" + type, element["e" + type]);
		element["e" + type] = null;
	} else {
		element["on" + type] = null;
	}
};

//发射按钮绑定事件
let shootFunc = function() {
	arrow.style.animation = "shoot 0.1s linear 1"
};
//开始按钮时间
let beginFunc = function() {
	//剩余飞镖
	remainArrowNum--;
	//箭袋减少一根箭
	arrowBag.removeChild(arrowBag.firstElementChild);
	//装备一只箭
	let arrowImg = document.createElement('img');
	arrowImg.src = arrowImgUrl;
	arrow.appendChild(arrowImg);
	//修改按钮名称
	shoot.innerHTML = 'Arrow';
	//解绑按钮开始事件
	removeHandler(shoot, 'click', beginFunc);
	//绑定射击新事件
	addHandler(shoot, 'click', shootFunc);
	//飞镖盘一直转
	docCircle.style.animation = 'circle-run 3.6s linear infinite';
	//游戏开始时间
	gameStartTime = new Date().getTime();
};
//重新开始事件
let reStartFunc = function() {
	targetArrow = []; //已经射中的角度
	target = false; //是否命中目标
	remainArrowNum = 10; //初始10只箭
	//修改按钮名称
	shoot.innerHTML = 'Begin';
	//解绑按钮重新开始事件
	removeHandler(shoot, 'click', reStartFunc);
	//绑定开始事件
	addHandler(shoot, 'click', beginFunc);
	//箭袋放入10只箭
	for (let i = 0; i < remainArrowNum; i++) {
		let arrowImg = document.createElement('img');
		arrowImg.src = arrowImgUrl;
		arrowBag.appendChild(arrowImg);
	}
	//清除转盘上的箭
	docCircle.innerHTML = '';
	//飞盘停止转动
	docCircle.style.animation = '';
};


//绑定开始按钮新事件
addHandler(shoot, 'click', beginFunc);

function isTarget(currentCircleDeg) {
	target = targetArrow.every(
		function(val, index, arr) {
			if (currentCircleDeg > val - 10 && currentCircleDeg < val + 10) {
				return false;
			} else {
				return true;
			}
		}
	);
	if (targetArrow.length <= 0) {
		target = true;
	}
}

function targetFunc(currentCircleDeg) {
	let newArrow = document.createElement('div');
	let arrowImg = document.createElement('img');
	arrowImg.src = arrowImgUrl;
	newArrow.appendChild(arrowImg);
	newArrow.className = 'embed-arrow';
	newArrow.style.transform = 'rotate(' + (beginDeg - currentCircleDeg) + 'deg) translate(-50%)';
	docCircle.appendChild(newArrow);
	targetArrow.push(currentCircleDeg);
}

//飞镖射到飞镖盘结束事件
addHandler(arrow, animationEndName, function() { //动画结束时事件 
	arrow.style.animation = "";
	//转盘旋转时间ms
	let time = new Date().getTime() - gameStartTime + 100;
	let gameTime = time % 3600;
	let currentCircleDeg = gameTime * 0.1;
	isTarget(currentCircleDeg);
	//发射之后箭袋及按钮样式处理
	calRemainArrowNum();
	if (!target) {
		target = false;
		return;
	} else {
		//命中目标样式处理
		targetFunc(currentCircleDeg);
	}
}, false); 

let calRemainArrowNum = function() {
	//剩余飞镖
	remainArrowNum--;
	//解绑发射按钮
	if (remainArrowNum < 0) {
		//解绑按钮射击事件
		removeHandler(shoot, 'click', shootFunc);
		//最后一支箭消失
		arrow.removeChild(arrow.firstElementChild);
		//修改按钮名称
		shoot.innerHTML = 'ReStart';
		//绑定按钮开始事件
		addHandler(shoot, 'click', reStartFunc);

	} else {
		arrowBag.removeChild(arrowBag.firstElementChild);
	}
};复制代码

js文件中事件绑定的方法是从网上寻找的资源. 为了实战下js源码写功能.所以未使用jq等等插件.兼容性测试了chrome(最新版 70.0.3538.77) ,safari(最新版 ),ie10, ie11

效果图



图片资源是从其他素材网站copy的,感谢!如果涉及版权,请联系会及时删除

转载于:https://juejin.im/post/5bf7b95de51d45661d36ebca

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值