《HTML5游戏编程核心技术与实战》一1.2 HTML5新特性初探

简介: 准备好HTML5开发工具之后,我都迫不急待地想看看HTML5给我们带来了哪些让人激动不已的新特性,相信,你也会和我一样,对它感到兴奋。由于HTML5新增加了很多元素,这里,我们重点简单介绍一下在游戏中会使用到的一些元素,在介绍每一个新的元素时,我都会列举一些小的例子。

本节书摘来异步社区《HTML5游戏编程核心技术与实战》一书中的第1章,第1.2节,作者: 向峰 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.2 HTML5新特性初探

HTML5游戏编程核心技术与实战
准备好HTML5开发工具之后,我都迫不急待地想看看HTML5给我们带来了哪些让人激动不已的新特性,相信,你也会和我一样,对它感到兴奋。由于HTML5新增加了很多元素,这里,我们重点简单介绍一下在游戏中会使用到的一些元素,在介绍每一个新的元素时,我都会列举一些小的例子。现在假定读者有一定的HTML以及JavaScript方面的知识,如果您对这些代码完全不清楚,没关系,后面的章节中会详细地解说。目前,我们只需要知道HTML5能做什么就足够了。

1.2.1 canvas元素

canvas是HTML5中一个非常重要的元素,canvas元素提供了硬件加速机制,能够让我们实现高效的绘图功能。第2章我们会详细介绍canvas功能,这里,我们先来领略一下canvas的魅力。

打开你的编辑工具,输入以下代码:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<style type="text/css">
 body, div{margin:0px;padding:0px;text-align:center}
 #cav{
  border:2px solid black;
  border-radius:4px;
  box-shadow:0px 0px 10px black;
  -webkit-box-shadow:0px 0px 10px black;
  -moz-box-shadow:0px 0px 10px black;
 }
 #bk{
  margin:10px auto;
  width:400px;
  height:36px;
 }
 .bk{
  text-align:center;
  width:20px;
  height:20px;
  margin:12px;
  display:inline-block;
  border:1px dotted gray;
 }
</style>
<body>
<div id="bk" align="center"></div>
<canvas id="cav" width="400" height="300"></canvas>
</body>
<script src="../js/jquery.js"></script>
<script charset="utf-8">   
//定义画笔颜色
var bColor = ["#000000", "#999999", "#CC66FF", "#FF0000", "#FF9900", "#FFFF00",   
           "#008000", "#00CCFF"]; 
//当前画笔颜色
var col="#FF0000";
function initBrush()
{
 for(var i=0;i<bColor.length;i++)
 {
  var bk = $("<span class='bk'></span>")
   .css("background-color", bColor[i])
   .click(function(){
    col = $(this).css("background-color");
   });
  $("#bk").append(bk)
 } 
}
function initPainter()
{
  //绑定绘图canvas
   var can = $("#cav"), self = this, x=0, y=0;
   var ctx = can[0].getContext("2d");
   ctx.lineWidth = 2;
   //绑定鼠标按下时间
   can.on("mousedown", function(e){    
    e.preventDefault();
    ctx.strokeStyle = col;
    x = e.offsetX, 
    y = e.offsetY;
    //开始路径
    ctx.beginPath();
    ctx.moveTo(x, y);   
    //绑定鼠标移动事件
    can.on("mousemove", function(e){
     var nx = event.offsetX, 
        ny = event.offsetY;
     ctx.lineTo(x, y);
     ctx.stroke();   
     x = nx;
     y = ny;
    });
    //绑定鼠标抬起事件
    can.on("mouseup", function(){
      //取消鼠标移动事件
    can.off("mousemove");
    });
   })
}
$(document).ready(function(){
 initBrush();
 initPainter();
})
</script>
</html>

虽然有点长,但当你完成它的时候,我想,一定不会让你失望的,这是一个不错的开始,也许现在你可能还看不太懂,没关系,第2章就会对canvas元素进行详细介绍。以上代码通过canvas元素完成了一个在浏览器中使用的画板,可以通过Chrome浏览器打开它,看到的效果如图1-9所示,你可以选择不同颜色的画笔在画板上进行涂鸦。


1_19

1.2.2 WebGL

除了支持2D渲染技术外,canvas还提供了通过WebGL的方式,利用硬件加速提供3D渲染技术。以下代码使用了开源的three.js的3D引擎,完成了一个简单的旋转方块,注意,该3D效果完全使用WebGL技术,不需要安装任何插件。顺便说一下,three.js是一款完全免费使用的3D引擎,该引擎完全基于WebGL编写,事实上WebGL也是在canvas上进行渲染,目前对WebGL支持比较好的浏览器有Chrome、Firefox以及Safari等。

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Cube</title>
 <script src="../js/jquery.js"></script>
 <!--引入Three.js-->
 <script src="three.min.js"></script>
