本节开始,我们将基于上一个项目所学到的知识,利用createjs 和 Tween两个图形绘制库开发一款新的游戏,名为欲望都市。这个游戏具备一个特点就是2.5D,它是一种经济系统构建型游戏,开始时玩家得到的是一个空白的城市地图,玩家以市长的身份选择在城市中构建各种设施,通过不同设施的组合何以产生金币,基本情况如下:

VUE+WebPack游戏设计:欲望都市,构建类RPG游戏的开发_createjs

玩家可以在每一个小格配置一种建筑,总共可以有三种建筑可以选择,一种是电厂,建造电厂可以增加人口,有了人口才能建造其他建造,依据上图,黄色带有闪电标识的建筑就是电厂,第二种建筑胶钱币工厂,有了这种建筑,城市才会有收入,但是建筑钱币工厂会消耗人口,右上角的标识意思是当前城市可以容纳70人口,其中50个人口已经被钱币工厂消耗掉了。第三种建筑是商店,有了商店就可以使用金币购买钻石,玩家的任务是配置三种建筑,最终使得城市具有的金币和钻石数量最大化,三种可供选择的建筑如下:

VUE+WebPack游戏设计:欲望都市,构建类RPG游戏的开发_游戏设计_02

选取其中一种建筑后,就可以通过鼠标把建筑拖拽到城市土地的小格子中,建筑的建造过程跟‘红警’类似,经过一系列形态变化后才最终形成相应模样,因此玩起来时也是饶有趣味。

在游戏开发时,我们把整个设计分成三部分,一部分叫背景图层,第一张图中,蓝色的背景加上飘动的云朵就是背景图层;第二部分叫城市图层,最上图中中间部分,用来配置各种建筑图案区域就是城市图层,第三部分叫UI图层,第一张图中,画面上的各种按钮,标志,例如右上角的人口数量标志,右下角的按钮,左上角的钱币数量标志和钻石数量标志,他们合在一起形成了UI图层,整个游戏的开发将分别处理三个图层,然后再通过底层逻辑把三个图层整合成一个整体。

首先我们先动手开发背景图层的功能。先像以前项目一样启动一个新的VUE工程,然后在index.html里面把createjs和tween这两个库引入项目,代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script type="text/javascript" src="./static/tweenjs-0.5.1.min.js"></script>
    <script type="text/javascript" src="./static/easeljs-0.7.1.min.js"></script>
    <script type="text/javascript">
      window.createjs = createjs
    </script>
    <title>Isometric City</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

接着再components目录中,创建gamecontainer.vue这个容器组件,它的内容跟上一个项目一样,这里就不详述了,我们看看gamecomponent.vue的代码实现,首先我们需要给页面添加一个canvas控件,因为所有的游戏动画都需要绘制在canvas控件上:

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

接着我们实现游戏的逻辑代码,由于我们先实现背景图层,游戏的背景是一个大蓝天,同时有两朵白云动态的从右边慢慢飘向左边,因此我们要实现这个动画效果,首先我们设置组件的内部数据:

<script>
  export default {
    data () {
      return {
        gameWidth: 960,
        gameHeight: 480,
        cjs: null,
        canvas: null,
        stage: null
      }
    },
    ....
}

游戏的宽和高分别是960和480像素,cjs将用来对应createjs的库对象,canvas对应画布控件对象,stage是用来容纳一切动画元素的容器对象,它的具体说明在上一个项目详细讲解过。

接下来实现组件的初始化,当组件被页面加载时,他需要做一系列的数据初始化操作,代码如下:

init () {
        this.cjs = window.createjs
        this.canvas = document.getElementById('canvas')
        this.stage = new this.cjs.Stage(this.canvas)
        var backGround = this.bgLayer()
        this.stage.addChild(backGround)
        this.cjs.Ticker.setFPS(40)
        this.cjs.Ticker.addEventListener('tick', this.tick)
      },
      tick () {
        this.stage.update()
      },

其中的backGround就是我们一会要开发的背景图层对象,我们设置画面的更新频率是每秒40帧。接下来我们看看背景图层是如何设计的,代码如下:

