3月23日晚上8點半(中國隊火拼韓國的時候),做了一期直播分享。15年做的一個小游戲,把核心代碼拿出來,現場講寫了一遍,結果后面翻車了,寫錯了兩個地方,導致運行效果有點問題,直播邊說話邊寫代碼還真不一樣(可以理解為借口)。我先貼出寫錯的兩個地方。
1.
//self.last['', ''];//重置 這個是寫錯的 self.last = ["",""];//重置 這個才是正確的
2.
$sword.css({'-webkit-transfrom':'rotateX(' + this.swordRotate[this.rotateIndex] +'deg)', 'display': 'block'});//錯的,form寫成from了(以前還老說別人常常寫錯)
$sword.css({'-webkit-transform':'rotateX(' + this.swordRotate[this.rotateIndex] +'deg)', 'display': 'block'});
直播又不能暫停,當時出了問題真的沒檢查出來,一直去看邏輯有沒有錯誤,結果全是拼寫錯誤,直到直播結束我才找到問題。 也算是第一次做視頻的現場直播,看了一下回放,核心問題應該是講清楚了,只是聽我說話有點難受,語言組織的太差,頓一頓的,還有很多口水語。 如果要看直播回放的朋友前30分鍾看看就行了,后面的快進吧。 因為直播的時候好多准備好的東西,沒有准確講出來,下面先用博客來說一遍,最后附上直播地址。
需求:
做的是一個有點類似切水果的游戲,游戲的應用場景在移動設備上,交互方式就是屏幕滑動,對着一只驢一陣亂切(可以想象是水果忍者切最后的那個紅色石榴),最后計算規定時間內,切的次數,給予相應獎勵。這類游戲的目的不在於多好玩,而在於給用戶優惠的同時排隊不那么無聊,一個購物的排隊過程的一個游戲,主要是還可以根據游戲情況打折,當然根據游戲的特性,還可以用於其它環境。這類H5小游戲都比較簡單,使用的技術:jq、html、css。
實現細分:
需求已經清楚了,我們來思考下,要實現功能,我們需要做哪些工作:游戲頁面-游戲功能交互-游戲結果。
- 游戲頁面: 寫好頁面,適配(頁面不要出現滾動,剛好一屏)
- 游戲功能交互(如何切驢):驢的區域,手勢交互(切驢的算法),切中效果(刀數增加、刀光劍影),倒計時
- 游戲結果:依據切驢次數展示的最終樣式和游戲后的中獎結果,送微信卡券,結果分享......
工作量大部分都在頁面和樣式上,還有狀態的切換,核心功能是手勢交互。
核心功能:
這次分享,其它頁面都做好了,直接來寫核心代碼。就是下面這頭驢,如何實現手勢滑動,計算切驢的次數。這個可以自己先思考一下,如果是自己做的話,准備怎么去做,自己的方案自己能不能把它實現。方案我想每個人都有想法,但是最終能不能落地,能不能實現這個只有做了才知道。

我的方案就是獲取驢的一個坐標范圍,根據手勢進出驢的范圍,來判斷是否算是切一次。比如我上一次手指的位置在驢外面,這次就在里面了,那就說明我是從外到里進去了一次,就算切了一刀,如果再從里面出去,那么又算是一刀。如下圖:

紅色區域是監聽的touch事件區域,綠色的區域都代表是驢,白色代表手勢,通過手勢進去這個區域我們統計切的次數。 但是有個問題如果我直接一刀從外面到里面再到外面不反向呢?如下圖

