HTML5游戏开发(一)

HTML5游戏开发(一)

一、Canvas元素

  HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。
画布是一个矩形区域,您可以控制其每一像素。
canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

1、一个简单的示例

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>H5Canvas</title>
        <style>
            body{
                background:#4F4B43;
            }
            #canvas{
                margin: 10px;
                padding: 10px;
                background: #82A36F;
                /*thin定义细的边框 inset将外部阴影 (outset) 改为内部阴影*/
                border: thin inset #EDE176;
            }
        </style>
    </head>
    <body>
        <canvas id='canvas' width="600" height="300"></canvas>
        <script type="text/javascript" src="js/canvas.js" ></script>
    </body>
</html>
    //获取Canvas对象
    var canvas=document.querySelector("#canvas");
    context=canvas.getContext('2d');
    context.font='38pt Arial';
    //填充色
    context.fillStyle='#EDE176';
    //设置字符轮廓线颜色
    context.strokeStyle='#C2A84A';
    //字符填充,并使文字内容居中
    context.fillText("一个Canvas示例", canvas.width/2 - 200,
                                     canvas.height/2 + 15);
    //字符轮廓                                 
    context.strokeText("一个Canvas示例", canvas.width/2 - 200,
                                       canvas.height/2 + 15 );

查看效果:
iamge

注意:
在设置canvas的宽度与高度时,不能使用px后缀。
默认的canvas元素大小是300x500个屏幕像素。
如果是通过CSS来设定canvas元素的大小,那么只会改变元素本身的大小,而不会影响到绘图表面。当canvas元素的大小不符合其绘图表面的大小时,浏览器就会对绘衅表面进行缩放,使其符合元素的大小。
尽量使用属性来设置元素大小,而不使用CSS。

二、时钟绘制

(一)绘制外圆

//定义多个变量
var canvas=document.querySelector("#canvas"),
context=canvas.getContext('2d'),
FONT_HEIGHT = 15,   //字体高度
MARGIN = 35,        //外边距
RADIUS = canvas.width/2 - MARGIN;       //半径

//绘制圆形
function drawCircle() {
   context.beginPath();
   //路径颜色
   context.strokeStyle="#A66085";
   //参数分别为:x,y 圆的中心坐标 半径 起始角 结束角 逆时还是顺时true为逆时
   context.arc(canvas.width/2, canvas.height/2,
               RADIUS, 0, Math.PI*2, true);
   context.stroke();
}

function drawClock() {
    //清除画布
   context.clearRect(0,0,canvas.width,canvas.height);
    //绘制外圆
   drawCircle();
}
//函数调用
drawClock();

(二)绘制钟表时间数字

var NUMERAL_SPACING = -10,       //数字与圆之间的间隔
HAND_RADIUS = RADIUS + NUMERAL_SPACING; //数字半径
//绘制时间数据
function drawNumerals() {
    //定义12个小时的数组
   var numerals = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ],
       angle = 0,
       numeralWidth = 0;
    //通过循环进行绘制
   numerals.forEach(function(numeral) {
      //角度
      angle = Math.PI/6 * (numeral-3);
      numeralWidth = context.measureText(numeral).width;
      //填充文字,参数 文本,坐标x,y
      context.fillText(numeral, 
         canvas.width/2  + Math.cos(angle)*(HAND_RADIUS) - numeralWidth/2,
         canvas.height/2 + Math.sin(angle)*(HAND_RADIUS) + FONT_HEIGHT/3);
   });
}

function drawClock() {
    //清除画布
   context.clearRect(0,0,canvas.width,canvas.height);
    //绘制外圆
   drawCircle();
   //绘制时间
   drawNumerals() ;
}
//函数调用
drawClock();

(三)绘制中心点

//绘制中心点
function drawCenter() {
   context.beginPath();
   //填充颜色
   context.fillStyle="#585E6B";
   //绘制位置:参数:坐标x,y 半径,起始角,结束角,方向
   context.arc(canvas.width/2, canvas.height/2, 5, 0, Math.PI*2, true);
   //填充
   context.fill();
}

function drawClock() {
    //清除画布
   context.clearRect(0,0,canvas.width,canvas.height);
    //绘制外圆
   drawCircle();
   //绘制时间
   drawNumerals() ;
   //绘制中心点
   drawCenter()
}
//函数调用
drawClock();

(三)绘制时分秒针

//时针长短差
var   HAND_TRUNCATION = canvas.width/25,
      //分针短差
      MIN_HAND_TRUNCATION = canvas.width/20,
      //时针长度差
      HOUR_HAND_TRUNCATION = canvas.width/10;

/**
 *  绘制时分秒针通用函数
 * @param {Object} loc
 * @param {Object} isHour 是否是小时
 */
