html5全接触(二)–BounceBall小游戏简易教程

最近一段时间都比较忙,好久没更新博客了,遵循着“时间就像那啥,挤挤总会有的”的原则,承接着上一篇html5先关的博文,继续我们的趣味html5之旅。

前一段时间很流行用html5写小游戏,当了解了一些常用的api之后,你会发现,写一些简单的小游戏自娱自乐也不会那么困难,当然,做逻辑和界面复杂的游戏除外。以下会提供一个弹球小游戏的简单教程,希望感兴趣的朋友能在编码中找到一点乐趣。

<!– 注:以下demo木有神马高深的东东,大牛们觉得无味请略过。同时,由于砖块厚度与弹球的纵向变换单元的比例不协调,故没做砖块的侧向碰撞监测.. –> 

<!DOCTYPE html>
<html>
<head>
<style>
body {margin:0; position:absolute; width:100%; height:100%}
canvas {display: block; margin: 20px auto; border: 2px solid #333}
.info {width: 600px; margin: 0 auto; color: #666; text-align:center}
</style>
<script>
var Bombule = function () {
var ctx, x = 295, y = 385, dx = 2, dy = 4, W, H, rd = false, ld = false, pause = true, X, B = {},
rowColor = ["#FF1C0A", "#FFFD0A", "#00A308", "#0008DB", "#EB0093", "#00A308", "#0008DB", "#EB0093"];
var init = function (id) {
var canvas = document.getElementById(id);
W = canvas.width || 600;
H = canvas.height || 400;
X = (W-100)/2;
ctx = canvas.getContext('2d');
this.initBricks(8, 8);
this.run();
this.evListen();
}
init.prototype = {
run : function () {
var _this = this;
this.st = setInterval(function () {
_this.draw();
}, 16)
},
draw : function () {
this.clear();
this.circle(x, y, 8);
if (rd && !pause && X < W-this.paddleW) {X += 10} else if (ld && !pause && X > 0) {X -= 10}
this.paddle(X, 100);
this.drawBricks();
this.hitBrick(x, y);
if (x + dx > W || x + dx < 0) dx = -dx;
if (y + dy < 0) {dy = -dy} 
else if (y + dy > H-10) {
x > X-4 && x < X+this.paddleW+4   this.hitPaddle(x) : this.stop();
}
if (!pause) {
x += dx;
y += dy;
}
},
clear : function () {
ctx.clearRect(0, 0, W, H);
},
circle : function (x, y, r) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
},
rect : function (x, y, w, h) {
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.closePath();
ctx.fill();
},
stop : function () {
clearInterval(this.st);
this.showInfo('Game Over')
},
paddle : function (l, w) {
this.paddleW = w;
this.rect(l, H-10, w, 10);
},
evListen : function () {
document.addEventListener('keydown', function (e) {
if (e.keyCode == 39) rd = true;
else if (e.keyCode == 37) ld = true;
}, false);
document.addEventListener('keyup', function (e) {
if (e.keyCode == 39) rd = false;
else if (e.keyCode == 37) ld = false;
else if (e.keyCode == 32) pause  = !pause   true : false;
}, false);
},
initBricks : function (row, col) {
B.row = row;
B.col = col;
B.w = W/col - 1;
B.h = 15;
B.pad = 1;
B.bricks = new Array(row);
for (var i=0; i<row; i++) {
B.bricks[i] = new Array(col);
for (var j=0; j<col; j++) {
B.bricks[i][j] = 1;
}
}
},
drawBricks : function () {
for (var i=0; i<B.row; i++) {
ctx.fillStyle = rowColor[i];
for (var j=0; j<B.col; j++) {
B.bricks[i][j] === 1 && this.rect(j*(B.w+B.pad) + B.pad, i*(B.h+B.pad)+B.pad, B.w, B.h);
}
}
},
hitBrick : function (x, y) {
var rh = B.h + B.pad,
cw = B.w + B.pad,
row = Math.floor(y/rh),
col = Math.floor(x/cw);
if (y < B.row*rh && row >= 0 && col >= 0 && B.bricks[row][col] === 1) {
dy = -dy;
B.bricks[row][col] = 0;
}
},
hitPaddle : function (x) {
dy = -dy;
dx = 10 * ((x-(X+this.paddleW/2))/this.paddleW);
},
showInfo : function (text) {
ctx.font = '60pt Calibri';
ctx.fillStyle = '#999';
ctx.fillText(text, 130, 200);
}
}
return init;
}();
onload = function () {
new Bombule('canvas');
}
</script>
</head>
<body>
<canvas id="canvas" width="600" height="400">Your Broswer don't support html5 canvas</canvas>
<p class="info">空格-开始/暂停 | 方向键控制挡板左右</p>
<!--<audio src="http://www.w3schools.com/html5/horse.ogg" autoplay="true">
Your browser does not support the audio element.
</audio>-->
</body>
</html>

 <!DOCTYPE html>

<html>
<head>
<style>
body {margin:0; position:absolute; width:100%; height:100%}
canvas {display: block; margin: 20px auto; border: 2px solid #333}
</style>
  <script>
var init = function () {
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(200, 200, 8, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}
onload = init;
</script></head>
<body>
<canvas id="canvas" width="600" height="400">Your Broswer don't support html5 canvas<canvas>
</body>
</html>

 

技术文:微信小程序和服务器通信-WebSocket

本文主要讲一下如何建立一个基于node.js的WebSocket服务器,并在小程序中使用这个提供实时服务的服务器。

引用
H5程序俱乐部微信号:wxappclub

「H5程序俱乐部」是一个专注微信小程序学习交流,相关外包/招聘需求信息发布的微信公众号

每天发布微信小程序设计/开发/运维知识,小程序最新资讯,外包需求信息/相关人才招聘信息

node.js中已经有很多现成的第三方库,用于构建WebSocket服务。我们今天选用一个叫做websocket的库,来构建一个可以提供标准WebSocket接口的node.js服务端程序。

先建一个空文件夹,名叫ws-server,然后进入该文件夹,在命令行执行:

npm install websocket

然后在ws-server文件夹下,再新建一个名为app.js的文件,内容如下:

因为WebSocket服务是建立在HTTP之上的,所以我们看到,代码中建立了一个http server, 然后建立了一个使用了该http server的WebSocket server,并让http server监听8080端口对外提供服务。

这个服务端的功能也很简单,就是收到客户端发送的消息并打印出来,然后在接收到的消息前面加上一个[from server]的前缀后,返回给客户端。

好,我们来实现调用该服务的微信小程序代码:

首先我们需要用wx.connectSocket()方法去连接目标服务器,因为我们开发环境用的是非安全的http,所以这边的url参数是ws://打头的,在以后微信的实际运行环境中,你的服务端必须使用SSL,所以连接url就会是wss://的了。

然后需要调用wx.onSocketOpen()方法来设置WebSocket连接打开时的回调函数。当连接打开后,就可以开始向服务端发送数据了,我们在这里使用wx.sendSocketMessage()方法,向服务端发送了一个后面跟随一个随机数的Hello,World字符串。我们运行一下程序,可以看到,服务端的控制台上会打印出这样的结果:

说明服务端已经成功接收到了客户端发送的字符串消息。

之后服务端会向客户端再反馈这个消息,那客户端这边如何接收这个从服务端过来的消息呢?我们可以在小程序中,使用wx.onSocketMessage()方法,监听服务端发送到客户端的消息,正如我们上面的示例代码写的那样:

wx.onSocketMessage(function (msg) {     

    console.log(msg)

})

我们在小程序的Console上,简单的打印了从服务端过来的消息,如下所示:

这样,一个简单但完整的客户端和服务器端的WebSocket交互就完成了。如果你想关闭这个WebSocket连接,那么你可以调用wx.closeSocket()来进行关闭。

  • 大小: 279.6 KB
  • 大小: 22.8 KB
  • 大小: 5.3 KB
  • 大小: 17.3 KB

蘑菇游戏_熊碰撞蘑菇处理

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<script type="text/javascript" src="jquery-1.4.2.js"></script>
		<title>熊碰撞蘑菇处理</title>
		<script type="text/javascript">
		var backgroundImg=new Image();
		var mushroomImg=new Image();
		//定义一个熊
		var bearEyesClosedImg=new Image();
		var speed=2;//开始的速度
		var horizontalSpeed=speed;//水平速度
		var verticalSpeed=-speed;//垂直速度
		var bearAngle=2;//熊旋转速度
		var ctx;
		var screenWidth;
		var screenHeight;
		//定义游戏物体对象
		function GameObject(){
			this.x=0;
			this.y=0;
			this.image=null;
		}
		function Mushroom(){};
		Mushroom.prototype=new GameObject();//继承GameObject
		//定义一个熊Amimal继承GameObject
		function Animal(){};
		Animal.prototype=new GameObject();
		Animal.prototype.angle=0;//动物的角度,目前中(即作为动物它在屏幕上旋转退回)
		var animal=new Animal();//实例化一个熊
		var mushroom=new Mushroom();
		function gameLoop(){
			//清屏
			ctx.clearRect(0, 0, screenWidth, screenHeight);
			ctx.save();
			//绘制背景
			ctx.drawImage(backgroundImg,0,0);
			//绘制蘑菇
			ctx.drawImage(mushroom.image,mushroom.x,mushroom.y);
			animal.x+=horizontalSpeed;
			animal.y+=verticalSpeed;
			animal.angle+=bearAngle;
			ctx.translate(animal.x+(animal.image.width/2),animal.y+(animal.image.height/2));//转换画布的用户坐标系统。
			ctx.rotate(animal.angle*Math.PI/180);//旋转画布
			ctx.drawImage(animal.image,-(animal.image.width/2),-(animal.image.height/2));
			ctx.restore();
			HasAnimalHitEdge();
			HasAnimalHitMushroom();
		}
		function loadImages(){
			mushroomImg.src="mushroom.png";
			backgroundImg.src="forest1.jpg";
			bearEyesClosedImg.src="bear_eyesclosed.png";
			mushroom.image=mushroomImg;
			animal.image=bearEyesClosedImg;
		}
		function AddEventHandlers(){
			$("#container").mousemove(function(e){
				mushroom.x=e.pageX-(mushroom.image.width/2);
			});
		}
		//检测碰撞边界
		function HasAnimalHitEdge(){
			//熊碰到右边边界
			if(animal.x>screenWidth-animal.image.width){
				if(horizontalSpeed>0){
					horizontalSpeed=-horizontalSpeed;
				}
			}
			//熊碰到左边边界
			if(animal.x<-10){
				if(horizontalSpeed<0){
					horizontalSpeed=-horizontalSpeed;
				}
			}
			if(animal.y>screenHeight-animal.image.height){
				setTimeout(function(){
					horizontalSpeed=speed;
					verticalSpeed=-speed;
					animal.x=parseInt(screenWidth/2);
					animal.y=parseInt(screenHeight/2);
					gameLoop();
				},2000);
			}
			if(animal.y<0){
				verticalSpeed=-verticalSpeed;
			}
		}
		//检测2个物体是否碰撞
		function CheckIntersect(object1, object2, overlap){
			A1=object1.x+overlap;
			B1=object1.x+object1.image.width-overlap;
			C1=object1.y+overlap;
			D1=object1.y+object1.image.height-overlap;
			
			A2=object2.x+overlap;
			B2=object2.x+object2.image.width-overlap;
			C2=object2.y+overlap;
			D2=object2.y+object2.image.height-overlap;
			//假如他们在x-轴重叠
			if(A1>A2&&A1<B2||B1>A2&&B1<B2){
				if(C1>C2&&C1<D1||D1>C2&&D1<D2){
					return true;
				}
			}
			return false;
		}
		function HasAnimalHitMushroom(){
				//假如碰撞
			if(CheckIntersect(animal, mushroom, 5))
			{
				//假如碰撞的位置属于蘑菇的左下位置
				if((animal.x + animal.image.width/2) < (mushroom.x + mushroom.image.width*0.25))
				{
					horizontalSpeed = -speed;//反弹
				}
				//假如碰撞的位置属于蘑菇的左上位置
				else if((animal.x + animal.image.width/2) < (mushroom.x + mushroom.image.width*0.5))
				{
					//反弹速度减半
					horizontalSpeed = -speed/2;
				}
				//假如碰撞的位置属于蘑菇的右上位置
				else if((animal.x + animal.image.width/2) < (mushroom.x + mushroom.image.width*0.75))
				{
					horizontalSpeed = speed/2;
				}
				else
				{
					horizontalSpeed = speed;
				}
				verticalSpeed = -speed;//改变垂直速度。也即动物向上移动
		 
			}

		}

		$(window).ready(function(){
			AddEventHandlers();
			loadImages();
			ctx=document.getElementById("canvas").getContext('2d');;
			screenWidth=parseInt($("#canvas").attr("width"));
			screenHeight = parseInt($("#canvas").attr("height"));
			mushroom.image = mushroomImg;
			mushroom.x = parseInt(screenWidth/2);// 蘑菇X坐标  
            mushroom.y = screenHeight - 40;//蘑菇Y坐标    
            animal.x = parseInt(screenWidth/2);// 蘑菇X坐标  
            animal.y = screenHeight - 40;//蘑菇Y坐标    
            setInterval(gameLoop, 10);
		});
	</script> 
	</head>
	<body>
		<div id="container" style="border:1px solid; cursor:none; width:480px; height:320px;">
			<canvas id="canvas" width="480" height="320" >
			</canvas>
	    </div>
	</body>
</html>

 

GoogleWave完全手册学习小结(一)

中文版
下载见附件

第二章:开始使用 Wave


剖析一个 wave



 
在 Wave 搜索框(在搜索面板的顶部)输入 with:public
查询,然后回车,你可以看到所有在服务器
公开
的 wave,你可以随意加入 。


 
这个搜索结果可能非常庞大,并且实时更新 。当然你还可以在 with:public 后面添加你想搜索的关键字,比如”with:public 大雪
“。

新消息提醒和Wave收件箱


在你的收件箱,如果有更新的wave,它们的标题和时间戳
会以粗体
显示。同时,更新的次数也会用数字 显示
未读的blip 用绿色数字 表示
。当你打开那条wave,你能通过blip 左边的绿色竖条
来辨别哪些是未读和更新
过的。点击一条未读的blip 并标记为已读,绿条就会消褪,同时收件箱或搜索面板里的未读计数也会更新。

 

更新一条wave 的三种方式


  • 在 blip 下直接回复

 

  • 在某条 blip 里内嵌回复

 

  • 编辑现存 blip 的内容

 

还有就是,任何时候你都可以知道有多少人编辑过一条 blip
,只要看每条 blip 上端有多少个头像和用户名
就行了。





最适合使用Wave 的浏览器


 

Wave 使用了一些近来才开发的网络标准(比如 HTML5
)来实现种种魔幻般的功能。意味着 Wave
虽然提供了用户所期望的丰富的 Web 应用体验,但同时也意味着你需要一个支持 HTML5 的浏览器
来使用
Wave。兼容 Wave 的浏览器包括:

  • Google Chrome
  • Firefox 3.5+
  • Safari 4
  • 大小: 72.6 KB
  • 大小: 116.7 KB
  • 大小: 106.7 KB
  • 大小: 28.4 KB
  • 大小: 25.8 KB
  • 大小: 33.9 KB

Senchatouch环境搭建

最近一个和一个朋友聊到Sencha Touch。做出来的App都很漂亮也很美观。涉及到的技术主要是HTML5。让我觉得比较新颖的是它不需要使用某种编程语言来开发。事实上使用Sencha Touch开发出来的App并不是一个本地应用。而是在与网络上的文件进行交互。而交互的体验会给人一种在使用本地App的感觉。使用Sencha Touch开发有两个前提条件:

  • 本机装有一个web server,Sencha Touch推荐的是XAMPP,因为它的安装和设置都比较简单。没有人会想花很多时间在这个服务器的配置上。
  • 使用Chrome或者Safari浏览器。这是官方推荐的浏览器,理由是它们比较时髦。更具体的理由的它们支持Webkit。

100个超炫的HTML5示例(三)

jquery博客继续折腾shopex纠结了,老是出现无法安装,即使导入本地的数据库,也是没有,居然最后还是乱码,已经安装了zend optimizer,不懂咋整,还是那样。最后还是果断切换至ecshop.

今天依然给分享一些牛掰的HTML5网站吧,不得不惊叹老外吃牛肉长大的,思想就是丰富。

11,Google Gravity

12,Biolab Disaster

13,Blob

14,Entanglement

15,Chain Reaction

转自 jquery http://www.jqueryba.com/613.html

加入中国HTML5研究小组

受邀加入了中国 HTML5 研究小组,比较意外。

一直以来很关注 Web 标准进程,随着 HTML5 的逐渐推广,应用逐渐接纳,这一标准得到普及。

其实,Web 上的 RIA 我只认为 DHTML(HTML,CSS,JavaScript)靠谱,Flex(Flash)纵有一些便捷沙箱,但终究还是不跨平台。

试问,从编程语言发展至今,有哪个语音能像 DHTML 这样跨平台运行,Java?(您是不知道什么是悲剧 :-)。

虽然 HTML5 的普及还待时日,但 Web 客户端开发人员应该读一下 HTML5 规范,服务器端开发人员也至少应该读一下 WebSocket

虽然得到所有浏览器厂商(包括移动)支持还需要一些时日….

但是 HTML5 是不可撼动的,因为这是作为 Web 应用开发人员的我们可以接触到的唯一的开放标准。

本文是使用 B3log Solo简约设计の艺术 进行同步发布的