[Canvas]游戏增加怪物爆炸效果,改善箭头形状
请点此下载代码并用浏览器打开试玩。
图例:
代码:
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <head> <title>地图加载 英雄可以射箭了 怪物爆炸 19.3.7 7:59 by:逆火狂飙 horn19782016@163.com</title> <style> #canvas{ background:#ffffff; cursor:pointer; margin-left:10px; margin-top:10px; -webkit-box-shadow:3px 3px 6px rgba(0,0,0,0.5); -moz-box-shadow:3px 3px 6px rgba(0,0,0,0.5); box-shadow:3px 3px 6px rgba(0,0,0,0.5); } #controls{ margin-top:10px; margin-left:15px; } </style> </head> <body onload="init()"> <div id="controls"> <input id='animateBtn' type='button' value='开始'/> </div> <canvas id="canvas" width="160px" height="160px" > 出现文字表示你的浏览器不支持HTML5 </canvas> </body> </html> <script type="text/javascript"> <!-- var paused=true; animateBtn.onclick=function(e){ paused=! paused; if(paused){ animateBtn.value="开始"; }else{ animateBtn.value="停止"; window.requestAnimationFrame(animate); } } var ctx;// 绘图环境 var r;// 表盘半径 var terrain; var hero; var arrows; var monsterMng; function init(){ // init Canvas var canvas=document.getElementById('canvas'); r=160; canvas.width =2*r; canvas.height=2*r; ctx=canvas.getContext('2d'); terrain=new Terrain(); hero=new Hero(); arrows=new Array(); monsterMng=new MonsterMng(); // 响应键盘事件 canvas.addEventListener('keydown', doKeyDown, true); canvas.focus(); window.addEventListener('keydown', doKeyDown, true); }; function draw(){ // Clear Canvas ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); ctx.fillStyle="#ECF5FF"; ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height); terrain.paint(ctx); monsterMng.paint(ctx); hero.paint(ctx); for(var i=arrows.length-1;i>-1;i--){ var arrow=arrows[i]; var x=parseInt(arrow.x / 32,10); var y=parseInt(arrow.y / 32,10); // 箭矢射中怪物所在 if(monsterMng.getValue(x,y)==1){ monsterMng.setValue(x,y,2); arrows.splice(i,1); break; } // 箭矢射中树木房屋等障碍物 if(terrain.getValue(x,y)!=0){ arrows.splice(i,1); } } // 画箭矢 for(var i=0;i<arrows.length;i++){ var arrow=arrows[i]; arrow.paint(ctx); } // 胜利条件 if(monsterMng.hasMonster()==false){ alert("You win!"); init(); } } function animate(){ if(!paused){ draw(); window.requestAnimationFrame(animate); /// 让浏览器自行决定帧速率 } } function doKeyDown(e) { var keyID = e.keyCode ? e.keyCode :e.which; if(keyID === 38 || keyID === 87) { // up arrow and W hero.move('up'); e.preventDefault(); } if(keyID === 39 || keyID === 68) { // right arrow and D hero.move('right'); e.preventDefault(); } if(keyID === 40 || keyID === 83) { // down arrow and S hero.move('down'); e.preventDefault(); } if(keyID === 37 || keyID === 65) { // left arrow and A hero.move('left'); e.preventDefault(); } if(keyID === 32 ) { // SpaceBar var a=new Arrow(hero.x+16,hero.y+16,hero.direction); arrows.push(a); console.log('arrows.length='+arrows.length); e.preventDefault(); } } //---------------------------------------------------地形类定义开始------------------------------------------------------------------->> Terrain=function(){ this.files=["road.png","tree.png","home.png"]; this.maps=new Array( [0,0,0,0,0,0,0,0,0,0], [0,0,1,1,1,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,2,2,2,2,2,2,2,0], [0,0,0,0,0,0,2,0,0,0], [0,0,0,2,0,0,2,0,0,0], [0,0,0,2,0,0,0,0,0,0], [0,2,2,2,2,2,2,2,0,0], [0,0,0,0,0,0,0,0,0,0], [0,1,1,1,1,1,1,1,1,0], ); } Terrain.prototype={ files:[], // Property maps:0, // method paint:function(ctx){ for(var i=0;i<this.maps.length;i++){ var arr=this.maps[i]; for(var j=0;j<arr.length;j++){ var value=arr[j]; var img=new Image(); img.src=this.files[value]; ctx.drawImage(img,i*32,j*32); } } }, getValue:function(i,j){ if(i<0 || i>=this.maps.length){ return undefined; } var arr=this.maps[i]; if(j<0 || j>=arr.length){ return undefined; } var value=arr[j]; return value; }, setValue:function(i,j,value){ if(i<0 || i>=this.maps.length){ return undefined; } var arr=this.maps[i]; if(j<0 || j>=arr.length){ return undefined; } arr[j]=value; }, } //---------------------------------------------------地形类定义结束-------------------------------------------------------------------<< //---------------------------------------------------英雄类定义开始------------------------------------------------------------------->> Hero=function(){ this.pngs=[ {left:0,top:10,width:40,height:40}, {left:0,top:66,width:40,height:40}, {left:0,top:120,width:40,height:40}, {left:0,top:180,width:40,height:40}, ]; } Hero.prototype={ pngs:[], x:160, y:160, xTo:160, yTo:160, step:32, direction:'up', paint:function(ctx){ var img=new Image(); img.src='bowman.png'; var index=0; if(this.direction=='up'){ index=3; } if(this.direction=='down'){ index=0; } if(this.direction=='left'){ index=1; } if(this.direction=='right'){ index=2; } var pos=this.pngs[index]; ctx.drawImage(img,pos.left,pos.top,pos.width,pos.height,this.x,this.y,pos.width,pos.height); }, move:function(direction){ this.direction=direction; if(this.direction=='up'){ this.yTo-=this.step; } if(this.direction=='down'){ this.yTo+=this.step; } if(this.direction=='left'){ this.xTo-=this.step; } if(this.direction=='right'){ this.xTo+=this.step; } if(terrain.getValue(this.xTo/this.step,this.yTo/this.step)==0){ this.x=this.xTo; this.y=this.yTo; }else{ this.xTo=this.x; this.yTo=this.y; } } } //---------------------------------------------------英雄类定义结束-------------------------------------------------------------------<< //---------------------------------------------------箭矢类定义开始------------------------------------------------------------------->> Arrow=function(x,y,direction){ this.x=x; this.y=y; this.direction=direction; } Arrow.prototype={ x:0, y:0, velocity:1,// 飞行速度 len:16,// 箭杆长 direction:'', // method paint:function(ctx){ var x1=this.x,y1=this.y; var leaf=4;//箭头箭羽长 var x2,y2,x3,y3; var angle=getRad(15); if(this.direction=='up'){ this.y-=this.velocity; y1=this.y-this.len; x1=this.x; y2=y1+leaf*Math.cos(angle); x2=x1-leaf*Math.sin(angle); y3=y2; x3=x1+leaf*Math.sin(angle); } if(this.direction=='down'){ this.y+=this.velocity; y1=this.y+this.len; x1=this.x; y2=y1-leaf*Math.cos(angle); x2=x1-leaf*Math.sin(angle); y3=y2; x3=x1+leaf*Math.sin(angle); } if(this.direction=='left'){ this.x-=this.velocity; x1=this.x-this.len; y1=this.y; x2=x1+leaf*Math.cos(angle); y2=y1-leaf*Math.sin(angle); x3=x2; y3=y1+leaf*Math.sin(angle); } if(this.direction=='right'){ this.x+=this.velocity; x1=this.x+this.len; y1=this.y; x2=x1-leaf*Math.cos(angle); y2=y1-leaf*Math.sin(angle); x3=x2; y3=y1+leaf*Math.sin(angle); } ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "#ff0000"; ctx.lineTo(this.x,this.y); ctx.lineTo(x1,y1); ctx.lineTo(x2,y2); ctx.lineTo(x3,y3); ctx.lineTo(x1,y1); ctx.stroke(); ctx.closePath(); }, } //---------------------------------------------------箭矢类定义结束-------------------------------------------------------------------<< //---------------------------------------------------怪物管理类定义开始------------------------------------------------------------------->> MonsterMng=function(){ this.files=["","skull.png","bomb.png",]; this.maps=new Array( [0,0,0,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0,1,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0,1,0], [0,0,0,0,0,0,0,0,0,0], ); } MonsterMng.prototype={ files:[], // Property maps:[], // method paint:function(ctx){ for(var i=0;i<this.maps.length;i++){ var arr=this.maps[i]; for(var j=0;j<arr.length;j++){ var value=arr[j]; if(value!=0){ var img=new Image(); img.src=this.files[value]; ctx.drawImage(img,i*32,j*32); } } } }, // 判断怪物还是否存在 hasMonster:function(){ var count=0; for(var i=0;i<this.maps.length;i++){ var arr=this.maps[i]; for(var j=0;j<arr.length;j++){ var value=arr[j]; if(value==1){ count++;// 累计怪物数 } } } // 怪物数大于零就是还有怪物 return count>0; }, getValue:function(i,j){ if(i<0 || i>=this.maps.length){ return undefined; } var arr=this.maps[i]; if(j<0 || j>=arr.length){ return undefined; } var value=arr[j]; return value; }, setValue:function(i,j,value){ if(i<0 || i>=this.maps.length){ return undefined; } var arr=this.maps[i]; if(j<0 || j>=arr.length){ return undefined; } arr[j]=value; }, } //---------------------------------------------------怪物管理类定义结束-------------------------------------------------------------------<< // 常规函数:角度得到弧度 function getRad(degree){ return degree/180*Math.PI; } //--> </script>
2019年3月7日08点50分
[Canvas]游戏增加怪物爆炸效果,改善箭头形状的更多相关文章
- Atitit 游戏引擎---物理系统(1)------爆炸效果
Atitit 游戏引擎---物理系统(1)------爆炸效果 1.1. 动画框架的来源flex,jqueryuijs,anim , cocos2d 1 1.2. Jqueryui的特效库 1 1.3 ...
- jQuery 打气球小游戏 点击气球爆炸效果
最近在学习前端,看到偶尔看到前端小游戏,就想自己写一个小游戏,奈何水平有限,只能写打气球这种简单的,所有的气球都是动态生成的,气球的颜色也是随机的 html部分 <div class=" ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- Java坦克大战 (五) 之产生敌方坦克和爆炸效果
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- canvas游戏小试:画一个按方向键移动的圆点
canvas游戏小试:画一个按方向键移动的圆点 自己对canvas,但又有一颗做游戏的心TT.然后记录一下对canvas的学习吧,用一个按方向键控制的小圆点来做练习.(编程时用了一些es6的语法) ...
- [一位菜鸟的COCOS-2D编程之路]打飞机中机种敌机和战机损毁时的爆炸效果
1.第一步,添加爆炸动画 //添加玩家飞机飞行动画 id _playerFlyAction; id _playerBlowupAnimation; //战机爆炸动画 id _enemyBlowupAn ...
- WPF编游戏系列 之七 动画效果(2)
原文:WPF编游戏系列 之七 动画效果(2) 上一篇已经对关闭窗口图标进行了动画效果处理,本篇将对窗口界面的显示和关闭效果进行处理.由于所有的动画效果都是针对窗口界面的Canvas,所以 ...
- WPF编游戏系列 之六 动画效果(1)
原文:WPF编游戏系列 之六 动画效果(1) 本篇主要针对界面进行动画效果处理.首先在打开或关闭界面时,使其产生动态效果而不是生硬的显示或消失(如下图).其次在鼠标放到关闭窗口图标上时, ...
- 【CSS】398- 原生JS实现DOM爆炸效果
爆炸动效分享 前言 此次分享是一次自我组件开发的总结,还是有很多不足之处,望各位大大多提宝贵意见,互相学习交流. 分享内容介绍 通过原生js代码,实现粒子爆炸效果组件 组件开发过程中,使用到了公司内部 ...
随机推荐
- CentOS 7.x,不重新编译 PHP,动态安装 imap 扩展
先前的教程:PHP5不重新编译,如何安装自带的未安装过的扩展,如soap扩展? # 安装依赖包 yum install -y libc-client-devel /usr/local/src/cent ...
- php简单浏览目录内容
<?php $dir = dirname(__FILE__); $open_dir = opendir($dir); echo "<table border=1 borderCo ...
- windows nginx出现 was not signaled for 5s的看过来
windows下 nginx 配置ssl的key是不能存储密码的,否则启动时会提示输入密码 输入后也启动不起来,会报错: 2011/04/18 09:49:09 [alert] 1992#4548: ...
- 关于iosApp审核问题
求各位大神指导!!!!我上周app打包上传给APPstore准备发布,可是苹果官方发来邮件,说我引用了非公有选择,原文如下: Non-public API usage: The app referen ...
- 【Devops】【docker】【CI/CD】Jenkins自动安装JDK需要提供Oracle的账号密码,否则报错:Unable ro auto-install JDK until the license is accepted
Jenkins自动安装JDK需要提供Oracle的账号密码,否则报错:Unable ro auto-install JDK until the license is accepted 解决方法: ...
- Glibc 和 uClibc
转自:https://blog.csdn.net/clirus/article/details/50145959?locationNum=4 最近在搞mips openwrt框架的东西,mipc的GC ...
- Java 与 Json的互相转换
这几天一直在做Java解析Json数据的一个项目,因为初识json,所以很多东西都是有着懵懂的认识.这里写下我解析时遇到的问题和收获. 我解析json时用到的是json-lib包.下载地址:http: ...
- 解决VS2010连接VSS时,Access to file"\\***\rights.dat" denied
1.通过VS2010打开项目链接VSS后,提示 Access to file"\\***\rights.dat" denied. 该提示是指没有网络访问的权限,用户要在共享文件夹有 ...
- Material Designer的低版本兼容实现(八)—— Flat Button
除了中规中矩的矩形按钮外,5.0中将按钮扁平化,产生了一个扁平按钮——Flat Button.这个按钮降低了很多存在感,主要用于在对话框,提示栏中.让整个界面减少层级.今天说的就是它的用法. 这 ...
- Shape画圆形控件
这里涉及到shape的运用,这仅仅是一个实例 circle.xml <?xml version="1.0" encoding="utf-8"?> & ...