通过游戏学javascript系列第一节Canvas游戏开发基础
本节教程通过一个简单的游戏小例子,讲解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游戏开发基础的更多相关文章
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第一节:3D时代来临!
<使用Cocos2d-x 开发3D游戏>系列在线课程 第一节:3D时代来临.Cocos2d-x程序猿的机遇和挑战! 视频地址:http://edu.csdn.net/course/deta ...
- django系列--第一节
学习前准备 安装必须的学习环境环境(学习前提:python2.7) pip install django==1.8 pip install mysqldb(后面会用) pip install Pill ...
- [Spring Batch 系列] 第一节 初识 Spring Batch
距离开始使用 Spring Batch 有一段时间了,一直没有时间整理,现在项目即将完结,整理下这段时间学习和使用经历. 官网地址:http://projects.spring.io/spring-b ...
- 第一节:Java 语言基础
5分30开始 18分正式开始议题 23分01开始创建项目: 讲个面向过程,函数式的方式 byte(8) char(16) short(16) int(32) long(64) long类型或者doub ...
- 前端基础入门第一阶段-Web前端开发基础环境配置
Web前端和全栈的定义: A.什么是传统传统web前端:需要把设计师的设计稿,切完图,写标签和样式,实现JS的效果,简而言之即只需要掌握HTML的页面结构,CSS的页面样式,javaScript页面的 ...
- 【实习第一天】odoo开发基础(一)
管理权限 在项目中,有个security文件夹,其中的ir.model.access文件后面带4个参数.分别代表着读,写,创建,删除的操作 想要开启权限需要将其参数调成为1,反之为0.倘若不调整参数, ...
- 第一章使用JSP/Server技术开发新闻发布系统第一章动态网页开发基础
一:为什么需要动态网页 由于静态网页的内容是固定的,不能提供个性化和定制化得服务,使用动态网页可真正地与用户实现互动. 二:什么是动态网页 ①:动态网页是指在服务器端运行的,使用程序语言设 ...
- SAP-ABAP系列 第二篇SAP ABAP开发基础
第二章SAP ABAP开发基础 1.ABAP数据类型及定义 ABAP程序中共包含8种基本数据类型定义, 类型名称 描述 属性 C Character Text (字符类型) 默认长度=1,默认值 = ...
- jsp第一章 动态网页开发基础
动态网站可以实现交互功能,如用户注册.信息发布.产品展示.订单管理等等: 动态网页并不是独立存在于服务器的网页文件,而是浏览器发出请求时才反馈网页: 动态网页中包含有服务器端脚本,所以页面文件名常以a ...
随机推荐
- 贼厉害,手撸的 SpringBoot 缓存系统,性能杠杠的!
一.通用缓存接口 二.本地缓存 三.分布式缓存 四.缓存"及时"过期问题 五.二级缓存 缓存是最直接有效提升系统性能的手段之一.个人认为用好用对缓存是优秀程序员的必备基本素质. 本 ...
- mysql 5.7添加server_audit 安全审计功能
mysql 5.7添加server_audit 安全审计功能 一.根据链接下载插件 参考链接下载 http://blog.itpub.net/31441024/viewspace-2213103 l ...
- .NET 开源工作流: Slickflow流程引擎高级开发(八) -- 审批网关(ApprovalOrSplit)模式的应用
前言:业务流程流转过程中,审批类型的节点是比较常见的,在审批操作中,常见的操作就是就是主管人员对待办事项进行同意或者拒绝.所以网关处理节点,就是需要对这两种审批结果进行预备处理,审批网关是在或分支(O ...
- kali 系列学习06 - 攻击之密码破解
参考书 <kali linux渗透测试技术详解> 清华大学出版社 2015 杨波 一.medusa使用 原理:并行登陆破解 1.只输入单个命令,是查看帮助 root@kali:/tool ...
- window下开启关闭mysql服务
cmd:管理员模式 net start mysql net stop mysql
- apache-commons和guava的工具类
apache-commons工具类:https://www.iteye.com/blog/zhoualine-1770014 guava工具类:https://blog.csdn.net/Dream_ ...
- git操作之四:git branch(本地仓库)
前面,介绍了git init/add/commit/restore/reset等git命令,今天介绍下git branch,这个命令是和分支相关的.首先要理解什么是分支,简单来说在协作开发中,每个人开 ...
- php bypass disable_function 命令执行 方法汇总简述
1.使用未被禁用的其他函数 exec,shell_exec,system,popen,proc_open,passthru (python_eval?perl_system ? weevely3 wi ...
- iOS中跑马灯效果小结
时光过得好快,记忆中刚刚从春节返回没有多久,清明.五一已飞逝而过,眨眼已到盛夏季节.不过还好,济南这两年不算太热,刚开始升温几天,一场及时雨总能让温度保持适宜.为了纪念一下青春的尾巴,也为了能有个健康 ...
- 经典面试题解析:这道 C 编程面试题居然有如此多的解法!
问题描述 任意给定一个32位无符号整数n,求n的二进制表示中1的个数,比如n = 5(0101)时,返回2,n = 15(1111)时,返回4 这也是一道比较经典的题目了,相信不少人面试的时候可能遇到 ...