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