本系列博文翻译自以下文章

http://blog.sklambert.com/html5-canvas-game-panning-a-background/

Languages: HTML5, JavaScript

Code: https://github.com/straker/galaxian-canvas-game/tree/master/part1

1.游戏背景滚动

最终的游戏演示界面如下:

控制:移动 –  (←↑↓→)箭头
射击 – 空格

The HTML5 Page

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Space Shooter Demo</title>
  5. <style>
  6. canvas {
  7. position: absolute;
  8. top: 0px;
  9. left: 0px;
  10. background: transparent;
  11. }
  12. </style>
  13. </head>
  14. <body onload="init()">
  15. <!-- The canvas for the panning background -->
  16. <canvas id="background" width="600" height="360">
  17. Your browser does not support canvas. Please try again with a different browser.
  18. </canvas>
  19. <script src="space_shooter_part_one.js"></script>
  20. </body>
  21. </html>

以上代码创建了一个600宽,360高的画布。

基础

创建一个封装全部图像的js对象:

  1. /**
  2. * Define an object to hold all our images for the game so images
  3. * are only ever created once. This type of object is known as a
  4. * singleton.
  5. */
  6. var imageRepository = new function() {
  7. // Define images
  8. this.background = new Image();
  9. // Set images src
  10. this.background.src = "imgs/bg.png";
  11. }
  1.  

接下来,我们创建Drawable对象,所有以后的可以运动的物体对象都继承于它,Drawable对象包含一个空的draw方法。

  1. /**
  2. * Creates the Drawable object which will be the base class for
  3. * all drawable objects in the game. Sets up default variables
  4. * that all child objects will inherit, as well as the default
  5. * functions.
  6. */
  7. function Drawable() {
  8. this.init = function(x, y) {
  9. // Default variables
  10. this.x = x;
  11. this.y = y;
  12. }
  13. this.speed = 0;
  14. this.canvasWidth = 0;
  15. this.canvasHeight = 0;
  16. // Define abstract function to be implemented in child objects
  17. this.draw = function() {
  18. };
  19. }
  1. 接下来我们创建背景Background对象,注意红色部分的代码,红色2句代码是背景移动的核心。
  1. 第一句让背景从纵坐标0开始向下移动,第二句让背景从纵坐标(0-画布)高度开始向下移动,这样就产生了背景在不断向下移动的效果。
    最后一句蓝色代码是将
    Background对象的原形设置为Drawable对象,继承Drawable中的变量和方法。
  1. /**
  2. * Creates the Background object which will become a child of
  3. * the Drawable object. The background is drawn on the "background"
  4. * canvas and creates the illusion of moving by panning the image.
  5. */
  6. function Background() {
  7. this.speed = 1; // Redefine speed of the background for panning
  8. // Implement abstract function
  9. this.draw = function() {
  10. // Pan background
  11. this.y += this.speed;
  12. this.context.drawImage(imageRepository.background, this.x, this.y);
  13. // Draw another image at the top edge of the first image
  14. this.context.drawImage(imageRepository.background, this.x, this.y - this.canvasHeight);
  15. // If the image scrolled off the screen, reset
  16. if (this.y >= this.canvasHeight)
  17. this.y = 0;
  18. };
  19. }
  20. // Set Background to inherit properties from Drawable
  21. Background.prototype = new Drawable();
  1.  

最后一步

创建Game对象,Game对象获得web页面中定义的画布,初始化背景对象Background,设置背景对象的context以及画布宽,画布高属性。

  1. /**
  2. * Creates the Game object which will hold all objects and data for
  3. * the game.
  4. */
  5. function Game() {
  6. /*
  7. * Gets canvas information and context and sets up all game
  8. * objects.
  9. * Returns true if the canvas is supported and false if it
  10. * is not. This is to stop the animation script from constantly
  11. * running on older browsers.
  12. */
  13. this.init = function() {
  14. // Get the canvas element
  15. this.bgCanvas = document.getElementById('background');
  16. // Test to see if canvas is supported
  17. if (this.bgCanvas.getContext) {
  18. this.bgContext = this.bgCanvas.getContext('2d');
  19. // Initialize objects to contain their context and canvas
  20. // information
  21. Background.prototype.context = this.bgContext;
  22. Background.prototype.canvasWidth = this.bgCanvas.width;
  23. Background.prototype.canvasHeight = this.bgCanvas.height;
  24. // Initialize the background object
  25. this.background = new Background();
  26. this.background.init(0,0); // Set draw point to 0,0
  27. return true;
  28. } else {
  29. return false;
  30. }
  31. };
  32. // Start the animation loop
  33. this.start = function() {
  34. animate();
  35. };
  36. }

以下是动画功能的实现,其中requestAnimFrame类似一个timer,会不定期的回调 animate()函数; animate()函数中调用game.background.draw();不断的重绘背景图片的位置,以实现背景滚动的动画效果。

  1.  
  1. /**
  2. * The animation loop. Calls the requestAnimationFrame shim to
  3. * optimize the game loop and draws all game objects. This
  4. * function must be a gobal function and cannot be within an
  5. * object.
  6. */
  7. function animate() {
  8. requestAnimFrame( animate );
  9. game.background.draw();
  10. }
  11. /**
  12. * requestAnim shim layer by Paul Irish
  13. * Finds the first API that works to optimize the animation loop,
  14. * otherwise defaults to setTimeout().
  15. */
  16. window.requestAnimFrame = (function(){
  17. return window.requestAnimationFrame ||
  18. window.webkitRequestAnimationFrame ||
  19. window.mozRequestAnimationFrame ||
  20. window.oRequestAnimationFrame ||
  21. window.msRequestAnimationFrame ||
  22. function(/* function */ callback, /* DOMElement */ element){
  23. window.setTimeout(callback, 1000 / 60);
  24. };
  25. })();

