接着上一篇(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. 记一次debug记录:Uncaught SyntaxError: Unexpected token ILLEGAL

    在使用FIS3搭建项目的时候,遇到了一些问题,这里记录下. 这里是发布搭建代码: // 代码发布时 fis.media('qa') .match('*.{js,css,png}', { useHash ...

  2. 梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画

    CSS动画并不是绝对比JavaScript动画性能更优越,开源动画库Velocity.js等就展现了强劲的性能. 一.两者的主要区别 先开门见山的说说两者之间的区别. 1)CSS动画: 基于CSS的动 ...

  3. 随手记_C#验证码

    前言 最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果: 总体来说效果还是可以的,官方提供的SDK也比较详细,可配置性很高.在这里在简单啰嗦几句使用方式: 使用步骤 ...

  4. Django

    一.Django 简介 Django 是一个由 Python 写成的开放源代码的 Web 应用框架.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) ...

  5. MongoDB系列(一):简介及安装

    什么是MongoDB MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为应用提供可扩展的高 ...

  6. stringstream的基本用法

    原帖地址:https://zhidao.baidu.com/question/580048330.htmlstringstream是字符串流.它将流与存储在内存中的string对象绑定起来.在多种数据 ...

  7. ActiveRecord模式整理

    DAO Data Access Object,数据访问对象 DAO是一个软件设计的指导原则,在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象 ...

  8. celery使用的一些小坑和技巧(非从无到有的过程)

    纯粹是记录一下自己在刚开始使用的时候遇到的一些坑,以及自己是怎样通过配合redis来解决问题的.文章分为三个部分,一是怎样跑起来,并且怎样监控相关的队列和任务:二是遇到的几个坑:三是给一些自己配合re ...

  9. MementoPattern(备忘录模式)

    /** * 备忘录模式 * @author TMAC-J * 用于存储bean的状态 */ public class MementoPattern { public class Memento{ pr ...

  10. 如何使用SHOW WARNINGS?

    1.show warnings:显示上一个语句的错误.警告以及注意.如图: