本节教程通过一个简单的游戏小例子,讲解Canvas的基础知识。

最终效果:

点击移动的方块,方块上的分数会增加,方块的行进方向会改变,并且方块的速度会增加。

在线演示

源码

HTML5引入了canvas元素。canvas元素为我们提供了一块空白画布。我们可以使用此画布来绘制和绘制我们想要的任何东西。JavaScript为我们提供了动态制作动画并绘制到画布上所需的工具。它不仅提供绘图和动画系统,还可以处理用户交互。在本教程中,我们将使用纯JavaScript制作基本的HTML5 Canvas框架,该框架可用于制作真实的游戏。在本教程的结尾创建了一个非常简单的游戏,以演示HTML5 Canvas与JavaScript结合的优势。

HTML5 Canvas基本游戏框架

让我们围绕canvas元素创建一个基本的游戏框架。我们需要一个HTML5文件和一个JavaScript文件。HTML5文件应包含canvas元素和对JavaScript文件的引用。JavaScript文件包含将代码绘制到canvas元素的代码。

这是HTML5文件index.html:

<head>
<meta charset="UTF-8">
<title>Canvas Example</title>
<script type="text/javascript" src="framework.js"></script>
</head>
<body>
<canvas id="viewport" width="640" height="480"></canvas>
</body>
</html>

如您所见,JavaScript文件game.js包含在html文件的头部。画布元素以名称“ viewport”定义,其宽度为640像素,高度为480像素。在我们的framework.js中,我们需要使用其名称查找canvas元素,以便可以在其上进行绘制。我们正在创建的框架应支持渲染循环以及玩家与鼠标的交互。对于渲染循环,我们将使用Window.requestAnimationFrame()。通过添加鼠标事件侦听器来启用鼠标交互。

这是JavaScript文件framework.js:

// The function gets called when the window is fully loaded
window.onload = function() {
// Get the canvas and context
var canvas = document.getElementById("viewport");
var context = canvas.getContext("2d"); // Timing and frames per second
var lastframe = 0;
var fpstime = 0;
var framecount = 0;
var fps = 0; // Initialize the game
function init() {
// Add mouse events
canvas.addEventListener("mousemove", onMouseMove);
canvas.addEventListener("mousedown", onMouseDown);
canvas.addEventListener("mouseup", onMouseUp);
canvas.addEventListener("mouseout", onMouseOut); // Enter main loop
main(0);
} // Main loop
function main(tframe) {
// Request animation frames
window.requestAnimationFrame(main); // Update and render the game
update(tframe);
render();
} // Update the game state
function update(tframe) {
var dt = (tframe - lastframe) / 1000;
lastframe = tframe; // Update the fps counter
updateFps(dt);
} function updateFps(dt) {
if (fpstime > 0.25) {
// Calculate fps
fps = Math.round(framecount / fpstime); // Reset time and framecount
fpstime = 0;
framecount = 0;
} // Increase time and framecount
fpstime += dt;
framecount++;
} // Render the game
function render() {
// Draw the frame
drawFrame();
} // Draw a frame with a border
function drawFrame() {
// Draw background and a border
context.fillStyle = "#d0d0d0";
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#e8eaec";
context.fillRect(1, 1, canvas.width-2, canvas.height-2); // Draw header
context.fillStyle = "#303030";
context.fillRect(0, 0, canvas.width, 65); // Draw title
context.fillStyle = "#ffffff";
context.font = "24px Verdana";
context.fillText("HTML5 Canvas Basic Framework ", 10, 30); // Display fps
context.fillStyle = "#ffffff";
context.font = "12px Verdana";
context.fillText("Fps: " + fps, 13, 50);
} // Mouse event handlers
function onMouseMove(e) {}
function onMouseDown(e) {}
function onMouseUp(e) {}
function onMouseOut(e) {} // Get the mouse position
function getMousePos(canvas, e) {
var rect = canvas.getBoundingClientRect(); return {
x: Math.round((e.clientX - rect.left)/(rect.right - rect.left)*canvas.width),
y: Math.round((e.clientY - rect.top)/(rect.bottom - rect.top)*canvas.height)
};
} // Call init to start the game
init();
};

上面的代码绘制了一个带有边框,标题和每秒帧数的简单框架。这是代码生成的内容

带有弹跳方块的游戏