layer () {
        var obj = new this.cjs.Container()
        return obj
      },
      cityLayer () {
        var obj = this.layer()
        return obj
      },
      bgLayer () {
        var layer = this.layer()
        var bitmap = new this.cjs.Bitmap('../../static/images/bg.png')
        layer.addChild(bitmap)

        var cloud1 = new this.cjs.Bitmap('../../static/images/cloud1.png')
        cloud1.y = 30
        cloud1.alpha = 0.4
        layer.addChild(cloud1)

        this.cjs.Tween.get(cloud1, {loop: true}).to({x: this.gameWidth + 300}, 0).wait(15500).to({x: -300}, 50 * 1000)

        var cloud2 = new this.cjs.Bitmap('../../static/images/cloud2.png')
        cloud2.y = 300
        cloud2.alpha = 0.4
        layer.addChild(cloud2)

        this.cjs.Tween.get(cloud2, {loop: true}).to({x: this.gameWidth + 50}, 0).wait(500).to({x: -300}, 50 * 1000)

        return layer
      }

layer函数是所有图层对象的基础,它返回的是一个容器对象,cityLayer返回的是城市图层,这里我们先简单返回一个容器对象,以后再进行详细的代码添加。bgLayer()函数绘制的就是背景图层了,它先加载两张图片,作为位图对象,这两张图片对应两片云彩,代码分别设置两片云彩图案在页面上绘制的位置y坐标为30和300,透明度是0.4,其中两个语句:

this.cjs.Tween.get(cloud1, {loop: true}).to({x: this.gameWidth + 300}, 0).wait(15500).to({x: -300}, 50 * 1000)

this.cjs.Tween.get(cloud2, {loop: true}).to({x: this.gameWidth + 50}, 0).wait(500).to({x: -300}, 50 * 1000)

第一个语句的作用是,先让第一张图片处于画布最右方再向右偏移300像素的位置,然后等待大概15秒,也就是wait(15500)的作用,然后产生动画效果,把图案从原来的位置平移到x坐标为左边-300像素的地方,这个渐变过程持续50秒,也就是to的第二个参数50*1000。

第二句代码的作用是一样的,上面代码完成后,加载页面,可以得到如下效果:

VUE+WebPack游戏设计:欲望都市,构建类RPG游戏的开发_createjs_03

两片白云图案慢慢的从右边挪动到左边,完了后这个过程不断重复。这就完成了我们想要的背景图层的设计。接下来我们完成UI图层的设计,继续在组件中添加如下代码:

uiLayer () {
        var obj = this.layer()
        this.setupHUD(obj)
        return obj
      },
      placeBitmap (layer, path, x, y) {
        var bitmap = new this.cjs.Bitmap(path)
        bitmap.x = x
        bitmap.y = y
        layer.addChild(bitmap)
      },
      placeText (layer, textStr, size, x, y, align) {
        var text = new this.cjs.Text(textStr, size + 'px Arial', '#222')
        text.x = x
        text.y = y
        text.textAlign = align
        layer.addChild(text)
        return text
      },
      setupHUD (layer) {
        this.placeBitmap(layer, '../../static/images/candies.png', 28, 16)
        this.placeBitmap(layer, '../../static/images/diamonds.png', 154, 14)
        this.placeBitmap(layer, '../../static/images/populations.png', 810, 14)

        this.consIndicator = this.placeText(layer, '12345', 12, 123, 34, 'right')
        this.diamondsIndicator = this.placeText(layer, '0', 12, 250, 34, 'right')
        this.populationIndicator = this.placeText(layer, '100', 16, 845, 32, 'center')
      }
    }

上面代码加载了几个图片,并生成了几个字符串对象,然后把他们添加到一个图层容器中,最后我们在初始化函数中,把UI图层对象添加到舞台容器中:

init () {
    ....
    var uilayer = this.uiLayer()
    var citylayer = this.cityLayer()
    this.stage.addChild(backGround)
    this.stage.addChild(uilayer)
    this.stage.addChild(citylayer)
    ....    
}

完成上面代码后,我们得到的游戏场景如下:

VUE+WebPack游戏设计:欲望都市,构建类RPG游戏的开发_2-5D游戏设计_04

到这里,我们就完成了第一阶段的背景图层和UI图层的设计,接下来我们将把精力集中到游戏图层以及游戏主逻辑的设计之中。

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

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