一直想用canvas写一个魂斗罗游戏,但是发现自己水平和学习能力差太多,收集好素材之后发现一个棍子英雄的小游戏挺火,就产生了写本文这个游戏的想法。直接上demo,建议在chrome下:点我。

简单说下写这个小游戏遇到的2个坑爹问题:

1.之前下的素材music.mp3这个文件,其实是3段音频。最后几秒是魂斗罗结束时的音乐,我想在结束的时候直接从调用最后几秒的音频。查了一下audio,很容易找到了audio的currentTime这个属性可以设置音频的播放位置。但是我本地测试的过程中,这个属性是一直不起作用的。后来百度(百度根本不好用),谷歌了半天才在stackoverflow上找到了一段描述,大概的意思就是需要一个sever环境,然后把测试环境放到了服务器环境就可以正常使用currentTime这个属性设置音频的播放起始位置了,一个大坑。

2.第二个大坑平时写transition的时候习惯的将transition-property写为all。比如transition:all 0s ease 0s;。在这个游戏中,当鼠标松开的时候棍子应该是以100% 100%的位置为远点进行旋转的。由于我写的是all,所以transfor-origin也产生了一个从默认的50% 50%到100% 100%的一个过渡过程,反应在页面上就是棍子开始明显转动的远点不是100% 100%的位置,但是动画完成到100%的时候原点是正确的。

剩下的就是逻辑实现,本来是想做到自适应和重置游戏的,最后多少都有点不足,重置游戏直接用刷新页面的暴力方式来解决了。页面有很多bug,不行就刷一次,哈哈。

直接上代码:

html部分:

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title>Child'sPlay</title><link href="style/style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="main" id="main"><div id="score">当前得分<i class="current">0</i>分;最高得分<i class="top">0</i>分</div><div class="bg"><div class="move" id="move"><div class="game-box" id="game_box"><div class="contra" id="contra"></div><div class="item" style="left: 0;"><div class="land"><div class="stick" id="stick"></div> </div></div></div></div></div>
</div>
<div class="loading"><progress id="progress" value="0" max="8"></progress><h3>游戏方法:按住鼠标让棍子变长,使其放下的时候正好落入下一块陆地时放开鼠标。</h3>
</div>
<div class="begin"><h3><i>点</i><i>击</i><i>键</i><i>盘</i><i>J</i><i>开</i><i>始</i><i>游</i><i>戏</i></h3>
</div>
<audio id="audio"><source src="audio/start.mp3" type="audio/mpeg"/>
</audio>
<audio id="audio2"><source src="audio/music.mp3" type="audio/mpeg"/>
</audio>
<audio id="audio3"><source src="audio/Game_Over.mp3" type="audio/mpeg"/>
</audio>
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/contra.js"></script>
<script src="js/source.js"></script>
<script src="js/record.js"></script>
</body>
</html>

css代码:

