通过游戏学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 ...
随机推荐
- Git-stash(暂存)
修改某文件后,不想commit,使用stash保存在本地的某分支内 # 暂存 git stash ## 可暂存新增文件 git stash -u ## 为此次暂存添加标识 git stash save ...
- 控制算法PID-理解分析1
以下内容是来自网络上的,本人觉得有道理,拷贝下来,由于没有找到最源头的出处,没有注明来自何方. 转载,下面说法应该更通俗易懂一家庭,每次需要开支的时候丈夫P都要拿卡去取钱.需要多少取多少,因为银行最低 ...
- C语言设计模式(应用)
#ifndef QUEUE_H #define QUEUE_H #define QUEUE_SIZE 10 typedef struct queue { int buffer[QUEUE_SIZE]; ...
- 各种有趣vbs,bat脚本
短信轰炸.vbs Dim btn,ie Set ie = WScript.CreateObject("InternetExplorer.Application") ie.Visib ...
- get_object_vars
get_object_vars()
- OAuth 2.0授权框架详解
目录 简介 OAuth的构成 refresh Token Authorization Code模式 隐式授权 Resource Owner 授权密码认证 Client 认证授权 github的OAut ...
- FL Studio中的音频剪辑功能讲解
音频剪辑,是FL Studio中的一个特色功能,音频剪辑的目的是保持在播放列表中显示和触发的音频,可以根据需要对它们进行切片和排列.但需要注意的是音频剪辑这个功能在FL Studio的基础版(果味版) ...
- guitar pro系列教程(五):Guitar Pro音轨属性之小节的功能
又到了guitar pro系列教程新的一章,本章节小编将采用图文相结合的方式与大家一起来讨论下关于Guitar Pro小节的功能,感兴趣的小伙伴都可以进来看看哦,如下图所示: 我们看到小节这选项栏中分 ...
- Boom 3D带你聆听《我们的乐队》音乐盛宴
说到前段时间大热的音乐类综艺节目,<我们的乐队>肯定值得一提.<我们的乐队>是由谢霆锋.萧敬腾.王俊凯担任导师,以团队的形式组成各种风格的乐队,并通过同场比拼,最终选出获胜的乐 ...
- 聊聊 ClassLoader 是如何查找资源的
ClassLoader作用 classloader这个写业务代码的童鞋们,应该很少用到,但是写框架的应该很熟悉.这个类负责Java底层的类的加载和查找,简单滴说Java 的所有类都是由它负责将clas ...