欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

说我死宅?看我在标准世界地图上来回摩擦!

程序员文章站 2024-03-16 21:33:52
...

※ 图片资源 来源于CreateJs官方Project
地图来源 自然资源部地图技术审查中心承办的标准地图服务网站 世界地图 小8开 审图号:GS(2016)1663号
想要了解和下载更多关于 标准地图 的内容,欢迎访问中国地图出版集团官网中国地图出版集团官方微博

效果演示

说我死宅?看我在标准世界地图上来回摩擦!

代码分释

整体思路

通过SpriteSheet构建一个可操作的动画,利用Ticker进行计时的事件触发,通过鼠标事件控制前进方向和跳跃动画的转换。

主要显示元素

  • sky 背景地图层
  • ground 下方地面层
  • hill & hill2 后方绿山层
  • grant 动画人物层

次要显示元素

  • jump & direct & text_jump & text_direct 按钮形状和按钮文字
  • mark 地图标识

0 加载资源

manifest = [
    { src: "spritesheet_grant.png", id: "grant" },
    { src: "sky_map.png", id: "sky" },
    { src: "ground.png", id: "ground" },
    { src: "hill1.png", id: "hill" },
    { src: "hill2.png", id: "hill2" },
    { src: "map_mark.png", id: "mark" }
]

loader = new createjs.LoadQueue(false)
loader.addEventListener("complete", handleComplete)
loader.loadManifest(manifest, true, "../_assets/img/")

利用Preload.js中的LoadQueue方法,一次性加载所有资源

LoadQueue([preferXHR=true], [basePath=""], [crossOrigin=""])

  • preferXHR 确定预加载实例是否倾向于使用XHR(XML HTTP请求)或HTML标签进行加载。如果为false,则队列将在可能的情况下使用标签加载,并在必要时使用XHR。
  • basePath 加载之前,队列中所有项目的source参数之前的路径。以诸如http://或相对路径作为协议开头的源…/ 将不会接收基本路径。
  • crossOrigin 不推荐使用crossOrigin参数。改用LoadItem.crossOrigin

loadManifest(manifest,[loadNow=true],[basePath])

  • manifest 要加载的文件列表
  • loadNow 启动立即加载 or 等待加载调用
  • basePath 在每个文件之前添加基本路径

1 sky元素

sky = new createjs.Shape()
sky.graphics.beginBitmapFill(loader.getResult("sky")).drawRect(-1000, 0, 3000, h)
sky.cache(-1000, 0, 3000, h)

地图图片宽度3000,每1000一个循环

getResult(value,[rawResult=false])

  • value id或者src
  • rawResult 返回原始结果而不是格式化结果

2 ground元素

var groundImg = loader.getResult("ground")
ground = new createjs.Shape()
ground.graphics.beginBitmapFill(groundImg)
	.drawRect(-groundImg.width, 0, w + groundImg.width * 2, groundImg.height)
ground.tileW = groundImg.width
ground.y = h - groundImg.height
ground.cache(-groundImg.width, 0, w + groundImg.width * 2, groundImg.height)

地面图像宽度81,设定层宽度为960 + 81 * 2

beginBitmapFill(image,repetition,matrix)

  • image 用作图案的图像
  • repetition 重复类型,默认为repeat
  • matrix 指定位图填充转换矩阵

3 hill&hill2元素

hill = new createjs.Bitmap(loader.getResult("hill"))
hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4)
hill.alpha = 0.5

hill2 = new createjs.Bitmap(loader.getResult("hill2"))
hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3)

hill设定4倍图像大小,hill2设定3倍图像大小

setTransform([x=0], [y=0], [scaleX=1], [scaleY=1], [rotation=0], [skewX=0], [skewY=0], [regX=0], [regY=0])

  • x,y 水平垂直位移
  • scaleX,scaleY 水平垂直比例
  • rotation 旋转度数
  • skewX,skewY 水平垂直偏斜系数
  • regX,regY 水平垂直配准点

4 grant元素

var spriteSheet = new createjs.SpriteSheet({
    framerate: 30,
    "images": [loader.getResult("grant")],
    "frames": { "regX": 82, "height": 292, "count": 64, "regY": 0, "width": 165 },
    "animations": {
        "run": [0, 25, "run", 1.5],
        "jump": [26, 63, "run"]
    }
})
grant = new createjs.Sprite(spriteSheet, "run")
grant.y = 35

设置雪碧图显示列表元素,并设置runjump动画