function drawHand(loc, isType) {
    //计算角度
   var angle = (Math.PI*2) * (loc/60) - Math.PI/2;
    //console.log(isType)
    //计算半径
    if(isType=='hour'){
         handRadius =RADIUS - HAND_TRUNCATION-HOUR_HAND_TRUNCATION;
    }else if(isType=='min'){
        handRadius =RADIUS - HAND_TRUNCATION-HOUR_HAND_TRUNCATION-MIN_HAND_TRUNCATION;
    }else if(isType=='sec'){
        handRadius=RADIUS - HAND_TRUNCATION;
    }
    //起始点为中心点
   context.moveTo(canvas.width/2, canvas.height/2);
   //结束点,通过向量计算
   context.lineTo(canvas.width/2  + Math.cos(angle)*handRadius, 
                  canvas.height/2 + Math.sin(angle)*handRadius);              
   context.stroke();
}
//绘制时分秒
function drawHands() {
   //获取当前小时数
   var date = new Date,
       hour = date.getHours();
   //进行12时计算    
   hour = hour > 12 ? hour - 12 : hour;
   //绘制时针
   drawHand(hour*5 + (date.getMinutes()/60)*5, 'hour');
   //绘制分针
   drawHand(date.getMinutes(), 'min');
   //绘制秒针
   drawHand(date.getSeconds(), 'sec');
}

function drawClock() {
    //清除画布
   context.clearRect(0,0,canvas.width,canvas.height);
    //绘制外圆
   drawCircle();
   //绘制时间
   drawNumerals() ;
   //绘制中心点
   drawCenter();
   //绘制时分秒针
   drawHands();
}
drawClock();

(四)动态显示

//每秒调用一次
setInterval(drawClock,1000);

显示结果:
image

二、事件处理

HTML5应用程序是以事件来驱动的。可以在HTML元素上注册事件监听器,并编写用一应这些事件的实现代码。
分别有:鼠标事件、键盘事件、触摸事件

(一)鼠标事件

将鼠标坐标转换为Canvas坐标
浏览器通过事件对象传递给监听器的鼠标坐标,是窗口坐标,而不是相对于canvas自身的坐标。
大部分情况下,开发者需要知道的是发生鼠标事件的点相对于canvas的位置,而不是整个窗口中的位置,所以必须进行坐标转换。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>H5Canvas</title>
        <style>
            body{
                background:#4F4B43;
            }
            #canvas{
                margin: 10px;
                padding: 10px;
                background: #82A36F;
                /*thin定义细的边框 inset将外部阴影 (outset) 改为内部阴影*/
                border: thin inset #EDE176;
            }
        </style>
    </head>
    <body>
         <div id='readout'></div>
        <canvas id='canvas' width="500" height="250"></canvas>
        <script type="text/javascript" src="js/canvasmouse.js" ></script>
    </body>
</html>
1、绘制背景
var canvas = document.querySelector('#canvas'),
    //用于读取转换后的坐标值
    readout = document.querySelector('#readout'),
    context = canvas.getContext('2d'),
    //创建一个精灵对象
    spritesheet = new Image();

//绘制带行分隔线的背景
function drawBackground() {
  //定义12个像素的间隔
   var VERTICAL_LINE_SPACING = 12,
   //获取画布的高度
   i = context.canvas.height;
   //清空画布
   context.clearRect(0,0,canvas.width,canvas.height);
   //设定路径颜色
   context.strokeStyle = '#61665C';
   //线的粗细为0.5
   context.lineWidth = 0.5;
   //绘制水平分隔线 间隔为12 ,第一行为VERTICAL_LINE_SPACING*4
   while(i > VERTICAL_LINE_SPACING*4) {
      context.beginPath();
      context.moveTo(0, i);
      //到画布的宽度
      context.lineTo(context.canvas.width, i);
      context.stroke();
      //一次减去12
      i -= VERTICAL_LINE_SPACING;
   }
}
drawBackground();
2、绘制精灵
//绘制精灵
function drawSpritesheet() {
   context.drawImage(spritesheet, 0, 0);
}
spritesheet.src = 'img/running-sprite-sheet.png';
//通过图像加载事件进行绘制
spritesheet.onload = function(e) {
   drawSpritesheet();
};
3、绘制参考线,并读取画布坐标值
//绘制水平线
function drawHorizontalLine (y) {
   context.beginPath();
   context.moveTo(0,y + 0.5);
   context.lineTo(context.canvas.width, y + 0.5);
   context.stroke();
}
//绘制垂直线
function drawVerticalLine (x) {
   context.beginPath();
   context.moveTo(x + 0.5, 0);
   context.lineTo(x + 0.5, context.canvas.height);
   context.stroke();
}
//绘制引导线
function drawGuidelines(x, y) {
   //设置线的颜色
   context.strokeStyle = 'rgba(0,0,230,0.8)';
   context.lineWidth = 0.5;
   //绘制水平线
   drawVerticalLine(x);
   //绘制垂直线
   drawHorizontalLine(y);
}
//更新读取的值
function updateReadout(x, y) {
   readout.innerHTML = '(' + x.toFixed(0) + ', ' + y.toFixed(0) + ')';
}

 //坐标转换 将window的坐标转换为Canvas的坐标
function windowToCanvas(canvas, x, y) {
    //返回canvas的大小与位置
   var bbox = canvas.getBoundingClientRect();
   //返回x,y值
   return { x: x - bbox.left * (canvas.width  / bbox.width),
            y: y - bbox.top  * (canvas.height / bbox.height)
          };
}
/**
 * 添加鼠标移动事件
 * @param {Object} e
 */
canvas.onmousemove = function (e) {
    //将window坐标转换为画布坐标
   var loc = windowToCanvas(canvas, e.clientX, e.clientY);
   //当鼠标移动时,重绘精灵与背景 
   drawBackground();
   drawSpritesheet();
   //绘制参考线
   drawGuidelines(loc.x, loc.y);
   //读取坐标值
   updateReadout(loc.x, loc.y);
};

显示效果:
image

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值