最后启动程序:

  1. /**
  2. * Initialize the Game and starts it.
  3. */
  4. var game = new Game();
  5. function init() {
  6. if(game.init())
  7. game.start();
  8. }
  1. 最后的运行效果如下:

博主其他系列博文推荐:

1.网络采集软件核心技术剖析系列博文索引

2.手把手教你使用FineUI开发一个b/s结构的取送货管理信息系统系列博文索引

Step by Step 使用HTML5开发一个星际大战游戏(1)的更多相关文章

  1. Step by Step 使用HTML5开发一个星际大战游戏(2)

    HTML5 Canvas Game: 玩家飞船  本系列博文翻译自以下文章 http://blog.sklambert.com/html5-canvas-game-the-player-ship/ L ...

  2. 使用HTML5开发Kinect体感游戏

    一.简介 我们要做的是怎样一款游戏? 在前不久成都TGC2016展会上,我们开发了一款<火影忍者手游>的体感游戏,主要模拟手游章节<九尾袭来 >,用户化身四代,与九尾进行对决, ...

  3. Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状)

    Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状) 本篇博客来给大家介绍怎样使用Lua这门语言来开发一个简单的小游戏-记数字踩白块. 游戏的流程是这种:在界面上生成5个数1~5字并显 ...

  4. 使用Cocos2dx-JS开发一个飞行射击游戏

    一.前言 笔者闲来无事,某天github闲逛,看到了游戏引擎的专题,引起了自己的兴趣,于是就自己捣腾了一下Cocos2dx-JS.由于是学习,所谓纸上得来终觉浅,只是看文档看sample看demo,并 ...

  5. HTML5 - 开发一个自己的websocket服务器

    应用:node.js 主要步骤: 创建文件夹 创建app.js(server入口,app为自定义命名) npm init -y (快速创建一个package.json文件) 依赖包安装:nodejs- ...

  6. 从零开始手把手教你使用javascript+canvas开发一个塔防游戏01地图创建

    项目演示 项目演示地址: 体验一下 项目源码: 项目源码 代码结构 本节做完效果 游戏主页面 index.html <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  7. 用Python做一个飞机大战游戏

    基于pygame的一款小游戏 这是我上半年做的一款小游戏,但是一直忘记了,现在才上传代码. github项目地址:StarMan 代码基于pygame,Python版本3.5.2运行正常. 游戏很简单 ...

  8. Nginx 模块开发(1)—— 一个稍稍能说明问题模块开发 Step By Step 过程

    1. Nginx 介绍        Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/S ...

  9. Step by Step: 基于MFC下的COM组件开发-Helloworld

    http://blog.csdn.net/sybifei/article/details/45008745 [这篇文章有问题, 仅供参考] http://blog.csdn.net/define_us ...

随机推荐

  1. 动态规划:状压DP-斯坦纳树

    最小生成树是最小斯坦纳树的一种特殊情况 最小生成树是在给定的点集和边中寻求最短网络使所有点连通 而最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网络开销最小 BZOJ2595 题意是给定一个棋盘 ...

  2. [洛谷P3501] [POI2010]ANT-Antisymmetry

    洛谷题目链接:[POI2010]ANT-Antisymmetry 题目描述 Byteasar studies certain strings of zeroes and ones. Let be su ...

  3. 【UOJ131/NOI2015D2T2-品酒大会】sam求后缀树

    题目链接:http://uoj.ac/problem/131 题意:给出一个字符串,第i个字符对应的值为a[i], 对于i∈[0,n),求最长公共前缀大于等于i的字串对个数,并求这些字符串对开头对应值 ...

  4. [bzoj1823][JSOI2010]满汉全席——2-SAT

    题目大意 题目又丑又长我就不贴了,说一下大意,有n种菜,m个评委,每一个评委又有两种喜好,每种菜有满汉两种做法,只能选一种.判断是否存在一种方案使得所有评委至少喜欢一种菜品.输入包含多组数据. 题解 ...

  5. 常用的find命令

    find命令 find [路径名] –name/-size/-perm find [路径名] –name “*p” 在路径搜索p结尾的文件夹及文件 find [路径名] –name “[ab]*” 在 ...

  6. Navigator与UserAgent笔记

    关于Navigator与UserAgent笔记 1.Navigator笔记 Navigator对象主要是包含有关客户端浏览器的一些信息,Navigator对象是由JavaScript runtime ...

  7. css样式表中的样式覆盖顺序(转)

    有时候在写CSS的过程中,某些限制总是不起作用,这就涉及了CSS样式覆盖的问题,如下 Css代码   #navigator { height: 100%; width: 200; position:  ...

  8. C# WinForm开发 取消窗体关闭按钮

    //禁用窗体的关闭按钮 private const int CP_NOCLOSE_BUTTON = 0x200; protected override CreateParams CreateParam ...

  9. 运行微信支付demo

    首先要说说写这篇文章的初衷:集成支付宝支付运行demo都是可以正常运行的,但是我下载下来微信支付的demo,却发现一大堆报错,而且相关文章几乎没有,可能大家觉得没必要,也许你觉得很简单:但是技术大牛都 ...

  10. linux下redis的最佳实践(Master-Slave)

    本文演示了redis在同一台linux上的安装及运行多个实例,并演示了主从复制,以及如何进行主从的切换. 1. 下载 $ wget http://download.redis.io/releases/ ...