SpriteSheet(data)

  • data:{images,frames,animations,framerate}
  • images 雪碧图资源
  • frameate 帧率
  • frames 镜框
    • widthheight 为必填项,并指定框架的尺寸
    • regXregY 指示框架的注册点或“原点”
    • spacing 指示帧之间的间隔
    • margin 指定图像周围的边距
    • count 允许您指定子画面中的帧总数;如果省略,将根据源图像和帧的尺寸进行计算。将根据帧在源图像中的位置(从左到右,从上到下)为帧分配索引。
  • animations 动画 定义要作为命名动画播放的帧序列
    • start 开始针,end 结束帧,next 动画完成后进行的动画,和speed 播放速度。

5 jumpdirecttext_directtext_jumpmark元素

jump = new createjs.Shape(
    new createjs.Graphics().beginFill('lightblue').drawCircle(w - 50, h - 50, 35)
)
jump.shadow = new createjs.Shadow('rgba(0,0,0,0.2)', 5, 5, 5)
jump.cache(0, 0, w, h)

direct = new createjs.Shape(
    new createjs.Graphics().beginFill('lightgreen').drawCircle(w - 140, h - 50, 35)
)
direct.shadow = new createjs.Shadow('rgba(0,0,0,0.2)', 5, 5, 5)
direct.cache(0, 0, w, h)

direct.addEventListener('mousedown', handleTurnDirection)
jump.addEventListener('mousedown', handleJumpStart)

text_direct = new createjs.Text("Turn\nRound", "20px Arial", "#fff")
text_direct.set({ x: w - 140, y: h - 70 })
text_direct.textAlign = 'center'

text_jump = new createjs.Text("Jump", "20px Arial", "#fff")
text_jump.set({ x: w - 50, y: h - 60 })
text_jump.textAlign = 'center'

mark = new createjs.Bitmap(loader.getResult('mark'))
mark.setTransform(200, 50, 0.1, 0.1)

direct 设置鼠标点击事件 handleTurnDirection 转换方向
jump 设置鼠标点击事件 handleJumpStart 切换跳跃动画

6 鼠标点击事件handleTurnDirection&handleJumpStart

function handleJumpStart() {
    grant.gotoAndPlay("jump")
}

function handleTurnDirection(event) {
    direction *= -1
    grant.scaleX = direction
}

direction1-1 ,分别代表向右和向左
7 计时tick事件

function tick(event) {
    var deltaS = event.delta / 1000
    var position = grant.x + 150 * deltaS * direction
	// 人物平移
    var grantW = grant.getBounds().width * grant.scaleX * direction
    grant.x = (position >= w + grantW) ? -grantW : ((position < -grantW) ? w + grantW : position)
	// 地面平移
    ground.x = (ground.x - deltaS * 150 * direction) % ground.tileW
    // 山丘平移
    hill.x = (hill.x - deltaS * 30 * direction)
    if (hill.x + hill.image.width * hill.scaleX <= 0) {
        hill.x = w
    }
    if (hill.x >= w) {
        hill.x = - hill.image.width * hill.scaleX
    }    
    hill2.x = (hill2.x - deltaS * 45 * direction)
    if (hill2.x + hill2.image.width * hill2.scaleX <= 0) {
        hill2.x = w
    }
    if (hill2.x >= w) {
        hill2.x = - hill2.image.width * hill2.scaleX
    }
	// 背景平移
    sky.x = (sky.x - deltaS * 5 * direction)
    if (sky.x <= -1000) {
        sky.x = -2
    }
    if (sky.x >= 1000) {
        sky.x = 2
    }

    stage.update(event)
}

全部代码

