VUE+WebPack游戏设计:'乘法防线'游戏设计

更详细的讲解和代码调试演示过程,请点击链接

从本节开始,我们进入新的游戏设计阶段。本次游戏设计,我们需要使用html5专有的canvas,也就是画布对象。同时为了便于在canvas上绘制图案,我们引入一个第三方库叫做CreateJS,它能帮我们管理在canvas上绘制的各种图形。

这里写图片描述

乘法防线的游戏目的是为了帮助小学生学习乘法运算法则。游戏的主要内容是,很多个盒子从天而降,盒子里面含有一个数字,在界面的底部,有两排数字按钮,玩家选择底部两个数字按钮,点击后游戏会计算玩家选中的两个按钮数值乘机,如果乘机结果跟正在下落的盒子数值一样,那么这个盒子就会爆掉,画面中那个绿色的圆圈就是盒子爆掉后显示的情形。当盒子下落超过底边防线时,游戏就结束了。

从技术上看,游戏的一大要点在于如何使用html5的canvas对象绘制图案,并且如何利用canvas接口实现绚丽的动画效果。整个游戏的开发将有赖于canvas和第三方库CreateJS,使用canvas,我们能够在页面上产生精准到像素级别的图画,并且体会到,利用canvas进行页面渲染能够有效的降低系统负载。

话不多说,上代码才是真正的王道。先创建一个WebPack项目,同时把含有CreateJS的第三方库文件easeljs-0.7.1.min.js拷贝到项目的static文件目录下,该第三方文件和所有项目代码,请到网易云课堂下载。在项目根目录下,打开index.html文件,进行如下代码修改:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="./static/easeljs-0.7.1.min.js"></script>
    <script type="text/javascript">
      window.createjs = createjs
    </script>
    <title>Multiply Defense</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>

</html>

我们先把第三方库文件加载到项目中,同时把包含在库文件中的createjs对象赋值到window对象里,后面我们开发组件时,需要从window全局对象获取createjs对象。

进入到src/components/目录,根据以往流程,我们在该目录下新建一个文件叫gamescontainer.vue,并在里面添加如下内容:

<template>
  <div>
    <header>
      <div class="row">
        <h1>Multiply Defense</h1>
      </div>
    </header>
    <section id="game" class="row">
      <game-scene></game-scene>
    </section>
  </div>
</template>

<script>
  import GameScene from './GameSceneComponent'
  export default {
    components: {
      GameScene
    }
  }
</script>

<style scoped>
  #game {
    position: relative;
    width: 300px;
    height: 480px;
    border: 1px solid black;
  }

</style>

代码逻辑在前面章节已经描述多次,这里就不复述了。真正发挥作用的,将是我们接下来要开发的组件,也就是GameScene,在components目录下新建一个文件,命名为gamescenecomponent.vue,打开后添加如下代码内容:

<template>
  <div>
    <canvas id="canvas" width="300" height="480">
    </canvas>
  </div>
</template>

template标签用来实现组件要做页面上渲染的内容,这里我们构建了一个canvas对象,并设置它的宽和高分别是300和480,所有的游戏动画特效都将依赖这个画布组件来实现,在同一个文件中增加如下代码:

<script>
 export default {
   data () {
     return {
       stage: null,
       canvas: null
     }
   },

   mounted () {
     this.canvas = document.getElementById('canvas')
     this.stage = new window.createjs.Stage(this.canvas)
     var hello = new window.createjs.Text('Hello CreateJS', '18px', 'white')
     this.stage.addChild(hello)
     this.stage.update()
   }
 }
</script>

<style scoped>
  #canvas {
    background: #333; 
  }
</style>

在组件加载时,mounted 函数会被调用,在函数里,我们先获取画布canvas的对象,并通过window对象获取前面从第三方库中拿到的createjs对象,接着我们通过new从createjs对象里构建了一个Stage对象,在构建时,把canvas对象当参数传进去。接着我们再从createjs对象里构建一个Text对象,顾名思义,它使用来在页面上显示字符串的,字符串的内容就是'Hello CreateJS',第二个参数表示字体大小是18像素单位,第三个参数用来指定字体的颜色。上面代码运行的效果就是在页面上以白色字体,用18个像素大小的字体在页面上显示一个字符串'Hello CreateJS'。完成代码后,在项目的根目录下执行命令 npm run dev,页面会自动在浏览器中加载,然后显示出如下情形:

这里写图片描述

对CreateJS的详细文档可以从以下链接获取

代码中的Text对象是CreateJS库中的一个子类,它的作用是在页面上渲染字符串,就如例子中一样。CreateJS提供的对象接口让我们在输出字符串时,能轻易的设定字体的大小,颜色,和样式。CreateJS使用了容器化的设计思想,任何能在页面上显示的元素都必须作为容器的一部分加入到容器中,例如例子中的Stage就类似于组装所以显示元素的容器,每种显示元素都要调用addChild加入父容器,当所有要显示的内容都加入容器后,再通过调用stage.update把容器里面包含的所有要显示的要素全部渲染到页面上。