</head>
<style type="text/css">
 body, div{margin:0px;padding:0px;text-align:center}
 #sce{
  border:2px solid black;
  border-radius:4px;
  width:480px;
  height:320px;
  margin:10px auto;
  box-shadow:0px 0px 10px black;
  -webkit-box-shadow:0px 0px 10px black;
  -moz-box-shadow:0px 0px 10px black;
 }
</style>
<body>
<div id="sce"></canvas>
<script>
  $(document).ready(function(){
   init();
  })
  //定义3D场景,摄像机光源等和立方体
  var scene, cam, render, cube, light;
  //初始化
  function init()
  {
   initScene();        
   initCube();
   animate();
  }
  function initScene()
  {
   scene = new THREE.Scene();
   cam = new THREE.PerspectiveCamera(45, $("#sce").width()/$("#sce"). height(), 0.1, 2000);
   cam.position.x= cam.position.y = cam.position.z=2;
   cam.lookAt(new THREE.Vector3(0, 0, 0 ));
   render = new THREE.WebGLRenderer({antialias:true});
   render.setSize($("#sce").width(), $("#sce").height());
   $("#sce").append(render.domElement);
  }
  function initCube()
  {
   //加载纹理 
   var text = THREE.ImageUtils.loadTexture( 'box.gif' );
   text.anisotropy = render.getMaxAnisotropy();
   //创建几何图形和材质
   var g = new THREE.CubeGeometry(1, 1, 1), 
      m = new THREE.MeshBasicMaterial({ map: text });        
   cube = new THREE.Mesh(g, m);
   scene.add(cube);
  }
  function animate()
  {
   requestAnimationFrame(animate);
   cube.rotation.y += Math.PI/180;
   render.render(scene, cam);
  }        
</script>
</body>
</html>

整个代码实现了一个绕Y轴旋转的方块,最好使用Chrome浏览器进行浏览,运行效果如图1-10所示。


1_10

当然,对于代码的细节暂时可以不用去关注,目前,我们只需要知道使用WebGL能做什么就足够了,对于目前的HTML5来说,2D的游戏将会是比3D更好的选择。

1.2.3 多媒体元素

正如我们所期待的一样,HTML5中增加了两个多媒体元素以及

比如,以下代码可以直接在浏览器中播放mp3音频文件。

<!DOCTYPE html>
<meta charset="utf-8" />
<style type="text/css">
 body{text-align:center;}
</style>
<body>
  <h2>简单的音视频</h2>
  <audio id="a1" src="media/scg.mp3" autoplay mediagroup="gp" controls>
   您的浏览器不支持audio元素
  </audio><br>
</body>
</html>

在浏览器中可以看到一个带有简单控制面板的音频播放器,如图1-11所示。


1_11

1.2.4 地理信息服务

HTML5提供了一组关于地理信息的API,通过这组API我们可以获取到客户端所在的经度和纬度,利用这些信息可以向这个坐标附近的区域提供服务。这些服务一般指的是基于位置的服务(LBS),LBS能够广泛支持需要动态地理空间信息的应用,从寻找旅馆、急救服务到导航,从社交游戏到生活服务,几乎可以覆盖生活中的所有方面。常见的一些LBS的应用有:位置信息查询、急救服务、道路辅助与导航、社交游戏等。

借助HTML提供的Geolocation API功能,很容易获取到用户当前的位置,结合这组API,我们可以编写基于LBS的社交类游戏。

同样地,我们给出一段简单的代码,可以获取用户所在的位置信息。