Github - SpriteSheet

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>EaselJS: Sprite Sheet Example</title>

    <link href="../_assets/css/shared.css" rel="stylesheet" type="text/css" />
    <script src="../_assets/js/shared.js"></script>

    <script src="../lib/easeljs-NEXT.js"></script>
    <!-- We also provide hosted minified versions of all CreateJS libraries.
	  http://code.createjs.com -->
    <script src="../lib/preloadjs-NEXT.min.js"></script>

    <script id="editable">
        var stage, w, h, loader
        var sky, grant, ground, hill, hill2
        var direct, jump
        var text_direct, text_jump
        var direction = 1

        function init() {
            shared.loading()

            stage = new createjs.Stage("examCanvas")

            w = stage.canvas.width
            h = stage.canvas.height

            manifest = [
                { src: "spritesheet_grant.png", id: "grant" },
                { src: "sky_map.png", id: "sky" },
                { src: "ground.png", id: "ground" },
                { src: "hill1.png", id: "hill" },
                { src: "hill2.png", id: "hill2" },
                { src: "map_mark.png", id: "mark" }
            ]

            loader = new createjs.LoadQueue(false)
            loader.addEventListener("complete", handleComplete)
            loader.loadManifest(manifest, true, "../_assets/img/")
        }

        function handleComplete() {
            shared.loaded()

            sky = new createjs.Shape()
            sky.graphics.beginBitmapFill(loader.getResult("sky")).drawRect(-1000, 0, 3000, h)

            sky.cache(-1000, 0, 3000, h)

            var groundImg = loader.getResult("ground")
            ground = new createjs.Shape()
            ground.graphics.beginBitmapFill(groundImg)
                .drawRect(-groundImg.width, 0, w + groundImg.width * 2, groundImg.height)
            ground.tileW = groundImg.width
            ground.y = h - groundImg.height

            ground.cache(-groundImg.width, 0, w + groundImg.width * 2, groundImg.height)

            hill = new createjs.Bitmap(loader.getResult("hill"))
            hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4)
            hill.alpha = 0.5

            hill2 = new createjs.Bitmap(loader.getResult("hill2"))
            hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3)

            var spriteSheet = new createjs.SpriteSheet({
                framerate: 30,
                "images": [loader.getResult("grant")],
                "frames": { "regX": 82, "height": 292, "count": 64, "regY": 0, "width": 165 },
                "animations": {
                    "run": [0, 25, "run", 1.5],
                    "jump": [26, 63, "run"]
                }
            })
            grant = new createjs.Sprite(spriteSheet, "run")
            grant.y = 35

            stage.addChild(sky, hill, hill2, ground, grant)

            jump = new createjs.Shape(
                new createjs.Graphics().beginFill('lightblue').drawCircle(w - 50, h - 50, 35)
            )
            jump.shadow = new createjs.Shadow('rgba(0,0,0,0.2)', 5, 5, 5)
            jump.cache(0, 0, w, h)

            direct = new createjs.Shape(
                new createjs.Graphics().beginFill('lightgreen').drawCircle(w - 140, h - 50, 35)
            )
            direct.shadow = new createjs.Shadow('rgba(0,0,0,0.2)', 5, 5, 5)
            direct.cache(0, 0, w, h)

            direct.addEventListener('mousedown', handleTurnDirection)
            jump.addEventListener('mousedown', handleJumpStart)

            stage.addChild(direct, jump)

            text_direct = new createjs.Text("Turn\nRound", "20px Arial", "#fff")
            text_direct.set({ x: w - 140, y: h - 70 })
            text_direct.textAlign = 'center'

            text_jump = new createjs.Text("Jump", "20px Arial", "#fff")
            text_jump.set({ x: w - 50, y: h - 60 })
            text_jump.textAlign = 'center'

            mark = new createjs.Bitmap(loader.getResult('mark'))
            mark.setTransform(200, 50, 0.1, 0.1)

            stage.addChild(mark, text_direct, text_jump)

            createjs.Ticker.timingMode = createjs.Ticker.RAF
            createjs.Ticker.addEventListener("tick", tick)

        }

        function handleJumpStart() {
            grant.gotoAndPlay("jump")
        }

        function handleTurnDirection(event) {
            direction *= -1
            grant.scaleX = direction
        }

        function tick(event) {
            var deltaS = event.delta / 1000
            var position = grant.x + 150 * deltaS * direction

            // 得到的是人物的宽度
            var grantW = grant.getBounds().width * grant.scaleX * direction
            grant.x = (position >= w + grantW) ? -grantW : ((position < -grantW) ? w + grantW : position)

            ground.x = (ground.x - deltaS * 150 * direction) % ground.tileW
            hill.x = (hill.x - deltaS * 30 * direction)
            if (hill.x + hill.image.width * hill.scaleX <= 0) {
                hill.x = w
            }
            if (hill.x >= w) {
                hill.x = - hill.image.width * hill.scaleX
            }
            hill2.x = (hill2.x - deltaS * 45 * direction)
            if (hill2.x + hill2.image.width * hill2.scaleX <= 0) {
                hill2.x = w
            }
            if (hill2.x >= w) {
                hill2.x = - hill2.image.width * hill2.scaleX
            }

            sky.x = (sky.x - deltaS * 5 * direction)
            if (sky.x <= -1000) {
                sky.x = -2
            }
            if (sky.x >= 1000) {
                sky.x = 2
            }

            stage.update(event)
        }
    </script>
</head>

<body onload="init()">
    <header class="Nora7aki">
        <h1>雪碧图列表动画 Sprite Sheets</h1>

        <p>
            通过<code>SpriteSheet</code>构建一个可操作的动画,通过鼠标控制前进方向和跳跃
        </p>

        <p>
            <strong>Note:</strong> Some browsers can not load images or access pixel
            data when running local files, and may throw a security error or not
            work unless the content is running on a server.
        </p>
    </header>

    <div class="content" style="overflow: hidden;width: 960px;height: 400px">
        <canvas id="examCanvas" width="960" height="400"></canvas>
    </div>

</body>

</html>