接下来我们看看如何绘制含有数字的盒子。
在gamescenecomponent.vue中添加如下代码:

export default {
   data () {
     return {
       stage: null,
       canvas: null,
       boxWidth: 50,
       boxHeight: 20,
       gameWidth: 300,
       gameHeight: 480,
       createjs: null,
       numberBoxes: []
     }
   },

boxWidth和boxHeight定义了数字盒子的宽和高,numberBoxes用来存储所有数字盒子对象,接着上面代码,继续添加以下代码:

mounted () {
     this.init()
     this.generateNumberBox()
     this.stage.update()
   },

   methods: {
     init () {
       this.createjs = window.createjs
       this.canvas = document.getElementById('canvas')
       this.stage = new this.createjs.Stage(this.canvas)
     },
     rectShape (width, height, style) {
       var obj = new this.createjs.Container()
       style = style || {}
       style.strokeWidth = style.strokeWidth || 0
       style.strokeColor = style.strokeColor || 0
       style.fillColor = style.fillColor || 'rgb(255, 0, 0, 1)'

       var shape = new this.createjs.Shape()
       shape.graphics.setStrokeStyle(style.strokeWidth).beginStroke(style.strokeColor).beginFill(style.fillColor).drawRect(0, 0, width, height)
       obj.addChild(shape)
       return obj
     },
     box () {
       return this.rectShape(this.boxWidth, this.boxHeight, null)
     },
     numberBox (value) {
       var boxObj = this.box()
       var text = new this.createjs.Text(value, '24px Impact', 'red')
       text.textBaseline = 'middle'
       text.textAlign = 'center'
       text.x = this.boxWidth / 2
       text.y = this.boxHeight / 2
       boxObj.addChild(text)
       return boxObj
     },
     randomInt (min, max) {
       return Math.floor(Math.random() * (max - min + 1) + min)
     },
     generateNumberBox () {
       var value = this.randomInt(1, 12) * this.randomInt(1, 12)
       var box = this.numberBox(value)
       box.x = Math.random() * (this.gameWidth - this.boxWidth)
       box.y = 0
       this.stage.addChild(box)
       this.numberBoxes.push(box)
     }

rectShape 用来在页面绘制一个方形盒子图案,它先从createjs库中创建一个Container对象,container跟前面讲过的Stage类似,是可以用来包含显示元素的容器对象,同时定义了盒子的绘制样式style, style.strokeWidth 表示盒子的边界线宽度,style.strokeColor用来显示盒子的边界线颜色,style.fillColor用来表示盒子的填充颜色。

接着构建一个绘制对象叫Shape,这个类专门用来绘制盒子,Shape包含一个子类叫graphics,通过这个类设置前面定义的绘制样式,最后通过drawRect函数把盒子绘制到Shape对象里面,最后用addChild把绘制盒子图形的Shape对象加入Container.

numberBox接口,先是调用box接口去绘制一个方盒子图案,然后在创建一个字符串对象,设置好字符串对象的各种属性后,把它加入到rectShape返回的Container对象里,这样该对象就包含了两种先是元素,一个是正方形的盒子图案,一个是数字字符串。

generateBox接口先通过randomInt构造一个随机整数,然后把这个随机整数作为字符串绘制到方形盒子里,通过调用generateNumberBox接口后,页面上就可以渲染出一个含有数字的方盒子。

上面代码完成,并加装到浏览器后,运行效果如下:


这里写图片描述

我们可以看到顶部有一个黑色方块,里面含有一个红色的数字8,黑色方块是由rectShape函数绘制的,在generateNumberBox里,代码先通过randomInt生成随机数8,然后在numberBox里把数字8转换成字符串并绘制到rectShape构建的Container对象里,于是就形成了我们现在看到的一个黑色背景方框内有一个红色数字8.

CreateJS 有个核心类对象是DisplayObject, 代码中的Container, Shape以及后面可能要用到的Bitmap对象都属于DisplayObject:


这里写图片描述

CreateJS 提供的这些接口类,目的是让我们方便的在canvas上绘制各种复杂的图形图像,或者是高效的显示动画效果。

游戏的内容介绍和开发的第一步骤先介绍到这,下一节我们进入游戏主循环的开发中。更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:


这里写图片描述
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,397评论 25 707
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 复习《通往财富自由之路》——抱怨,我的一位朋友,他就是一个不抱怨的人。 在工作中,遇到不顺时,同样的情况,他和他的...
    浩林成长记录阅读 227评论 0 0
  • 不积跬步无以致千里,每日的积累才是最终结果的过程,数量引起的质变也是一条漫长的路径。 现在创业很多,很多人都想通过...
    斯里兰卡的蓝桉阅读 104评论 0 1
  • “心之如何,有似万丈迷津,遥亘千里,其中并无舟子可渡人,除了自渡,他人爱么能助”—三毛 我羡慕三毛的随性,...
    小屁孩艾特世界阅读 513评论 0 2