通过《HTML5游戏开发》摘抄了一个小迷宫游戏,感觉还不错,可以画画,写字,把摘抄的代码放上来分享下,喜欢的同学可以拿来玩玩!
<html>
<head>
<title>创建运行迷宫</title>
<script type="text/javascript">
//用于清除画布
var cwidth = 900;
var cheight = 350;
var ctx;//画布上下文
var everything = [];//用于保存所有的对象
var curwall;//对应当前墙
var wallwidth = 5;//固定墙宽
var wallstyle = "rgb(200,0,200)";
var walls = [];//保存所有墙
var inmotion = false;//指标,指示正在通过拖动鼠标构建墙
var unit = 10;//token移动的单位
function Token(sx,sy,rad,stylestring,n){
this.sx = sx;
this.sy = sy;
this.rad = rad;
this.draw = drawtoken;
this.n = n;
this.angle = (2*Math.PI)/n;
this.moveit = movetoken;
this.fillstyle = stylestring;
}
function drawtoken(){
ctx.fillstyle = this.fillstyle;
var i;
var rad = this.rad;
ctx.beginPath();
ctx.moveTo(this.sx+rad*Math.cos((i-.5)*this.angle),this.sy+rad*Math.sin((i-.5)*this.angle));//移动到多边形的第一个顶点
for(i = 1;i < this.n;i++){
ctx.lineTo(this.sx+rad*Math.cos((i-.5)*this.angle),this.sy+rad*Math.sin((i-.5)*this.angle));//指定连线到下一个点,用于绘制一条边
}
ctx.fill();//绘制token
}
function movetoken(dx,dy){
this.sx += dx;
this.sy += dy;
var i;
var wall;
for(i = 0;i < walls.length;i++){
wall = walls[i];
//检查是否相交,如果这个token新位置与特定的墙相交
if(intersect(wall.sx,wall.sy,wall.fx,wall.fy,this.sx,this.sy,this.rad)){
this.sx -= dx;//不做移动
this.sy -= dy;
break;
}
}
}
function Wall(sx,sy,fx,fy,width,stylestring){
this.sx = sx;
this.sy = sy;
this.fx = fx;
this.fy = fy;
this.width = width;
this.draw = drawAline;
this.strokestyle = stylestring;
}
function drawAline(){
ctx.lineWidth = this.width;//设置线宽
ctx.strokeStyle = this.strokestyle;
ctx.beginPath();
ctx.moveTo(this.sx,this.sy);//设置起始点
ctx.lineTo(this.fx,this.fy);//设置终点
ctx.stroke();
}
var mypent = new Token(100,100,20,"rgb(0,0,250)",5);
everything.push(mypent);
function init(){
ctx = document.getElementById("canvas").getContext("2d");
var canvas1 = document.getElementById("canvas");
canvas1.addEventListener("mousedown",startwall,false);
canvas1.addEventListener("mousemove",strecthwall,false);
canvas1.addEventListener("mouseup",finish,false);
window.addEventListener("keydown",getkeyAndMove,false);
drawall();
}
function startwall(ev){
var mx;
var my;
//获取鼠标位置
if(ev.layerX || ev.layerX == 0){
mx = ev.layerX;
my = ev.layerY;
}else if(ev.offsetX || ev.offsetX == 0){
mx = ev.offsetX;
my = ev.offsexY;
}
curwall = new Wall(mx,my,mx+1,my+1,wallwidth,wallstyle);//创建新墙
inmotion = true;
everything.push(curwall);
drawall();
}
function strecthwall(ev){
if(inmotion){
var mx;
var my;
if(ev.layerX || ev.layerX == 0){
mx = ev.layerX;
my = ev.layerY;
}else if(ev.offsetX || ev.offsetX == 0){
mx = ev.offsetX;
my = ev.offsetY;
}
curwall.fx = mx;
curwall.fy = my;
drawall();
}
}
function finish(ev){
inmotion = false;
walls.push(curwall);
}
function drawall(){
ctx.clearRect(0,0,cwidth,cheight);//擦除画布
var i ;
for(i = 0;i < everything.length;i++){
everything[i].draw();//绘制所以对象
}
}
function getkeyAndMove(event){
var keyCode;
if(event == null){
keyCode = window.event.keyCode;
window.event.preventDefault;//停止默认动作
}else{
keyCode = event.keyCode;
event.preventDefault;//停止默认动作
}
switch(keyCode){
case 37: //左箭头
mypent.moveit(-unit,0); //水平左移
break;
case 38: //上箭头
mypent.moveit(0,-unit); //向上移动
break;
case 39: //右箭头
mypent.moveit(unit,0); //水平右移
break;
case 40: //下箭头
mypent.moveit(0,unit); //向下移动
break;
Default:
window.removeEventListener("keydown",getkeyAndMove,false);//停止监听按键
}
drawall();
}
function intersect(sx,sy,fx,fy,cx,cy,rad){
var dx;
var dy;
var t;
var rt;
dx = fx - sx;
dy = fy - sy;
//取从各点到(cx,cy)距离的平方公式,取导数,解为0
t = 0.0 - ((sx - cx)*dx+(sy-cy)*dy)/((dx * dx)+(dy * dy));
if(t < 0.0){
t = 0.0;
}else if(t > 1.0){
t = 1.0;
}
dx = (sx+t*(fx-sx))-cx;//计算此t值时的差
dy = (sy+t*(fy-sy))-cy;
rt = (dx*dx)+(dy*dy);//计算距离
if(rt < (rad*rad)){
return true;
}else{
return false;
}
}
function savewalls(){
var w = [];
var allw = [];
var sw ;//保存最终的字符串
var onewall ;//保存中间字符串
var i ;
var lsname = document.sf.slname.value;//取玩家指定的名称,用于本地保存
for(i = 0;i <walls.length;i++){
w.push(walls[i].sx);
w.push(walls[i].sy);
w.push(walls[i].fx);
w.push(walls[i].fy);
onewall = w.join("+");
allw.push(onewall);
w = [];
}
sw = allw.join(";");
try{
localStorage.setItem(lsname,sw);
}catch(e){
alter("data not saved,error given "+e);
}
return false;//返回false避免刷新
}
function getwalls(){
var swalls;
var sw;
var i;
var sx;
var sy;
var fx;
var fy;
var curwall;
var lsname = document.gf.glname.value;//抽取玩家指定存储的名字,以备获取
swalls = localStorage.getItem(lsname);
if(swalls != null){
wallstgs = swalls.split(";");
for(i = 0;i < wallstgs.length;i++){
sw = wallstgs[i].split("+");
sx = Number(sw[0]);
sy = Number(sw[1]);
fx = Number(sw[2]);
fy = Number(sw[3]);
curwall = new Wall(sx,sy,fx,fy,wallwidth,wallstyle);//使用提取值创建新墙
walls.push(curwall);
everything.push(curwall);
}
drawall();
}else{
alert("no data retrieved");
}
window.addEventListener("keydown",getkeyAndMove,false);
return false;
}
</script>
</head>
<body onLoad="init();">
<canvas id="canvas" width="900" height="400">
你的浏览器版本不支持html5的canvas标签,请升级到最新版本或者使用支持html5的浏览器
</canvas>
<br />
按下鼠标按钮,拖动和释放来绘制墙,用方向键来进行换行操作<br />
按其他键来保存迷宫<br />
<form name="sf" onSubmit="return savewalls()">
输入名字后,在保存迷宫按钮上点击保存迷宫<br />
名字:<input name="slname" value="maze_name" type="text" />
<input type="submit" value="保存迷宫" />
</form>
<form name="gf" onSubmit="return getwalls()">
通过获取迷宫按钮上获取以前保存的迷宫<br />
名字:<input name="glname" value="maze_name" type="text" />
<input type="submit" value="获取迷宫" />
</form>
</body>
</html>