1. 程式人生 > 其它 >說我死宅?看我在標準世界地圖上來回摩擦!

說我死宅?看我在標準世界地圖上來回摩擦!

技術標籤:CreateJsjscanvas

※ 圖片資源 來源於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>