无聊的人用JS实现了一个简单的打地鼠游戏
直入正题,用JS实现一个简单的打地鼠游戏
因为功能比较简单就直接裸奔JS了,先看看效果图,或者 在线玩玩 吧
如果点击颜色比较深的那个(俗称坏老鼠),将扣分50;如果点击颜色比较浅的那个(俗称好老鼠),将得分100
实现
老鼠好像有点难画,又不想用图片,就直接用CSS画个简单的图代表老鼠和坑吧
html结构
挺简单,用9个 li 标签代表坑,用9个 div 标签代表老鼠
- <div class="container">
- <h4>无聊打打地鼠</h4>
- <div class="game-top">
- <p><input type="button" value="开始游戏" id="game-start"><p>
- <p>得分:<span id="game-score">0</span></p>
- <p>剩余时间:<span id="game-time">60</span> s</p>
- </div>
- <div class="game-content">
- <ul>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- <li><div></div></li>
- </ul>
- </div>
- </div>
CSS的实现
有点小技巧
对于坑,加个box-shadow: ... inset 美化一下样式
- .game-content li {
- float: left;
- margin-top: 50px;
- margin-left: 30px;
- width: 100px;
- height: 50px;
- border-radius: 50%;
- background-color: #67d0b4;
- box-shadow: 0 0 50px #706565 inset;
- }
对于老鼠,用 border-radius:50%/40% 绘制,第二个参数还是有点使用价值的
- .game-content div {
- position: relative;
- margin-top: -15px;
- margin-left: 25px;
- width: 50px;
- height: 70px;
- border-radius: 50%/40%;
- background-color: #dfb25d;
- opacity:;
- }
而要让老鼠动起来,这里的处理方式就是用动画了,老鼠运动的时候,先往上再往下即可,控制好相对位置看起来和谐一点就行
- @keyframes mouse-move {
- 50% {
- margin-top: -40px;
- opacity:;
- }
- 100% {
- margin-top: -15px;
- opacity:;
- }
- }
- .game-content div.active {
- animation: mouse-move 2s ease-in-out infinite;
- }
注意 animation: ... infinite 的使用,让动画能一直进行下去,我们使用JS控制好时间差判断应该显示那个老鼠,应该显示多少只老鼠即可
不然的画,会发现动画完成了再也无法让它继续进行了
点击的是好老鼠还是坏老鼠,应该给出提示如:
可以直接用CSS的伪元素::after置入对错,在点击的时候,根据不同的性质设置不同的值及颜色
- .game-content div.good {
- background-color: #dfb25d;
- }
- .game-content div.good[clicked="1"]::after {
- content: "✓";
- line-height: 70px;
- font-size: 40px;
- color: #0ad845;
- }
- .game-content div.bad {
- background-color: #a48f5c;
- }
- .game-content div.bad[clicked="1"]::after {
- content: "✕";
- line-height: 70px;
- font-size: 40px;
- color: #db1536;
- }
- .container {
- width: 500px;
- height: 300px;
- margin: 50px auto;
- border: 1px solid #ddd;
- text-align: center;
- }
- .game-top {
- padding-top: 10px;
- width: 100%;
- height: 90px;
- }
- .game-top p {
- margin: 5px;
- }
- .game-content {
- overflow: auto;
- width: 100%;
- border-top: 1px solid #ddd;
- background-color: #ddf;
- }
- .game-content ul {
- list-style: none;
- }
- .game-content li {
- float: left;
- margin-top: 50px;
- margin-left: 30px;
- width: 100px;
- height: 50px;
- border-radius: 50%;
- background-color: #67d0b4;
- box-shadow: 0 0 50px #706565 inset;
- }
- .game-content li:last-child {
- margin-bottom: 50px;
- }
- .game-content div {
- position: relative;
- margin-top: -15px;
- margin-left: 25px;
- width: 50px;
- height: 70px;
- border-radius: 50%/40%;
- background-color: #dfb25d;
- opacity:;
- }
- .game-content div.good {
- background-color: #dfb25d;
- }
- .game-content div.good[clicked="1"]::after {
- content: "✓";
- line-height: 70px;
- font-size: 40px;
- color: #0ad845;
- }
- .game-content div.bad {
- background-color: #a48f5c;
- }
- .game-content div.bad[clicked="1"]::after {
- content: "✕";
- line-height: 70px;
- font-size: 40px;
- color: #db1536;
- }
- @media screen and (max-width: 500px) {
- .container {
- width: 290px;
- }
- .game-content ul {
- padding:;
- }
- .game-content li {
- margin-left: 5px;
- width: 90px;
- }
- .game-content div {
- margin-left: 20px;
- }
- }
- @-webkit-keyframes mouse-move {
- 50% {
- margin-top: -40px;
- opacity:;
- }
- 100% {
- margin-top: -15px;
- opacity:;
- }
- }
- @keyframes mouse-move {
- 50% {
- margin-top: -40px;
- opacity:;
- }
- 100% {
- margin-top: -15px;
- opacity:;
- }
- }
- .game-content div.active {
- -webkit-animation: mouse-move 2s ease-in-out infinite;
- animation: mouse-move 2s ease-in-out infinite;
- }
完整CSS
JS的处理
逻辑是点击开始游戏,倒计时开始,同时好坏老鼠不断运动,控制好坑中好坏老鼠及其数量的随机性,点击好老鼠加分,点击坏老鼠减分,时间到结束游戏。
先看看老鼠的运动
- // 运动操作
- moveUpAndDown: function() {
- var that = this;
- // 定时器随机定义good|bad老鼠个数,以及需要显示的个数
- that.moveTime = setInterval(function() {
- for (var i = 0, j = that.mouses.length; i < j; ++i) {
- that.mouses[i].setAttribute('clicked', '0');
- that.mouses[i].className = 'good active';
- that.mouses[i].style.display = 'none';
- }
- // bad 的个数
- var badNum = that.getRandom(0, 8);
- for (var i = 0; i < badNum; i++) {
- that.mouses[that.getRandom(0, 8)].className = 'bad active';
- }
- // 要显示的个数
- var showNum = that.getRandom(0, 8);
- for (var i = 0; i < showNum; i++) {
- that.mouses[that.getRandom(0, 8)].style.display = 'block';
- }
- }, 2000);
- },
使用定时器,定时器的循环与CSS中的动画设置一致,保证循环连贯性
设置class为good 即可定义出一只好老鼠,同理bad 为坏老鼠
在开始游戏,进行调用时,设置class为active 即可让老鼠运动起来
对于打老鼠的操作,要注意到只有运动的老鼠才能点击,每只老鼠只能点击一次
- // 打地鼠操作
- that.mousesWrap[0].addEventListener('click', function(e) {
- e = e || window.event;
- var elem = e.target || e.srcElement;
- // 如果当前项被隐藏则不操作,多次点击只取第一次分数
- if (elem.style.display !== 'block' || elem.getAttribute('clicked') === '1') {
- return;
- }
- // 扣分
- if (elem.className.indexOf('bad') !== -1) {
- that.score -= that.badScore;
- }
- // 加分
- else {
- that.score += that.goodScore;
- }
- elem.setAttribute('clicked', '1');
- that.text(that.gameScore[0], that.score);
- }, false);
倒计时结束之后,清除两个计时器,同时将所有老鼠项display都设为none 即可(否则动画会一直循环展示出来)
- // 倒计时,当前剩余游戏时间
- countDown: function() {
- var that = this;
- var t = setInterval(function() {
- that.text(that.gameTime[0], --that.totalTime);
- if (that.totalTime === 0) {
- clearInterval(t);
- clearInterval(that.moveTime);
- for (var i = 0, j = that.mouses.length; i < j; ++i) {
- that.mouses[i].style.display = 'none';
- }
- alert('游戏结束,得分为:' + that.score);
- }
- }, 1000);
- },
- function MouseGame() {
- this.mousesWrap = this.$('.game-content');
- this.mouses = this.$('.game-content div');
- this.gameStart = this.$('#game-start');
- this.gameTime = this.$('#game-time');
- this.gameScore = this.$('#game-score');
- this.goodScore = 100;
- this.badScore = 50;
- this.bindEvent();
- }
- MouseGame.prototype = {
- constructor: MouseGame,
- /**
- * 获取元素
- * @param {String} elem 元素的字符串标识
- * @example
- * $('div') | $('p.active')
- * @return {NodeList} 获取的元素集
- */
- $: function(elem) {
- return document.querySelectorAll(elem);
- },
- /**
- * 获取给定范围的随机数
- * @param {Number} from 起始
- * @param {Number} to 结束
- * @return {Number} 随机数
- */
- getRandom: function(from, to) {
- return Math.floor(Math.random() * (to - from + 1)) + from;
- },
- /**
- * 设置元素内容
- * @param {HTMLElement} elem 要设置的元素
- * @param {String} val 设置的内容
- * @return {String} 设置好的内容|元素本身的内容
- */
- text: function(elem, val) {
- if (elem.textContent) {
- return val !== undefined ? elem.textContent = val : elem.textContent;
- } else if (elem.innerText) {
- return val !== undefined ? elem.innerText = val : elem.innerText;
- }
- },
- // 运动操作
- moveUpAndDown: function() {
- var that = this;
- // 定时器随机定义good|bad老鼠个数,以及需要显示的个数
- that.moveTime = setInterval(function() {
- for (var i = 0, j = that.mouses.length; i < j; ++i) {
- that.mouses[i].setAttribute('clicked', '0');
- that.mouses[i].className = 'good active';
- that.mouses[i].style.display = 'none';
- }
- // bad 的个数
- var badNum = that.getRandom(0, 8);
- for (var i = 0; i < badNum; i++) {
- that.mouses[that.getRandom(0, 8)].className = 'bad active';
- }
- // 要显示的个数
- var showNum = that.getRandom(0, 8);
- for (var i = 0; i < showNum; i++) {
- that.mouses[that.getRandom(0, 8)].style.display = 'block';
- }
- }, 2000);
- },
- // 打地鼠操作
- bindEvent: function() {
- var that = this;
- // 监听游戏开始/重新开始
- that.gameStart[0].addEventListener('click', function() {
- that.startGame();
- }, false);
- // 打地鼠操作
- that.mousesWrap[0].addEventListener('click', function(e) {
- e = e || window.event;
- var elem = e.target || e.srcElement;
- // 如果当前项被隐藏则不操作,多次点击只取第一次分数
- if (elem.style.display !== 'block' || elem.getAttribute('clicked') === '1') {
- return;
- }
- // 扣分
- if (elem.className.indexOf('bad') !== -1) {
- that.score -= that.badScore;
- }
- // 加分
- else {
- that.score += that.goodScore;
- }
- elem.setAttribute('clicked', '1');
- that.text(that.gameScore[0], that.score);
- }, false);
- },
- // 倒计时,当前剩余游戏时间
- countDown: function() {
- var that = this;
- var t = setInterval(function() {
- that.text(that.gameTime[0], --that.totalTime);
- if (that.totalTime === 0) {
- clearInterval(t);
- clearInterval(that.moveTime);
- for (var i = 0, j = that.mouses.length; i < j; ++i) {
- that.mouses[i].style.display = 'none';
- }
- alert('游戏结束,得分为:' + that.score);
- }
- }, 1000);
- },
- // 开始游戏
- startGame: function() {
- this.score = 0;
- this.totalTime = 60;
- this.text(this.gameTime[0], this.totalTime);
- this.text(this.gameScore[0], this.score);
- this.countDown();
- this.moveUpAndDown();
- }
- };
- new MouseGame();
完整JS
代码有注释应该不难看懂了
那么..快来fork吧..
无聊的人用JS实现了一个简单的打地鼠游戏的更多相关文章
- Unity 2D游戏开发高速入门第1章创建一个简单的2D游戏
Unity 2D游戏开发高速入门第1章创建一个简单的2D游戏 即使是如今,非常多初学游戏开发的同学.在谈到Unity的时候.依旧会觉得Unity仅仅能用于制作3D游戏的. 实际上.Unity在2013 ...
- 通过创建一个简单的骰子游戏来探究 Python
在我的这系列的第一篇文章 中, 我已经讲解如何使用 Python 创建一个简单的.基于文本的骰子游戏.这次,我将展示如何使用 Python 模块 Pygame 来创建一个图形化游戏.它将需要几篇文章才 ...
- 用canvas和原生js写的一个笨鸟先飞的小游戏(暂时只有一个关卡)
其中一个画布背景是一张图片,还有小鸟,两个管子的图片.暂时不知道怎么附上去就不添加了.这里只有源代码,css和js都是在html写着的,感觉比他们的容易吧,hah <!DOCTYPE html& ...
- 利用前端三大件(html+css+js)开发一个简单的“todolist”项目
一.介绍 todolist,即待办事项.在windows android ios上参考微软家出的那个To-Do应用,大概就是那样的.我这个更简单,功能只有“待办” “已完成”两项,并且是在浏览器打开的 ...
- react.js+easyui 做一个简单的商品表
效果图: import React from 'react'; import { Form, FormField, Layout,DataList,LayoutPanel,Panel, Lab ...
- js写的一个简单的手风琴菜单
1 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&q ...
- 原生js写的一个简单slider
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 用JS写的一个简单的时钟
没什么技术含量,单纯的想传上去.手痒了 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- Cocos2dx系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)
懒骨头(http://blog.csdn.com/iamlazybone) 或许有天 我们羡慕和崇拜的人 因为我们的努力 也会来了解我们 说不定 还会成为好友 骨头喜欢这样与哲哲共勉 多少个夜晚 一张 ...
随机推荐
- Opencv算法学习二
1.直方图:图片中像素值分布情况的坐标图. 直方图均衡化:按一定规律拉伸像素值,提高像素值少的点,增加原图的对比度,使人感觉更清晰的函数. equalizeHist( src, dst ); 2.ha ...
- Eclipse自动补全设置
如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为ecl ...
- 基于Redis的开源分布式服务Codis
Redis在豌豆荚的使用历程--单实例==>多实例,业务代码中做sharding==>单个Twemproxy==>多个Twemproxy==>Codis,豌豆荚自己开发的分布式 ...
- 解读2015年互联网UGC内容发展态势,安全事件频发
<2015内容安全年报> 阿里移动安全 第一章 2015年内容安全形势 随着互联网业务的迅速发展,互联网上的信息内容带来了爆炸式的增长.由于缺乏对网络活动进行有效监督和管理的措施,致使互联 ...
- 将asp.net core站点发布到IIS上遇到的问题
今天第一次将整个 asp.net core 站点发布到 IIS 上,以前都是发布到 Linux 服务器上. 开始使用 dotnet publish -c release 命令发布,用浏览器访问站点时出 ...
- AnguarJS 第一天----Hello World
AngularJS是什么? AngularJS是目前很火的前端JS框架之一, AngularJS的开发团队将其描述为一种构建动态Web应用的结构化框架.它是完全使用JavaScript编写的客户端技术 ...
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之二lock方法分析
前一篇博客简单介绍了ReentrantLock的定义和与synchronized的区别,下面跟随LZ的笔记来扒扒ReentrantLock的lock方法.我们知道ReentrantLock有公平锁.非 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (42) ------ 第八章 POCO之使用POCO
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第八章 POCO 对象不应该知道如何保存它们,加载它们或者过滤它们.这是软件开发中熟 ...
- 在微软伪静态处理机制下action导致伪静态的地址重现的问题
伪静态前的地址:/sc/ProductList.aspx?pClass=0&descType=2&minPrice=1&maxPrice=11 伪静态后的地址:/product ...