现在我们有了一个框架,让我们用它创建一个简单的游戏。我们将创建一个在屏幕上具有反弹方块的游戏。当玩家单击它时,方块上的分数会增加,方块的行进方向会改变,并且方块的速度会增加。

首先,我们定义一些对象和属性。该级别定义了方块可以反弹的区域。方块本身具有位置,尺寸和运动属性。最后,有一个分数。

    // Level properties
var level = {
x: 1,
y: 65,
width: canvas.width - 2,
height: canvas.height - 66
}; // Square
var square = {
x: 0,
y: 0,
width: 0,
height: 0,
xdir: 0,
ydir: 0,
speed: 0
} // Score
var score = 0;

我们需要在init()函数中初始化对象和属性。

    // Initialize the game
function init() {
// Add mouse events
canvas.addEventListener("mousemove", onMouseMove);
canvas.addEventListener("mousedown", onMouseDown);
canvas.addEventListener("mouseup", onMouseUp);
canvas.addEventListener("mouseout", onMouseOut); // Initialize the square
square.width = 100;
square.height = 100;
square.x = level.x + (level.width - square.width) / 2;
square.y = level.y + (level.height - square.height) / 2;
square.xdir = 1;
square.ydir = 1;
square.speed = 200; // Initialize the score
score = 0; // Enter main loop
main(0);
}

这些对象需要更新,因此让我们修改update()函数。方块需要移动,并且应该检测并解决与标高边缘的碰撞。

    // Update the game state
function update(tframe) {
var dt = (tframe - lastframe) / 1000;
lastframe = tframe; // Update the fps counter
updateFps(dt); // Move the square, time-based
square.x += dt * square.speed * square.xdir;
square.y += dt * square.speed * square.ydir; // Handle left and right collisions with the level
if (square.x <= level.x) {
// Left edge
square.xdir = 1;
square.x = level.x;
} else if (square.x + square.width >= level.x + level.width) {
// Right edge
square.xdir = -1;
square.x = level.x + level.width - square.width;
} // Handle top and bottom collisions with the level
if (square.y <= level.y) {
// Top edge
square.ydir = 1;
square.y = level.y;
} else if (square.y + square.height >= level.y + level.height) {
// Bottom edge
square.ydir = -1;
square.y = level.y + level.height - square.height;
}
}

我们需要绘制方块和分数。这需要在render()函数中完成。

    // Render the game
function render() {
// Draw the frame
drawFrame(); // Draw the square
context.fillStyle = "#ff8080";
context.fillRect(square.x, square.y, square.width, square.height); // Draw score inside the square
context.fillStyle = "#ffffff";
context.font = "38px Verdana";
var textdim = context.measureText(score);
context.fillText(score, square.x+(square.width-textdim.width)/2, square.y+65);
}

最后一步是添加鼠标交互。让我们将代码添加到onMouseDown()函数中。

   function onMouseDown(e) {
// Get the mouse position
var pos = getMousePos(canvas, e); // Check if we clicked the square
if (pos.x >= square.x && pos.x < square.x + square.width &&
pos.y >= square.y && pos.y < square.y + square.height) { // Increase the score
score += 1; // Increase the speed of the square by 10 percent
square.speed *= 1.1; // Give the square a random position
square.x = Math.floor(Math.random()*(level.x+level.width-square.width));
square.y = Math.floor(Math.random()*(level.y+level.height-square.height)); // Give the square a random direction
square.xdir = Math.floor(Math.random() * 2) * 2 - 1;
square.ydir = Math.floor(Math.random() * 2) * 2 - 1;
}
}

这是通过基本框架和一些修改而成的最终游戏。单击方块以增加您的分数并前进到下一个方块。