<!DOCTYPE html>
<html>
 <head>
  <title> Location </title>
  <meta charset="utf-8" />
 </head>
 <body>
  <input type="button" id="btnLocation" value="获取位置信息"/>
 </body>
 <script src="js/jquery.js"></script>
 <script>   
   //检测是否支持地理信息
   function isSupportGeo()
   {
    return (navigator.geolocation!=null)
   }   
   //绑定click事件
   $("#btnLocation").click(function(){
    if(!isSupportGeo())
    {
     alert("浏览器不支持地理位置定位!");
    }
    else
    {
      navigator.geolocation.getCurrentPosition(doSucc, doFail); 
    }
   });
   //处理成功
   function doSucc(position)
   {
    // alert("成功获取地理位置!");
    alert("成功获取地理位置,您当前所处的位置位于经度:"+position.coords.longitude+"   
       纬度:"+position.coords.latitude); 
   }
   //处理失败
   function doFail(error)
   {
    var errors=["拒绝地理信息服务", "获取不到地理信息", "获取信息超时"]
    alert(errors[error.code+1]);
   }
 </script>
</html>

代码绑定一个“获取位置信息”的按钮,单击按钮将会调用isSupportGeo方法检测浏览器是否支持地理信息,如果支持的话就调用getCurrentPosition获取当前设备的地理信息。需要注意的是,第一次访问地理信息的时候由于个人隐私的问题,浏览器会弹出一个窗口询问用户是否允许让浏览器访问自己的位置,用户可以选择接受或者拒绝,如果拒绝的话将会得到一个错误。

1.2.5 本地存储

我们知道在传统的Web应用程序开发过程中,当客户端和服务器进行数据交互时,远程服务器需要存储客户端的各种数据,如果需要在客户端保留数据,可以采用“Cookie”的形式,但Cookie的存储量很小,通常只有4 kB,而且安全性和使用性都还有所欠缺。为了能够满足于HTML5本地应用的迅速发展,弥补HTML在本地数据持久化的弱势,HTML5推出了新的本地存储规范,提供了容量更大、更安全和更易于使用的本地存储方案。

HTML5中使用Web Storage技术进行本地存储,能够在Web客户端进行数据存储。Web Storage曾经属于HTML5的规范,目前已经被独立出来形成单独的规范体系。简单来说使用Web本地存储类似于HashMap一样,采用键值对的形式保存数据,而且保存的数据会根据需要持久化在浏览器所在的客户端,具体来说Web Storage又可以分为以下两种。

localStorage。将数据保存在客户端本地的硬件设备(通常指硬盘,但也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问网站时仍然可以继续使用。
sessionStorage。将数据保存在session对象中。session对象就是会话对象,session中存储的数据独立于每个客户,该数据会随着浏览器的关闭而消失。
这两者的区别在于,sessionStorage为临时保存,而localStorage为永久保存。localStorage提供了5 MB的存储空间,而sessiongStorage甚至没有限制,取决于内存的大小。

对于这两种本地存储对象都可以使用以下方法进行数据存取。

setItem(key, value)。使用键值对的方式保存数据,key为键,value为值,键是一个字符串,而数据则可以是任何类型的JavaScript基本数据类型,包括字符串、Boolean、整数和浮点数。需要注意的是,这些数据在存储时实际上是以字符串保存的。因此在访问数据时需要进行数据类型的转换,也可以直接用localStorage.key = value或者localStorage[key] = value的方式设置,对于复杂的数据类型,可以使用JSON格式的对象转换成字符串对象存储。
getItem(key)。根据key键值来获取数据,也可以直接用localStorage.key或者localStorage[key]获取,需要注意的是,这些数据在取出来时实际上是字符串。因此在访问数据时需要进行数据类型的转换。

removeItem(key)。清除key键值。

clear()。清除所有的键值对。

例如,以下简单的代码用于记录用户访问页面的总次数:

<body>  
  <h2>您是第<span id="ct"></span>次访问本页面</h2>
</body>
<script>
  $(document).ready(function(){
   //获取访问次数
   readCount();
  })
  //获取访问次数
  function readCount()
  {
   var count = localStorage["count"];
      if(count==null){count=1;}
      else {count = Number(count)+1;}
      $("#ct").text(count);
   localStorage["count"] = count;
  }
</script>

上面代码中记录了用户访问页面次数,第一次访问时,获取的count为空,设置其为1,随后的访问中获取数据后通过Number函数转成数字进行累加并重新设置到localStorage中。需要注意的是,即使关闭浏览器,下次打开时,数据依然存在,因为localStorage的数据实际上持久化在本地文件中。

1.2.6 Web sockets网络通信

一直以来,HTTP的无状态性和单向性作为常用的应用已经足够,但还无法实现游戏中需要的实时双向通信技术,而HTML5中新增加的WebSocket通信元素则弥补了这一缺陷,使用新的Web sockets技术对于实现高效的Web网络游戏提供了基础。

我们可以使用以下代码连接支持Web sockets协议的服务器端,并发送数据。

var ws = new WebSocket(“ws://localhost:9000/socket”);
ws.onopen = function(){
 try 
 {
  ws.send(“Hello, Web Socket”);
 }
 catch(e)
 {
   console.log(“发送消息失败!”);
 } 
}

当然,需要注意的是,以上只是使用WebSocket元素的客户端代码,需要有支持WebSocket协议的服务器端支持,在本书的第5章会详细介绍使用WebSocket的客户端以及Node.js的服务器端通信技术。

1.2.7 Web Worker多线程

Web Worker技术填补了JavaScript中一直所缺少的多线程技术,之前的HTML中,进行DOM元素渲染以及执行JavaScript脚本都是在单一的线程中执行,一旦在JavaScript中需要执行比较耗时间的操作,则会阻塞当前线程的执行。所带来的效果就是,当前的浏览器处于无响应状态,直到浏览器会弹出一个提示脚本运行时间过长的信息。这里,我们看一个简单的例子。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<style type="text/css">
 body, div{margin:0px;padding:0px;text-align:center}
</style>
<body>
 <input type="button" id="btn_calc" value="计算圆周率" />
 <input id="txt_rt" />
</body>
<script src="../js/jquery.js"></script>
<script charset="utf-8">   
 $(document).ready(function(){
  $("#btn_calc").on("click", function(){
    $("#txt_rt").val(getPI(80000000));
   }) 
 })
 //求圆周率
 function getPI(n)
 {
  var a=0;
  for (i=0;i<=n;i++)
  { 
   a = a + 4*Math.pow(-1, i)/(2*i+1);  
  }
   return a;
 }
</script>
</html>

在该例子中,提供了一个通过级数获取圆周率的函数,参数n表示迭代次数,次数越高,计算越精确。然后提供一个按钮计算圆周率在文本框中显示,在浏览器中运行,我们发现当迭代次数很高的时候,计算量较大,在得到计算结果之前,按钮和文本框都是处于无法响应的状态,这也符合实际情况,因为此时DOM元素的更新被大计算量的程序给阻塞了。如果使用Web Worker则不会出现此情况,我们可以把计算量大的工作放到一个单独的线程中运行,不会阻塞当前线程。

创建后台线程可以使用以下方式:

var worker = new Worker(“worker.js”)
我们把计算工作放到worker.js文件中,前台可以通过postmessage方法发送消息给Worker线程,请求Worker进行工作,直到Worker线程工作完毕返回结果。

对于前面计算PI的例子,我们可以修改如下,首先,创建worker.js文件,代码如下:

function getPI(n)
{
 var a=0;
 for (i=0;i<=n;i++)
 { 
  a = a + 4*Math.pow(-1, i)/(2*i+1);  
 }
  return a;
}
onmessage = function(e)
{
  var result = getPI(e.data);
  postMessage(result);
}

worker.js文件中定义了计算PI的函数,我们需要定义一个onmessage函数,当前台通过调用worker对象的postmessage方法时,该回调函数被响应。

然后,把显示结果的页面修改如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<style type="text/css">
 body, div{margin:0px;padding:0px;text-align:center}
</style>
<body>
 <input type="button" id="btn_calc" value="计算圆周率" />
 <input id="txt_rt" />
</body>
<script src="../js/jquery.js"></script>
<script charset="utf-8">   
 $(document).ready(function(){
  $("#btn_calc").on("click", function(){
   var wk = new Worker("worker.js");
    //注册返回结果,当woker发送postmessage时,该回调函数响应 
    wk.onmessage = function(e)
    {
     $("#txt_rt").val(e.data);
    }
    //发送计算请求
    wk.postMessage(80000000);
   }) 
 }) 
</script>
</html>

这里,首先创建了一个Worker对象,然后在Workder对象中注册一个onmessage回调函数。注意,这个回调函数和workder.js文件中的onmessage是不同的,这里的回调函数当woker.js文件中的onmessage函数执行完毕后响应,最后,调用Worker对象的postMessage方法发送计算请求,此时,woker.js文件中的onmessage函数就会执行。

修改成Worker版本后,你会发现,当单击按钮得到计算结果之前,按钮和文本框都是可以响应的,因为此时计算线程被独立出来了。

相关文章
|
1月前
|
XML 编解码 前端开发
编程笔记 html5&css&js 033 HTML SVG
编程笔记 html5&css&js 033 HTML SVG
|
8天前
|
前端开发 搜索推荐 数据安全/隐私保护
HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
18 1
|
20天前
|
人工智能 前端开发 JavaScript
【前端设计】HTML+CSS+JavaScript基本特性
【前端设计】HTML+CSS+JavaScript基本特性
|
1月前
|
存储 移动开发 编解码
html5的新特性详解
HTML5是构建和呈现互联网内容的语言描述方式,HTML5在HTML4的基础上增加了许多新特性,使其更具语义化、更加标准化,同时也提高了用户体验和开发效率。以下是HTML5的部
|
1月前
|
移动开发 定位技术 API
编程笔记 html5&css&js 035 HTML 地理定位
编程笔记 html5&css&js 035 HTML 地理定位
|
1月前
|
XML 移动开发 数据格式
编程笔记 html5&css&js 034 HTML MathML
编程笔记 html5&css&js 034 HTML MathML
|
1月前
|
前端开发 JavaScript 容器
编程笔记 html5&css&js 032 HTML Canvas
编程笔记 html5&css&js 032 HTML Canvas
|
1月前
|
Web App开发 前端开发 安全
编程笔记 html5&css&js 031 HTML视频
编程笔记 html5&css&js 031 HTML视频
|
13天前
|
前端开发 JavaScript 开发工具
【HTML/CSS】入门导学篇
【HTML/CSS】入门导学篇
21 0