摘要:為了實現(xiàn)物體隨機出現(xiàn)的效果,讓每個物體隨機多少秒后開始出現(xiàn)最后一個物體出現(xiàn)完,多少秒后出現(xiàn)結(jié)束畫面等等,需要理清楚各個定時器的關(guān)系,并對其添加語義化良好的標記,及時對未完結(jié)的定時器進行清除,防止定時器帶來的意想不到的問題。
效果圖快到年終的時候做了一個以游戲形式展示的h5活動頁,第一次嘗試使用js寫小游戲,很有趣的過程,很寶貴的經(jīng)驗。
直接上個效果的gif圖,游戲的一小部分效果,錄出來有點卡
結(jié)果頁:
產(chǎn)品妹子突然給我拉進來一個群,跟我們講做了這么久的制作平臺(用戶制作手機主題的平臺),我們是不是應(yīng)該反饋給用戶點什么東西,就像之前特別火的微信年終總結(jié)那樣。總之就是要打動用戶,要特別酷。說特別酷的時候她回頭朝我微微一笑,微笑中帶著一點點,嗯,殺意。
活動形式,展現(xiàn)方式,什么數(shù)據(jù)反正就是統(tǒng)統(tǒng)都沒想好,整個過程中大家討論的熱火朝天。當時不知道我為啥腦子一熱,跟她說了一句:“沒事兒,搞吧,你能想出來我就給你做出來。”而我也因為這句話把自己置身于水深火熱之中。。
討論的結(jié)果就是大家的idea感覺都不是特別酷,又不好玩兒,干脆就做個游戲形式的吧!所有人都轉(zhuǎn)頭看向我,我想了想之前說的話,只吐出來一個字,“搞”。而內(nèi)心中五味雜陳,“游戲?有意思啊?搞!沒搞過啊?能搞定嗎?搞!”。最終敲定,兩周時間,游戲方式,展現(xiàn)用戶在魔秀的點點滴滴。
游戲的形式大概類似一個滑雪大冒險和賽車的結(jié)合,以賽車的形式進行偽3d效果的展現(xiàn),滑雪大冒險的樣式作為我們的主題,同時大家還給我們的游戲起了個酷炫的名字----魔秀時光道。
游戲引擎游戲的展現(xiàn)形式確定后,直覺告訴我,想要將游戲快速穩(wěn)定的呈現(xiàn),免去圖片加載控制,動畫控制之類的復(fù)雜處理,我需要一個JS游戲引擎。最終在EgretPhaserPixiJS中選定了PixiJS,雖然不像Egret一樣有完善的中文文檔,但是它提供了清晰易懂的examples可快速上手,沒有復(fù)雜的生態(tài),簡單的幾行代碼就可以用js實現(xiàn)我想要以下幾點功能:
容器渲染及背景描繪我需要定制整個畫布的大小和背景,我需要使用不同的容器來承接不同的內(nèi)容,并且靈活控制每個容器的屬性:
//畫布 var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb}); document.body.appendChild(app.view); //定制container var container = new PIXI.Container(); container.x = (app.renderer.width - container.width) / 2; container.y = (app.renderer.height - container.height) / 2; app.stage.addChild(container);圖片加載及動畫處理
大家都知道,使用canvas進行圖片繪制的時候,需要確定圖片已經(jīng)成功加載,而游戲中有著大量的圖片資源需要去維護,PixiJS已經(jīng)為我們提供此項服務(wù):
var bunny = PIXI.Sprite.fromImage("required/assets/basics/bunny.png’); bunny.x = app.renderer.width / 2; bunny.y = app.renderer.height / 2; app.stage.addChild(bunny);
同時,我們需要一個動畫控制器,來控制各Sprite的運動和重繪,而不是生硬的對各項屬性進行重新修改:
app.ticker.add(function(delta) { bunny.rotation += 0.1 * delta; });
需要注意的是,我們會發(fā)現(xiàn),此處的Sprite動畫控制,相當于添加了運動的動畫隊列,并且實現(xiàn)了類似transformjs的效果,可直接對實例的屬性進行操作。而我在寫項目的時候官方的例子是通過統(tǒng)一animate函數(shù)進行操作,通過requestAnimationFrame進行幀動畫控制,更推薦新的方式而不是如下:
function animate () { requestAnimationFrame(animate); bunny.rotation += 1; renderer.render(stage); }事件處理
游戲最重要的部分相當于用戶的交互了,也就是所謂的事件處理,為Sprite添加事件監(jiān)聽,很簡單,如下所示:
//元素可點擊 sprite.interactive = true; //鼠標移入cursor sprite.buttonMode = true; sprite.on("click", onClick); // mouse-only prite.on("tap", onClick); // touch-only function onClick () { sprite.scale.x *= 1.25; sprite.scale.y *= 1.25; }設(shè)計圖
設(shè)計圖當然也是很重要的,決定了我們?nèi)绾稳崿F(xiàn)這個游戲,當我拿到設(shè)計圖的時候,他是長成這樣的,我的內(nèi)心是崩潰的。我能怎么樣,我也很無奈呀~ 開搞吧!
根據(jù)以上,PixiJS已經(jīng)基本滿足我們的需求,也就是說,工具準備和素材準備已經(jīng)都完成了。在動手書寫之前,我們需要把實現(xiàn)思路想好,才能保證書寫過程的清晰,避免不必要的麻煩。
背景滑動效果實現(xiàn)就像我們平時玩兒賽車游戲一樣,我們感覺賽車在跑道上進行比賽,實際上賽車只進行左右移動而已,而運動的則是背景,如何規(guī)劃好路線,讓背景按照既定的場景去運動,并展現(xiàn)不同的視角,特意向央美的同胞咨詢了下,他們是用一個叫“攝像機”的東西實現(xiàn)的。對于我們來說,不需要那么復(fù)雜的場景,只需讓背景像前規(guī)律的“平移”,造成“樹動我不動”的視覺效果,同時我們利用“透視”的原理,讓背景以“近大遠小”的方式進行變化,就會產(chǎn)生一種low low的立體效果。
關(guān)鍵詞:透視 近大遠小(偏移,大小,速度)
偏移路線對于背景及物體的運動,大概路線規(guī)劃如下:
確定視覺焦點后,我們只需隨機生成物體出現(xiàn)的位置,計算出a,b相對固定,使其y進行相應(yīng)速度的增加,x根據(jù)運動軌跡進行對應(yīng)偏移,則可實現(xiàn)往近跑的效果。針對運動軌跡, 假設(shè)物體向下偏移距離為N,則對應(yīng)水平針對中軸線的偏移為:
同時,我們還需對物體進行近大遠小的顯示,這個比較簡單,以焦點為0,頁面最底端為1,進行對應(yīng)比例放大即可:
scale = (curY - startY) / ( endY - startY);運動速度
針對物體的運動速度,也應(yīng)在遠近有不同的體現(xiàn)。
背景樹與碰撞物體的區(qū)別針對背景樹,我們需在最初對所有的樹進行展現(xiàn),鋪滿兩邊背景。每列樹對應(yīng)的運動路線一致,可直接讓其進行循環(huán)展示,當樹運動到最底時,讓其出現(xiàn)在最頂點。因此只需確定一共有幾行幾列樹,并設(shè)定其邊界,根據(jù)行列確定初始唯一并對其進行運動。同時,可以讓樹進行小范圍的隨機偏移,使樹錯落有致。如下所示:
export default function Tree (row, col, direction) { this.cfg = { direction: direction, //方向 col: col, //第幾列 row: row, //第幾行 MaxX: 440, minY: 210, maxY: 500, range: 10 //坐標浮動范圍 } };
而針對物體,則需要隨機生成它的初始x坐標,并計算出其對于的路線進行運動,在運動過程中,進行碰撞檢測,檢測是否與人物進行相撞。
人物滑動實現(xiàn)人物滑動的操作,用了最簡單的實現(xiàn)方式:按鈕。當用戶點擊不同方向時,讓人物向?qū)?yīng)方向進行偏移。同時,為了讓人物滑動不僵硬,在左右滑動過程中,人也應(yīng)該隨著運動有對應(yīng)角度的傾斜,就像我們平時玩兒滑雪拐彎時,會改變中心一樣。思路如下:
點擊按鈕時,改變方向
運動時檢測方向,若向左,則x減小,向右,則增加
向右(左)運動時,人物對應(yīng)rotation也進行增加(減小)
松開手時,人物對應(yīng)rotation慢慢恢復(fù)成0;
碰撞檢測由于人物有吃東西的環(huán)節(jié)(不然這還叫什么游戲呢),因此碰撞檢測肯定是必須的啦。我們可以通過兩種方式進行碰撞檢測
人物檢測碰撞物體,需實時遍歷物體坐標列表,進行檢測
每個物體自身進行碰撞檢測,檢測自身與人物位置的對應(yīng)差
我很機智的選擇了第二個,畢竟每個物體的位置都是實時變動的,而每次碰撞檢測都進行一次循環(huán)的方法,太笨重啦。在這里我們設(shè)置碰撞檢測的區(qū)域(寬高),在物體運動時,針對人物的x,y坐標,與自身的x,y坐標加減形成的四條邊界進行比較即可,若進行碰撞,則進行對應(yīng)的操作即可,如播放音頻,得分+1等。
架構(gòu)設(shè)計思路理清楚之后,后面的路就很明朗啦。接下來我們就可以著手設(shè)計下如何實現(xiàn)這個東西了,很顯然,游戲中我們擁有許許多多的“角色”,使用“面向?qū)ο蟆钡姆绞皆俸貌贿^了。大概的劃分如下
stage //舞臺,進行基本場景渲染,游戲整體控制(開始,停止)等
player //玩兒家,也就是對應(yīng)的人物
sprite //出現(xiàn)的物體,如蛋糕等,提供玩兒家吃。 包含碰撞檢測等,會自己運動
tree //因為tree自身會運動,所以每個tree為一個類
score //進行分數(shù)控制及顯示
cfg.js //包含整體游戲配置
對象內(nèi)部劃分每個對象包含以下幾點屬性及功能:
1. 對象配置每個對象包含其內(nèi)部自身基本配置,包括位置,邊界,圖片等。直觀,便于調(diào)試
export default function People (stage) { this.cfg = { img: require("./img/people.png"), anchor: { x: 0.5, y: 0.5, }, position: { x: cfg.width / 2, y: 500 }, speed: 5, } }2. 其他方法
每個對象都包含其自身方法,如下所示:
render //進行圖片等渲染
animate //動畫function
init //一些初始化配置
實現(xiàn)通過以上思路的設(shè)計和結(jié)構(gòu)的設(shè)計,我很快的將這個游戲?qū)崿F(xiàn)了。。。沒錯,理清思路和結(jié)構(gòu)的重要性就是這樣。當然,在實現(xiàn)過程中,也有一些小的點可以記錄下:
資源加載器(圖片)為了游戲的進行效果,還是決定在加載完所有資源(尤其是圖片資源)后,才停止loading頁面。如何判斷所有內(nèi)容都加載完畢了呢?寫了個小loader
var pics = [ require("./img/bg-start.png"), require("./img/btn-start.png"), ... ]; function loadImages (pics, callback) { if(pics.length) { var img = new Image(), pic = pics.shift(); img.onload = callback; img.src = pic; loadImages(pics, callback); } else{ return; } } $(function() { loadImages(pics, function () { if (!pics.length) { $(".loading").hide(); }; }) });強制橫屏
游戲是橫屏展示的,那就強制橫屏好啦。這個當時還糾結(jié)挺久,還是自己功底不扎實腦子走私了,還在想是監(jiān)聽resize事件還是旋轉(zhuǎn)屏幕事件,都沒有這些事兒啊好嗎!直接讓它旋轉(zhuǎn)就好。
if(window.orientation==180||window.orientation==0) { $("#main").height(winW); $("#main").width(winH); $(‘#main’).css({ "transform": "rotate(90deg)", }); } else{ $(‘#main’).css("transform", "rotate(0)"); }timer控制
理清思路后,最亂的還是各種定時器啦。 為了實現(xiàn)物體隨機出現(xiàn)的效果,讓每個物體隨機多少秒后開始出現(xiàn);最后一個物體出現(xiàn)完,多少秒后出現(xiàn)結(jié)束畫面等等,需要理清楚各個定時器的關(guān)系,并對其添加語義化良好的標記,及時對未完結(jié)的定時器進行清除,防止定時器帶來的意想不到的問題。
寫在最后最終游戲的效果基本讓大家滿意啦,也是第一次嘗試這方面的開發(fā),周圍也完全沒有做過這東西的人。從開始的忐忑和一無所措,到過程中理清思路和結(jié)構(gòu),到書寫中的各種未知的坑,自己在這兩周感覺經(jīng)歷了很充實的一件事情。同時也對后續(xù)進行一些未知事物的探索和學(xué)習有了更豐富的經(jīng)驗,找對路子才是王道呀!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/50622.html
摘要:為了實現(xiàn)物體隨機出現(xiàn)的效果,讓每個物體隨機多少秒后開始出現(xiàn)最后一個物體出現(xiàn)完,多少秒后出現(xiàn)結(jié)束畫面等等,需要理清楚各個定時器的關(guān)系,并對其添加語義化良好的標記,及時對未完結(jié)的定時器進行清除,防止定時器帶來的意想不到的問題。 快到年終的時候做了一個以游戲形式展示的h5活動頁,第一次嘗試使用js寫小游戲,很有趣的過程,很寶貴的經(jīng)驗。 效果圖 直接上個效果的gif圖,游戲的一小部分效果,錄出...
摘要:直到今天,突然看到一個有意思的微信小游戲。后來試了幾次之后才發(fā)現(xiàn),這個小游戲比較刁,不僅做了微信的登錄授權(quán),而且做了手機端訪問的判斷,更甚至竟然用的還是協(xié)議的網(wǎng)頁。調(diào)用的目標發(fā)生了異常。 記一次使用Fiddler抓包工具抓取Https協(xié)議數(shù)據(jù)的踩坑過程 前言 記得從剛?cè)腴T前端第一天開始,當時的師傅就跟我介紹了一個可以抓取一些必須要在微信瀏覽器打開的鏈接的工具Fiddler,主要用來抓取...
平日學(xué)習接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進擊的 Promise Effective JavaScript leeheys blog -...
閱讀 2702·2023-04-25 14:59
閱讀 889·2021-11-22 11:59
閱讀 635·2021-11-17 09:33
閱讀 2468·2021-09-27 13:34
閱讀 3898·2021-09-09 11:55
閱讀 2321·2019-08-30 15:44
閱讀 1123·2019-08-30 14:06
閱讀 1925·2019-08-29 16:55