我直播里講錯了,寫博客我才想起之前的邏輯,源碼里也確實不是上面那樣算的。 實際是我第一次手指的位置 從“外” 到 “里" 再到 "外"算是一刀;第一次手指的位置從”里“到”外“算一刀。 這樣從哪里開始似乎都並沒有重復計算。 但是要嚴格按照真實情況模擬,這樣的算法和代碼或者具體怎么算一刀的需求,還是需要再進行一次深刻的推敲。但目前的方式算出來,從感官上確實是察覺不到任何問題的,本身游戲也是無條件的給用戶優惠,這樣的算法也不會讓用戶受損,或者說大家都是公平的。
還是來說說具體代碼和實現步驟把
1. 先找到驢的范圍:
$donkey: $('.donkey'),//倔驢的dom
init: function(){
var self = this;
var $offset = self.$donkey.offset();//獲取驢的位置和寬度
self.$x = [$offset.left + $offset.width / 5, $offset.left + $offset.width - $offset.width / 5];//0左1右
self.$y = [$offset.top + $offset.height / 5, $offset.top + $offset.height - $offset.height / 5];//0上1下
return this;
}
以上定義了驢的左右上下坐標,因為驢和菜板是一張圖,加減處理的五分之一是截掉后面菜板。
2. 綁定touch事件
cut: function(){ var self = this, $region = $('.cut-region'); $region.on('touchstart', function(){ $region.on('touchmove', function(e){ e.preventDefault(); if(self.cutCount(e)){//去計算是否應該算一次,如果需要計數+1,會返回true } }); }).on('touchend', function(){ $region.off('touchmove'); }); },
3. 進出判斷計算
cutCount: function(e){//傳入的touch事件對象 var self = this;
self.last = ['', '']; var loca = e.targetTouches[0]; if(loca.clientX > self.$x[0] && loca.clientX < self.$x[1] && loca.clientY < self.$y[1] && loca.clientY > self.$y[0]){//在驢身上 if(self.last[0] == 'in') return false;//上一次同樣在里面,不執行 if(self.last[0] == 'out' && self.last[1] == 'in'){//上一次在外面 return true; }else{ self.last[1] = self.last[0]; self.last[0] = 'in'; return false; } }else{//就在外面 if(self.last[0] == 'out') return false;//上一次在同樣外面,不執行 if(self.last[0] == 'in' && self.last[1] == 'out'){ return true; }else{ self.last[1] = self.last[0]; self.last[0] = 'out'; return false; } } },
last紀錄了上一次和上上次手指的位置,這樣紀錄我們后面才能判斷正確。
剩下的就是去打磨交互效果了,這里就不多說了,可以直接看下源碼或者直播回放。
小游戲的思考:
我做過那么些個小游戲,基本都是自己想方案再寫出來實現的,拿到需求的時候需要拆分和評估,先把游戲核心難點找出來單獨實現了才行,否則先做其它事情沒有意義。 游戲本質是通過視覺、觸覺、聽覺和本能意識產生與現實相近的體驗,利用這幾個感官的特性,給人造成逼真的體驗,比如視覺上的錯位、相對移動,聽覺上物體的聲音、遠近聲音大小等等。 對於一些要求並不高的小游戲,我們可以做一些模擬上的舍棄,要實現一個現實模擬,有些時候可能會非常復雜,如果做不到百分百准確,至少先做出一個讓人使用起來感覺到基本上是這個東西的版本。 當然如果自己願意鑽研也是好事,不要影響開發進度就好。 如果有一天誰遇到這類的需求,發現這個事情很難做,就要先想辦法簡化,達到最低要求,再慢慢去優化,不會拆分會給人心理造成負擔,容易被一拳頭撐死。 如果是做h5小游戲的話,一定要強調html和css,先寫好這兩個東西,再去使用JS,因為如果html和css不寫好,不充分利用其最大優勢的話,用js去填補是會消耗很大精力的,會讓代碼維護和可讀性變得復雜,比如說一些輪播圖的實現,自己寫過的人可能會有所體會。
以下是直播地址 和 github上的源碼,有興趣的看看吧,給個start也好~
直播回放地址https://www.mayigeek.com/mayi-edu-web/user/html/liveShare.html?id=8
看不了的話,復制鏈接在微信打開吧!