通过游戏学javascript系列第一节Canvas游戏开发基础的更多相关文章

  1. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第一节:3D时代来临!

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第一节:3D时代来临.Cocos2d-x程序猿的机遇和挑战! 视频地址:http://edu.csdn.net/course/deta ...

  2. django系列--第一节

    学习前准备 安装必须的学习环境环境(学习前提:python2.7) pip install django==1.8 pip install mysqldb(后面会用) pip install Pill ...

  3. [Spring Batch 系列] 第一节 初识 Spring Batch

    距离开始使用 Spring Batch 有一段时间了,一直没有时间整理,现在项目即将完结,整理下这段时间学习和使用经历. 官网地址:http://projects.spring.io/spring-b ...

  4. 第一节:Java 语言基础

    5分30开始 18分正式开始议题 23分01开始创建项目: 讲个面向过程,函数式的方式 byte(8) char(16) short(16) int(32) long(64) long类型或者doub ...

  5. 前端基础入门第一阶段-Web前端开发基础环境配置

    Web前端和全栈的定义: A.什么是传统传统web前端:需要把设计师的设计稿,切完图,写标签和样式,实现JS的效果,简而言之即只需要掌握HTML的页面结构,CSS的页面样式,javaScript页面的 ...

  6. 【实习第一天】odoo开发基础(一)

    管理权限 在项目中,有个security文件夹,其中的ir.model.access文件后面带4个参数.分别代表着读,写,创建,删除的操作 想要开启权限需要将其参数调成为1,反之为0.倘若不调整参数, ...

  7. 第一章使用JSP/Server技术开发新闻发布系统第一章动态网页开发基础

      一:为什么需要动态网页    由于静态网页的内容是固定的,不能提供个性化和定制化得服务,使用动态网页可真正地与用户实现互动. 二:什么是动态网页  ①:动态网页是指在服务器端运行的,使用程序语言设 ...

  8. SAP-ABAP系列 第二篇SAP ABAP开发基础

    第二章SAP ABAP开发基础 1.ABAP数据类型及定义 ABAP程序中共包含8种基本数据类型定义, 类型名称 描述 属性 C Character Text (字符类型) 默认长度=1,默认值 = ...

  9. jsp第一章 动态网页开发基础

    动态网站可以实现交互功能,如用户注册.信息发布.产品展示.订单管理等等: 动态网页并不是独立存在于服务器的网页文件,而是浏览器发出请求时才反馈网页: 动态网页中包含有服务器端脚本,所以页面文件名常以a ...

随机推荐

  1. Git-stash(暂存)

    修改某文件后,不想commit,使用stash保存在本地的某分支内 # 暂存 git stash ## 可暂存新增文件 git stash -u ## 为此次暂存添加标识 git stash save ...

  2. 控制算法PID-理解分析1

    以下内容是来自网络上的,本人觉得有道理,拷贝下来,由于没有找到最源头的出处,没有注明来自何方. 转载,下面说法应该更通俗易懂一家庭,每次需要开支的时候丈夫P都要拿卡去取钱.需要多少取多少,因为银行最低 ...

  3. C语言设计模式(应用)

    #ifndef QUEUE_H #define QUEUE_H #define QUEUE_SIZE 10 typedef struct queue { int buffer[QUEUE_SIZE]; ...

  4. 各种有趣vbs,bat脚本

    短信轰炸.vbs Dim btn,ie Set ie = WScript.CreateObject("InternetExplorer.Application") ie.Visib ...

  5. get_object_vars

    get_object_vars()

  6. OAuth 2.0授权框架详解

    目录 简介 OAuth的构成 refresh Token Authorization Code模式 隐式授权 Resource Owner 授权密码认证 Client 认证授权 github的OAut ...

  7. FL Studio中的音频剪辑功能讲解

    音频剪辑,是FL Studio中的一个特色功能,音频剪辑的目的是保持在播放列表中显示和触发的音频,可以根据需要对它们进行切片和排列.但需要注意的是音频剪辑这个功能在FL Studio的基础版(果味版) ...

  8. guitar pro系列教程(五):Guitar Pro音轨属性之小节的功能

    又到了guitar pro系列教程新的一章,本章节小编将采用图文相结合的方式与大家一起来讨论下关于Guitar Pro小节的功能,感兴趣的小伙伴都可以进来看看哦,如下图所示: 我们看到小节这选项栏中分 ...

  9. Boom 3D带你聆听《我们的乐队》音乐盛宴

    说到前段时间大热的音乐类综艺节目,<我们的乐队>肯定值得一提.<我们的乐队>是由谢霆锋.萧敬腾.王俊凯担任导师,以团队的形式组成各种风格的乐队,并通过同场比拼,最终选出获胜的乐 ...

  10. 聊聊 ClassLoader 是如何查找资源的

    ClassLoader作用 classloader这个写业务代码的童鞋们,应该很少用到,但是写框架的应该很熟悉.这个类负责Java底层的类的加载和查找,简单滴说Java 的所有类都是由它负责将clas ...