接着上一篇(http://www.cnblogs.com/zhouhuan/p/H5_tankgame.html),这一篇研究一下怎么响应玩家的操作让坦克进行相应的移动。
 
  1. 了解keydown事件
  keydown这一键盘事件的触发条件为按下键盘上的任意键,如果按住不放,则会重发触发。
  示例:
window.onkeydown = function(){
alert("Merry Christmas!");
};
  此时载入页面之后,无论按下哪个键,都会弹出“Merry Christmas!”的弹窗。
 
  2. 了解键码和字符编码
 
  ① 键码
  在发生keydown和keyup事件时,event对象的keyCode(键码)属性会包含一个代码,与键盘上一个特定的键对应。对于数字字母字符集,keyCode属性的值与ASCII码中对应小写字母或数字的编码相同。字母中的大小写不影响。
window.onkeydown = function(eve){
alert(eve.keyCode);
};
  此时按键盘上的任意键,便可得到所按键对应的keyCode
  
  ② 字符编码
  发生keypress事件时,event对象的charCode属性会包含一个值,这个值就是按下的那个键所代表字符的ASCII编码,并且,同一个字母的大小写对应的字符编码也是不一样的。
  要注意的是,keypress事件只有在按下字符键时才会触发,并不是所有的按键,像Ctrl, Alt之类的就不会触发该事件。
 
  3. 热身环节
 
  ① 获取玩家的指令
  我们先看看怎么获取到玩家的操控指令,这里我们写一段代码:
window.onkeydown = function(eve){
alert("所按键对应的键码是: " + eve.keyCode);
};
  大家运行一下就可以知道键盘上每一个按键所对应的键码是多少了,然后取自己需要的按键继续编写程序。这里需要的是方向键的上下左右,当然这个在网上可以查到,也非常方便。
  我们运行了之后会发现,上下左右对应的键码分别是38, 40, 37, 39。考虑到有些玩家习惯于使用W A S D来操作,那我们把这几个键也做进去,这几个键对应的键码分别是87, 65, 83, 68。
  OK,知道了上面这些东西之后我们就可以写出下面这段代码了:
window.onkeydown = function(eve){
if(eve.keyCode == 38 || eve.keyCode == 87){
alert("上");
}else if(eve.keyCode == 40 || eve.keyCode == 83){
alert("下");
}else if(eve.keyCode == 37 || eve.keyCode == 65){
alert("左");
}else if(eve.keyCode == 39 || eve.keyCode == 68){
alert("右");
}
};
  此时,根据玩家的操作便能弹出相应方向的文字。
  鉴于上面if语句的条件分支数量略多,我们最好用switch语句改写一下上面的代码,这样可以提高性能,如下:
window.onkeydown = function(eve){
switch(eve.keyCode){
case 38:
case 87:
alert("上");
break;
case 40:
case 83:
alert("下");
break;
case 37:
case 65:
alert("左");
break;
case 39:
case 68:
alert("右");
}
};
  ② 封装画坦克的函数
  前面我们写的画坦克的代码其实是面向过程的,我们将它拿过来改巴改巴做以封装:
function drawTank(x,y){
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.fillStyle = "#542174";
cxt.fillRect(x,y,20,65);
cxt.fillRect(x+70,y,20,65);
cxt.fillRect(x+23,y+10,44,50);
cxt.fillStyle = "#FCB827";
cxt.beginPath();
cxt.arc(x+45,y+35,16,0,2*Math.PI,false);
cxt.closePath();
cxt.fill();
cxt.strokeStyle = "#FCB827";
cxt.lineWidth = "8.0";
cxt.moveTo(x+45,y+35);
cxt.lineTo(x+45,y-25);
cxt.stroke();
}
  这个函数调用的时候传两个参数(x, y),分别代表坦克左上角的X坐标,Y坐标。
  封装好之后,在任何地方只要一调用,便可以造出一个坦克了:
drawTank(150,200);        //以(150,200)的点为坦克的左上角(左边履带的左上角)造一个坦克
 
  ③ 了解clearRect()方法
  有一个前面遗漏掉的知识点clearRect()方法,这个方法是做游戏的关键,用来清空指定矩形内的所有像素,传四个参数(x, y, width, height),前两个参数表示要清除的矩形的左上角坐标,后两个参数表示要清除的矩形的宽高。
  比如我们先画一个矩形:
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.fillStyle = "orange";
cxt.fillRect(50,50,300,80);

得到:

  我们再加上下面这句代码运行一下:
cxt.clearRect(0,0,800,500);
  此时会发现整个画布又空空如也了,因为我们把整个画布的像素都清除掉了。
 
  4. 热身完毕,正式开始
  前面热身热了这么久,相信大家已经可以写出一个根据玩家的操作移动的坦克了。
  我们尽量以面向对象的思想来写每一个过程,代码如下:
//封装一个获取绘图环境的函数
function getCxt(){
var myCanvas = document.getElementById('floor'),
myContext = myCanvas.getContext('2d');
return myContext;
} //封装一个画坦克的函数,传两个参数x,y,分别代表左上角的横纵坐标
function drawTank(x,y){
var cxt = getCxt();
cxt.fillStyle = "#542174";
cxt.fillRect(x,y,20,65);
cxt.fillRect(x+70,y,20,65);
cxt.fillRect(x+23,y+10,44,50);
cxt.fillStyle = "#FCB827";
cxt.beginPath();
cxt.arc(x+45,y+35,16,0,2*Math.PI,false);
cxt.closePath();
cxt.fill();
cxt.strokeStyle = "#FCB827";
cxt.lineWidth = "8.0";
cxt.moveTo(x+45,y+35);
cxt.lineTo(x+45,y-25);
cxt.stroke();
} //初始化一个对象myTank,用来存储一些属性和方法
var myTank = {};
myTank.x = 350;
myTank.y = 400;
myTank.step = 3; //设置步长,步长越大那么坦克运动的速度越快 //先画一个坦克出来
drawTank(myTank.x,myTank.y); //封装一个更新战场的函数
function updateFloor(){
var cxt = getCxt();
cxt.clearRect(0,0,800,500); //更新之前先清除画布
drawTank(myTank.x,myTank.y); //清除完之后重新造坦克,坦克要移动就必须实时地根据坐标重新来造
} //设置一个间歇调用的函数,每隔100ms更新一下战场
setInterval(function(){
updateFloor();
},100); //响应玩家的操作指令
window.onkeydown = function(eve){
switch(eve.keyCode){
case 38:
case 87:
myTank.y -= myTank.step; //Y坐标减小向上移动
break;
case 40:
case 83:
myTank.y += myTank.step; //Y坐标增加向下移动
break;
case 37:
case 65:
myTank.x -= myTank.step; //X坐标减小向左移动
break;
case 39:
case 68:
myTank.x += myTank.step; //X坐标增加向右移动
}
};
  所有必要的说明都已经写在了注释中。这样写出来之后,我们发现坦克已经可以随着玩家的按键上下左右移动了,但是还存在一点问题,坦克运动起来非常的生硬,不管向哪个方向动它的头一直都是朝上的,我们必须在这个基础上做以修改,下篇待续...

H5坦克大战之【玩家控制坦克移动】的更多相关文章

  1. 《杜增强讲Unity之Tanks坦克大战》3-添加坦克

    3 添加坦克 3.1 本节效果预览   3.2 另存新场景 首先打开上次的场景s1,另存为s2,放到同一个文件夹下面.   3.3 添加坦克模型 在Model文件夹下面找到Tank模型   将Tank ...

  2. cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测

    上篇我们完成了简单的AI编写,但是各个坦克移动时之间是可以重合的, 这节课我们来完成坦克之间的碰撞检测,还是在上篇的EnemyAI中完成. 1.我先现在坦克类Tank中添加两个成员变量: CC_SYN ...

  3. cocos2d-x游戏开发系列教程-坦克大战游戏之敌方坦克AI的编写

    在上篇我们完成了子弹和地图碰撞的检测,在这篇我们将完成敌方坦克AI的编写. 具体思路是屏幕中保持有四个敌方坦克,然后坦克随机方向运动,并且子弹消失后1秒发射一次 1.我们新建一个敌方坦克的AI类来控制 ...

  4. 【 java版坦克大战--事件处理】 让坦克动起来--事件处理的准备

    要能够控制坦克运动,必须用到事件处理的知识. 事件处理的一个demo. /** * 事件处理机制:委派事件模型.指当事件发生的时候,产生事件的对象(事件源),会把此 * "消息"传 ...

  5. H5坦克大战之【玩家控制坦克移动2】

    周一没有看圣诞大战,这几天比较忙也没有看赛后的报道,今天就先不扯NBA,随便扯扯自己.昨天在电脑里找东西的时候翻到以前兼职健身教练时的照片,思绪一下子回到学生时代,脑子久久换不过来.现在深深觉得健身和 ...

  6. 《杜增强讲Unity之Tanks坦克大战》11-游戏流程控制

    11 游戏流程控制 使用协程来控制游戏流程 11.1 添加MessageText 首先添加一个Text来显示文字   image 设置GameMgr   image 11.2 游戏整体流程 下面Gam ...

  7. 《杜增强讲Unity之Tanks坦克大战》10-相机控制

    10 相机控制 本节主要学习如何控制相机自动调整位置和焦距,使两个坦克一直同时在视野内.   image 在Hierarchy点击右键   image 点击 Create Empty,生成空对象,改名 ...

  8. html5制作坦克大战

    全部html5都采用绘图技术完成.坦克是画出来的.(坦克,子弹,墙,水,草坪) 首先我们画出坦克. 坦克是两边两个矩形,中间一个大矩形,矩形了有一个圆,还有一根线. 画出坦克的思路是以坦克的左上角为参 ...

  9. 阶段学习总结-坦克大战(2D)案例

    这是前几天学习的案例,这两天学习了NGUI和UGUI,被UI搞得很烦躁,但是今天还是将前几天学习的坦克大战总结以下.这个游戏是小时候的经典红白机游戏的复刻,见截图: 一.游戏物体 游戏中包含地图元素( ...

随机推荐

  1. Azkaban源码学习笔记

    1. ConnectorParams (interface): 定义了各种常量参数,没有声明任何方法. 2. ExecutorServlet.java类   2.1 继承类HttpServlet和接口 ...

  2. CoreCRM 开发实录 —— Profile

    再简单的功能,也需要一坨代码的支持.Profile 的编辑功能主要就是修改个人的信息.比如用户名.头像.性别.电话--虽然只是一个编辑界面,但添加下来,涉及了6个文件的修改和7个新创建的文件.各种生成 ...

  3. 04.SQLServer性能优化之---读写分离&数据同步

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 过段时间再继续写文章吧,本来准备把SQLServer一个系列写完的,最近状态很差很不好, ...

  4. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  5. 谈谈一些有趣的CSS题目(七)-- 消失的边界线问题

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  6. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

  7. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  8. gulp初学

    原文地址:gulp初学 至于gulp与grunt的区别,用过的人都略知一二,总的来说就是2点: 1.gulp的gulpfile.js  配置简单而且更容易阅读和维护.之所以如此,是因为它们的工作方式不 ...

  9. H3 BPM产品安装手册(.Net版本)

    1         安装说明 1.1    服务器安装必备软件 在使用该工作流软件之前,有以下一些软件是必须安装: l  IIS7.0以上版本(必须): l  .Net Framework 4.5(必 ...

  10. 页面与ViewModel(下)

    在上一篇博客中,笔者分享了一些从页面整体的角度对页面与ViewModel的思考.在本文中笔者希望从相对细节的角度分享一些对页面与ViewModel的思考. 比如,当我们在更新View Model中的绑 ...