*{ margin: 0; padding: 0;}
body{ overflow: hidden;}
.loading{ position: absolute; left: 0; top: 0; right: 0; bottom: 0; z-index: 2; background: #000;}
#progress{ width: 100%; height: 200px;border: 1px solid #0064B4;background-color:#e6e6e6;}
progress::-webkit-progress-bar { background: #e6e6e6; }
progress::-webkit-progress-value  { background: #0064B4; }
.loading h3{ text-align: center; color: #fff;}.begin{ position: absolute; width: 100%; background: url("img/begin.jpg") 0 0 no-repeat; z-index: 3;}
.begin h3{ display: none; position: absolute; left: 0; top: 20px; width: 100%; text-align: center; color: #fff;}
.begin h3 i{-webkit-animation: slide_letters 1.8s linear 1s infinite;-moz-animation: slide_letters 1.8s linear 1s infinite;-ms-animation: slide_letters 1.8s linear 1s infinite;animation: slide_letters 1.8s linear 1s infinite}
.main{ position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden;}
#score{ position: absolute; left: 0; top: 50px; width: 100%; text-align: center; color: #fff;}
#score i{ color: red;}
.main .bg{ background: url("img/bg.png") 0 0 repeat-x;}
.land{ position: relative; float: left; background: url("img/land.png") 0 0 no-repeat; background-size: 100% 100%;}
.move{ position: relative; left: 0;}
.game-box{ position: fixed; bottom: 5%; width: 99999px;}
.game-box .item{ position: absolute; top: 0;}
#audio{ display: none; position: fixed; right: 20px; top: 20px;}
.contra{ background: url("img/contra.png"); width: 97px; height: 109px; position: absolute; left: 0; bottom: 65%; z-index: 9;}
.stick{ position: absolute; right: 0; bottom: 65%; width: 2px; background: gold; z-index: 99;}
.rolling{ transition: transform 1s ease-in 0s;transform-origin:center bottom; -webkit-transform-origin:center bottom; -webkit-transform: rotate(90deg); transform: rotate(90deg); }.run{ width: 87px; height: 110px; background: url("img/run.png") 0px center no-repeat; overflow: hidden;-webkit-animation:run 1s steps(8) infinite;animation:run 1s steps(8) infinite;}@-webkit-keyframes run{100%{background-position: -696px 0px;}
}
@keyframes run{100%{background-position: -696px 0px;}
}.begin h3 i:nth-child(1) {-webkit-animation-delay: 0.2s;-moz-animation-delay: 0.2s;-ms-animation-delay: 0.2s;animation-delay: 0.2s;
}.begin h3 i:nth-child(2) {-webkit-animation-delay: 0.4s;-moz-animation-delay: 0.4s;-ms-animation-delay: 0.4s;animation-delay: 0.4s;
}.begin h3 i:nth-child(3) {-webkit-animation-delay: 0.6s;-moz-animation-delay: 0.6s;-ms-animation-delay: 0.6s;animation-delay: 0.6s;
}
.begin h3 i:nth-child(4) {-webkit-animation-delay: 0.8s;-moz-animation-delay: 0.8s;-ms-animation-delay: 0.8s;animation-delay: 0.8s;
}
.begin h3 i:nth-child(5) {-webkit-animation-delay: 1s;-moz-animation-delay: 1s;-ms-animation-delay: 1s;animation-delay: 1s;
}
.begin h3 i:nth-child(6) {-webkit-animation-delay: 1.2s;-moz-animation-delay: 1.2s;-ms-animation-delay: 1.2s;animation-delay: 1.2s;
}
.begin h3 i:nth-child(7) {-webkit-animation-delay: 1.4s;-moz-animation-delay: 1.4s;-ms-animation-delay: 1.4s;animation-delay: 1.4s;
}
.begin h3 i:nth-child(8) {-webkit-animation-delay: 1.6s;-moz-animation-delay: 1.6s;-ms-animation-delay: 1.6s;animation-delay: 1.6s;
}
.begin h3 i:nth-child(9) {-webkit-animation-delay: 1.8s;-moz-animation-delay: 1.8s;-ms-animation-delay: 1.8s;animation-delay: 1.8s;
}
@-webkit-keyframes slide_letters {0%,50% { color: #fff; }25% { color: red;}
}
@-moz-keyframes slide_letters {0%,50% { color: #fff; }25% { color: red;}
}@-ms-keyframes slide_letters {0%,50% { color: #fff; }25% { color: red;}
}
@keyframes slide_letters {0%,50% { color: #fff; }25% { color: red;}
}

进度条加载source.js

var gameSource = {"bg":"style/img/bg.png","contra":"style/img/contra.png","land":"style/img/land.png","run":"style/img/run.png","begin":"style/img/begin.jpg"
};var loadNum = 0;function loading(){for(i in gameSource){var obj = new Image();obj.src = gameSource[i];//console.log(gameSource[i])obj.onload = function(){console.log(this.src+"   completed");//gameSource.splice(i,1);loadNum++;$("#progress").attr({"value":loadNum});};}
}
loading()var matchState = [1,1,1];
function checkState(){var audioReadyState = [$("#audio")[0].readyState,$("#audio2")[0].readyState,$("#audio3")[0].readyState];if(loadNum==8){$("#progress").attr({"value":loadNum});clearInterval(checkStateTimer);contraHero.begin();$("#audio")[0].play();}for(var i=0; i<audioReadyState.length;i++){if(audioReadyState[i]==4 && matchState[i]){matchState[i] = 0;console.log("test",i,audioReadyState,matchState)loadNum++;console.log(audioReadyState);}}
}
var checkStateTimer = setInterval(checkState,1000);//var a = [];
//alert(~a); // -1
//alert(+a); // 0
//alert(++a); // 1
//alert(!a); // false

localStorage保存得分记录

if(localStorage.TopScore){$("#score .top").html(localStorage.TopScore);
}
function writeTopScore(score){if(!localStorage.TopScore || score > localStorage.TopScore){localStorage.TopScore = score;$("#score .top").html(localStorage.TopScore);}
}

contraHero主体逻辑代码

var contraHero = {canPlay : false,isOn:false,//标记按住鼠标dom : {contra : $("#contra"),stick : $("#stick"),main : $("#main"),bg : $(".bg"),move : $("#move"),gameBox : $("#game_box"),audio : $("#audio"),audio2 : $("#audio2"),item : $("#game_box .item")},data : {landWidth : 0, //适配后一个陆地的宽度landHeight :0 , //适配后一个陆地的高度stickHeight:0, //棍子长度stickLong : "", //棍子边长定时器currentItem : 0, //魂斗罗当前所在的item索引itemPosition : [[0,1]]  //每片陆地的left值和对应的陆地数},init : function(){this.initEvent();this.initUnit();this.makeNextLand();this.mainTitle();},//getLastPositionLeft : function(){//    var n = contraHero.data.itemPosition.length-1;//    return contraHero.data.itemPosition[n][0] + contraHero.data.itemPosition[n][1]*contraHero.data.landWidth;//},makeNextLand : function(){var left = parseInt(Math.random()*500) + contraHero.data.itemPosition[contraHero.data.itemPosition.length-1][1] * contraHero.data.landWidth+ contraHero.data.itemPosition[contraHero.data.itemPosition.length-1][0];console.log(contraHero.data.itemPosition[contraHero.data.itemPosition.length-1][1] * contraHero.data.landWidth,contraHero.data.itemPosition[contraHero.data.itemPosition.length-1][0],left,"left")var landNo = parseInt(Math.random()*3)+1;contraHero.data.itemPosition.push([left,landNo]);var str = '';for(var i=0;i<contraHero.data.itemPosition[contraHero.data.itemPosition.length-1][1];i++){str +='<div class="land" style="width:'+contraHero.data.landWidth+'px;height:'+contraHero.data.landHeight+'px;">'+'</div>';};str ='<div class="item" style="left:'+contraHero.data.itemPosition[contraHero.data.itemPosition.length-1][0]+'px;height:'+contraHero.data.landHeight+'px;">'+str+'</div>';contraHero.dom.gameBox.append(str);},increase : function(){if(contraHero.isOn){contraHero.data.stickLong = setInterval(function(){contraHero.data.stickHeight +=3;$("#stick").css({"height":contraHero.data.stickHeight+"px"})},20)}},initEvent : function(){$(window).mousedown(function(){contraHero.isOn = true;contraHero.data.stickHeight = 0;contraHero.increase()});$(window).mouseup(function(){contraHero.isOn = false;contraHero.data.stickHeight = $("#stick").height();clearInterval(contraHero.data.stickLong);contraHero.putDownStick();});$(window).resize(function(){contraHero.initEvent();contraHero.initUnit();});},initUnit : function(){var screenHeight = contraHero.dom.main.height();var ratio = screenHeight/489;var bgSizeWidth = parseInt(1284*ratio);contraHero.data.landWidth = parseInt(34*ratio);contraHero.data.landHeight = parseInt(122*ratio);var gameBoxHeight = contraHero.dom.gameBox.height();contraHero.dom.bg.css({"background-size":bgSizeWidth+"px "+screenHeight+"px","height":screenHeight+"px"});$(".land").css({"width":contraHero.data.landWidth+"px","height":contraHero.data.landHeight+"px"});contraHero.dom.gameBox.css({"height":contraHero.data.landHeight+"px"});$(".begin").css({"background-size":"100% "+screenHeight+"px","height":screenHeight+"px","left":"100%"});contraHero.begin();},check : function(){var min = contraHero.data.itemPosition[contraHero.data.currentItem+1][0] - contraHero.data.itemPosition[contraHero.data.currentItem][0]- contraHero.data.itemPosition[contraHero.data.currentItem][1] * contraHero.data.landWidth;var max = min + contraHero.data.itemPosition[contraHero.data.currentItem+1][1] * contraHero.data.landWidth;console.log(contraHero.data.currentItem,min,max,contraHero.data.stickHeight)if(contraHero.data.stickHeight >=min && contraHero.data.stickHeight <= max){return true;}else{return false;}},begin: function () {$(".begin").css({"background-size":"100% "+screen.height+"px","height":screen.height+"px","left":"100%"});$(".begin").animate({"left":"0"},6400,function(){$(".loading").remove();$(".begin h3").show();$(document).on("keyup",function(e){e = e || window.e;if(e.keyCode==74){console.log("testet")$(".begin").remove();contraHero.init();console.log("j")$(document).off("keyup");}})});},moveScreen : function(n){var distance = -contraHero.data.itemPosition[n][0]contraHero.dom.move.animate({"left":distance+"px"});contraHero.dom.bg.animate({backgroundPositionX:distance});},mainTitle:function(){contraHero.dom.audio2[0].play();contraHero.loopMainTitleTimer = setInterval(this.checkMainTitle,1000);},checkMainTitle:function(){var curTime = contraHero.dom.audio2[0].currentTime;contraHero.dom.audio2[0].play();if(curTime-64>=0){contraHero.dom.audio2[0].load();};},overMusic :function(){//contraHero.dom.audio2[0].pause();//contraHero.dom.audio2[0].currentTime = 140;//contraHero.dom.audio2[0].play();$("#audio3")[0].play();},putDownStick : function(){$("#stick").addClass("rolling");setTimeout(this.run,1000);},contraFixPosition : function(){contraHero.dom.contra.animate({"left":contraHero.data.itemPosition[contraHero.data.currentItem][0] + contraHero.data.itemPosition[contraHero.data.currentItem][1] * contraHero.data.landWidth -70 +"px"});console.log(contraHero.data.itemPosition[contraHero.data.currentItem][0],contraHero.data.itemPosition[contraHero.data.currentItem][1],"fix")},run : function(){contraHero.dom.contra.addClass("run");console.log(parseInt(contraHero.dom.contra.css("left")),contraHero.data.stickHeight,"wtf")contraHero.dom.contra.animate({"left":parseInt(contraHero.dom.contra.css("left"))+contraHero.data.stickHeight+"px"},5*contraHero.data.stickHeight,function(){if(contraHero.check()){contraHero.data.currentItem++;$("#score .current").html(contraHero.data.currentItem);writeTopScore(contraHero.data.currentItem);contraHero.contraFixPosition();contraHero.moveScreen(contraHero.data.currentItem);$("#stick").remove();contraHero.dom.contra.removeClass("run");contraHero.makeNextLand();contraHero.dom.gameBox.find(".item").eq(contraHero.data.currentItem).find(".land:last").html('<div class="stick" id="stick"></div>');}else{//contraHero.dom.contra.removeClass("run");////contraHero.reset();//contraHero.init();contraHero.killMusic();contraHero.overMusic();$("#stick").css({"transform":"rotate(180deg)"});$("#contra").animate({"top":"1000px"},7000,function(){location.reload();});}})},killMusic:function(){$("#audio")[0].pause();$("#audio2")[0].pause();$("#audio3")[0].pause();clearInterval(contraHero.loopMainTitleTimer);},reset : function(){contraHero.dom.contra.siblings(".item:gt(0)").remove();$("#stick").removeClass("rolling").removeAttr("style");contraHero.dom.contra.removeAttr("style");contraHero.dom.bg.css({"background-position-x":"0"});contraHero.dom.move.removeAttr("style");contraHero.data.stickHeight = 0;contraHero.data.itemPosition = [[0,1]];}
}

最后附上下载包,渣代码,见笑。ContraHero

转载于:https://www.cnblogs.com/childsplay/p/4184804.html

js实现魂斗罗版的棍子英雄小游戏ContraHero相关推荐

  1. Vue 开发一个简略版的飞机大战小游戏

    文章目录 使用 Vue 开发一个简略版的飞机大战小游戏 一.实现思路 二.所需知识点 三.实现步骤 使用 Vue 开发一个简略版的飞机大战小游戏 如题,假设你为了向更多访问你博客的人展示你的技术,你决 ...

  2. 基于Python pygame简易版斗兽棋小游戏源代码

    基于Python pygame简易版斗兽棋小游戏源代码 游戏规则如下: 胜利条件: 1.吃掉对方全部棋子 2.走入对方兽穴(不可进入自己洞穴) 吃法: 1.象>狮>虎>豹>狼& ...

  3. JAVA实现简易版【斗地主】小游戏

    JAVA实现简易版[斗地主]小游戏 gitee项目源码链接:https://gitee.com/xzq25_com/playcardtest 效果展示:快来人机对战吧 一 二 三

  4. 基于 Python 的横版 2D 动作类小游戏

    基于 Python 的横版 2D 动作类小游戏 游戏代码 游戏代码 游戏整体代码(基于 pygame 模块开发) // An highlighted block import pygame impor ...

  5. android内存修改 跳一跳,Android版微信跳一跳小游戏利用技术手段达到高分的操作方法...

    本文主要来讲个个好玩的东西,近来微信刚出的跳一跳微信小程序的游戏很火,看到很多人都达到了二三百分就各种刷朋友圈了. 甩手一个表情 最终我们达到的分数却是这样的: 羡慕吧 一定会有人拍手叫好," ...

  6. 云开发版合成大西瓜小游戏微信小程序源码 微信游戏小程序附带流量主功能

    这是一款云开发版的合成大西瓜小游戏微信小程序源码,微信游戏小程序源码.该小游戏玩法简单,只需要拖动同样的水果落下合成新品众的水果,最终合成大西瓜,玩法酷似俄罗斯方块,相当于换一种形式的俄罗斯方块,简单 ...

  7. 找回童年乐趣,在线玩超级玛丽、冒险岛、魂斗罗、坦克大战等经典游戏

    苏生不惑第252篇原创文章,将本公众号设为星标,第一时间看最新文章. 下周就是六一了,分享几个能让你找回童年乐趣的在线游戏. 怀旧游戏机 在线小霸王游戏机,威力无穷http://god.fhjo.cn ...

  8. 每个人都能制作的简易版狂拍灰太狼小游戏(HTML+CSS+JavaScript)

    自制系列一完善版来了. 如果在制作过程中有任何问题你都可以私信我,我会一一答复你们的. 由于上一次发的进度条不是很完善,显得不美观,这次改进了进度条问题,使增强了游戏的体验感.制作过程很简单,每个人都 ...

  9. canvas+js实现简单的双人坦克对战小游戏

    相信有很多人对坦克大战的游戏模仿很有兴趣,在实现经典的坦克大战之前,我先写了个双人的坦克对战,实现了基本的对战功能.下面就开始介绍游戏的编写. 首先创建一个基本的html文件,添加canvas标签以实 ...

最新文章

  1. 为什么我们的信标信号被干扰?
  2. python3 打印对象的全部属性
  3. 想学python从哪里入手-想要学习python,如何入手学习?
  4. boost::geometry::strategy::vincenty用法的测试程序
  5. python安装、anaconda安装、pycharm安装(学习笔记,自己重新整理后的内容,最新版本工具安装)
  6. JavaScript实现字符串转换成驼峰表示法
  7. interceptor 拦截器的使用 (session验证)
  8. 【Java】计算二进制数中1的个数
  9. canvas笔记-canvas加载图片及放缩及加水印(两canvas同时使用)
  10. 东北到底有没有互联网?!
  11. java final 变量 大小写_java – 为什么“final static int”可以用作开关的大小写常量但不是“final static”...
  12. win10锁定计算机命令,win10怎么锁定磁盘 锁住win10计算机磁盘的操作步骤
  13. 已经不能再简单的UE4中播放视频没有声音的解决方案
  14. ChineseLunisolarCalendar 农历日期
  15. hdu 3037 插板法组合 + lucas定理
  16. sketch html尺寸,sketch教程 | 设置常用画板尺寸
  17. 成功启动electron-egg项目,electron+vue的傻瓜式搭建
  18. 端到端说话人验证系统中长度归一化的分析
  19. 【JavaSE】继承 你拿下继承了吗?一篇让你轻松拿下,简明扼要,超详解
  20. 大学计算机实验六文件管理与磁盘恢复,虚拟实验:文件管理与磁盘恢复.pdf

热门文章

  1. Java Bean 简介及其应用
  2. Spring IoC容器以及Bean的创建过程
  3. 青春在为谁燃烧 梦想在为谁咆哮
  4. 有关win7 设备管理器空白,没有声音的问题
  5. Linux端口占用查询
  6. python输入姓名专业班级_Python — 学生成绩管理
  7. Python 利用栈质因数分解
  8. Python 中删除文件的几种方法
  9. 发现一个免费可用的股票实盘交易接口API,直接GET/POST请求,不用交易客户端
  10. Windows Server 2012 将【我的电脑】添加到桌面图标