左右躲避障碍-神手ts版本
生活随笔
收集整理的這篇文章主要介紹了
左右躲避障碍-神手ts版本
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
TypeScript-左右躲避障礙-神手
學(xué)習(xí)typescript,第一步應(yīng)該是學(xué)習(xí)官方文檔,理解最基礎(chǔ)的語法。第二步開始用typescript實現(xiàn)一些js+css 或者canvas類型的游行。現(xiàn)在開始我們用ts寫跳一跳
?前言:
最近微信小程序里面,出現(xiàn)了一個左右手躲避障礙物的游戲:神手。玩了一下覺得很有意思,決定用typescript寫一版。
核心點:
1.識別手勢動作:雙指同時點擊,單指隨機放開
2.障礙物的成對生成。
3.動畫幀的優(yōu)化
游戲截圖
Typescript腳本:
1 //1.創(chuàng)建障礙 2 //2.移動障礙 3 //3.小球控制 4 //4.碰撞檢測 5 module game { 6 7 interface FootBall { 8 node: JQuery<HTMLElement>; 9 track: Track; 10 } 11 enum Direction { 12 left, right 13 } 14 enum Track { 15 one, two, three, four 16 } 17 let mask: JQuery<HTMLElement> = $(".game"); 18 let speed: number = 10; 19 let score: number = 0; 20 let rblist: Array<RandBox> = []; 21 let roadList: Array<Road> = []; 22 let ft1: FootBall = { node: $("#ft1"), track: Track.two }; 23 let ft2: FootBall = { node: $("#ft2"), track: Track.three }; 24 //h5的專門適應(yīng)繪制動畫的屬性 25 window.requestAnimationFrame = 26 window.requestAnimationFrame || 27 window.webkitRequestAnimationFrame || 28 (function () { 29 return function (callback: Function, element: { __lastTime: number }) { 30 var lastTime = element.__lastTime; 31 if (lastTime === undefined) { 32 lastTime = 0; 33 } 34 var currTime = Date.now(); 35 var timeToCall = Math.max(1, 33 - (currTime - lastTime)); 36 window.setTimeout(callback, timeToCall); 37 element.__lastTime = currTime + timeToCall; 38 }; 39 })(); 40 window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame; 41 let requestAnimationFrameFlag = 0; 42 class MathHelp { 43 /** 44 * 返回范圍內(nèi)隨機數(shù)[min,max] 45 * @param min 最小值 46 * @param max 最大值 47 */ 48 static RandRange(min: number, max: number): number { 49 return Math.floor(Math.random() * (max - min + 1) + min); 50 } 51 } 52 export class Road { 53 top: number = 0; 54 id: number = 0; 55 heigth: number = document.documentElement.clientHeight; 56 node: JQuery<HTMLElement> = $(''); 57 static num: number = 0; 58 constructor() { 59 this.id = Road.num; 60 this.top = -(Road.num) * this.heigth; 61 this.node = $(`<div id="${this.id}" class="road" style="top:${this.top}px;"></div>`); 62 mask.append(this.node); 63 Road.num++; 64 } 65 move() { 66 this.top += speed; 67 this.node.css({ 68 top: this.top + "px" 69 }); 70 //循環(huán)路面 71 if (this.top >= this.heigth) { 72 this.top -= Road.num * this.heigth; 73 } 74 } 75 } 76 export class RandBox { 77 78 left: number = 0; 79 top: number = -100; 80 heigth: number = 80; 81 width: number = 80; 82 node: JQuery<HTMLElement> = $(''); 83 type: Direction = Direction.left; 84 id: string = "p" + new Date().getTime(); 85 track: Track = Track.one; 86 constructor(p: number = 0) { 87 this.top = p; 88 } 89 createrb(type: Direction) { 90 this.type = type; 91 let r = 0; 92 if (type == Direction.left) { 93 r = MathHelp.RandRange(0, 1); 94 } else { 95 r = MathHelp.RandRange(2, 3); 96 } 97 this.track = r; 98 //計算所屬賽道 99 this.left = 70 + 126 * r + (126 - this.width) / 2; 100 this.node = $(`<div id="${this.id}" class='rb'style='left:${this.left}px;top:${this.top}px; background-image:url(img/c${MathHelp.RandRange(1, 4)}.png);'></div>`); 101 mask.append(this.node); 102 } 103 move() { 104 this.top += speed; 105 this.node.css({ 106 top: this.top + "px" 107 }); 108 //碰撞檢測 109 if (this.top >= 870 && this.top < 950) { 110 if (this.track == ft1.track || this.track == ft2.track) { 111 scence.gameover(); 112 return false; 113 } 114 } 115 return true; 116 } 117 } 118 119 export class scence { 120 static timer: number; 121 static Init() { 122 //重新開始 123 $(".againBtn").on("click", () => { 124 scence.restart(); 125 }); 126 //創(chuàng)建路面 127 for (let i = 0; i < 3; i++) { 128 let road = new Road(); 129 roadList.push(road); 130 } 131 //最開始給一對障礙,此后是每秒一對 132 scence.makeDoubleRb(450); 133 //開始游戲(可以綁定到開始按鈕) 134 scence.start(); 135 } 136 static start() { 137 scence.loadlisten(); 138 //場景平移 139 let move = () => { 140 let status = true; 141 $.each(rblist, (i, item) => { 142 if (!item.move()) { 143 status = false; 144 return false; 145 } 146 147 }); 148 if (status) { 149 $.each(roadList, (i, item) => { 150 item.move(); 151 }); 152 requestAnimationFrameFlag = requestAnimationFrame(move); 153 } else { 154 cancelAnimationFrame(requestAnimationFrameFlag); 155 } 156 } 157 move(); 158 //積分及創(chuàng)建障礙 159 scence.timer = setInterval(() => { 160 score++; 161 speed++; 162 $(".jfb").html(score.toString()); 163 scence.makeDoubleRb(); 164 //移除超出屏幕路障 165 rblist.forEach((item, i) => { 166 167 if (item.top > 1200) { 168 $("#" + item.id).remove(); 169 rblist.splice(i, 1); 170 } 171 }) 172 }, 1000); 173 174 } 175 static gameover() { 176 clearInterval(scence.timer); 177 $(".gameEnd").show(); 178 $(".score").html(score.toString()); 179 scence.removelisten(); 180 //小車回到原始位置 181 ft1.node.animate({ 182 left: "235px" 183 }, 50); 184 ft1.track = Track.two; 185 ft2.node.animate({ 186 left: "360px" 187 }, 50); 188 ft2.track = Track.three; 189 } 190 static restart() { 191 speed = 10; 192 score = 0; 193 $(".rb").remove(); 194 rblist = []; 195 $(".jfb").html(score.toString()); 196 $(".gameEnd").hide(); 197 scence.start(); 198 } 199 //創(chuàng)建成對出現(xiàn)的障礙 200 static makeDoubleRb(top?: number) { 201 let RB1 = new game.RandBox(top); 202 RB1.createrb(Direction.left); 203 rblist.push(RB1); 204 let RB2 = new game.RandBox(top); 205 RB2.createrb(Direction.right); 206 rblist.push(RB2); 207 } 208 private static loadlisten() { 209 document.addEventListener('touchstart', scence.touch, false); 210 document.addEventListener('touchmove', scence.touch, false); 211 document.addEventListener('touchend', scence.touch, false); 212 } 213 private static removelisten() { 214 document.removeEventListener('touchstart', scence.touch, false); 215 document.removeEventListener('touchmove', scence.touch, false); 216 document.removeEventListener('touchend', scence.touch, false); 217 } 218 private static touch(e: TouchEvent) { 219 e.preventDefault(); 220 if (e.type == "touchstart") { 221 if (e.touches.length == 1) { 222 //一指的情況 223 let x1 = e.touches[0].clientX; 224 if (x1 < 320) { 225 //左邊 226 ft1.node.animate({ 227 left: "112px" 228 }, 50); 229 ft1.track = Track.one; 230 231 } else { 232 //右邊 233 ft2.node.animate({ 234 left: "490px" 235 }, 50); 236 ft2.track = Track.four; 237 } 238 } else if (e.touches.length == 2) { 239 //兩指手指的情況 240 let x1 = e.touches[0].clientX; 241 let x2 = e.touches[1].clientX; 242 let a = x1 < 320 ? 0 : 1; 243 let b = x2 < 320 ? 0 : 1; 244 if (a + b == 0) { 245 246 //兩指都在左邊 247 ft1.node.animate({ 248 left: "112px" 249 }, 50); 250 ft1.track = Track.one; 251 252 } else if (a + b == 1) { 253 //兩指一左一右 254 ft1.node.animate({ 255 left: "112px" 256 }, 50); 257 ft1.track = Track.one; 258 ft2.node.animate({ 259 left: "490px" 260 }, 50); 261 ft2.track = Track.four; 262 } else if (a + b == 2) { 263 //兩指都在右邊 264 ft2.node.animate({ 265 left: "490px" 266 }, 50); 267 ft2.track = Track.four; 268 } 269 } 270 271 } else if (e.type == "touchend") { 272 273 if (e.touches.length == 0) { 274 //放開兩指 275 ft1.node.animate({ 276 left: "235px" 277 }, 50); 278 ft1.track = Track.two; 279 ft2.node.animate({ 280 left: "360px" 281 }, 50); 282 ft2.track = Track.three 283 } else if (e.touches.length == 1) { 284 //放開一指 285 let x1 = e.touches[0].clientX; 286 if (x1 > 320) { 287 //放開的左邊 288 ft1.node.animate({ 289 left: "235px" 290 }, 50); 291 ft1.track = Track.two; 292 } else { 293 //放開的右邊 294 ft2.node.animate({ 295 left: "360px" 296 }, 50); 297 ft2.track = Track.three 298 } 299 } 300 } 301 } 302 } 303 304 } 305 306 game.scence.Init(); View Code
html代碼
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title></title><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script><script type="text/javascript">var isios = false;! function(userAgent) {var screen_w = parseInt(window.screen.width),scale = screen_w / 640;console.log(scale);if(/Android (\d+\.\d+)/.test(userAgent)) {var version = parseFloat(RegExp.$1);document.write(version > 2.3 ? '<meta name="viewport" content="width=640, initial-scale = ' + scale + ',user-scalable=1, minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', target-densitydpi=device-dpi">' : '<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');} else {isios = true;document.write('<meta name="viewport" content="width=640, initial-scale = ' + scale + ' ,minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', user-scalable=no, target-densitydpi=device-dpi">');}}(navigator.userAgent);</script><style>html,body {margin: 0;padding: 0;height: 100%;width: 100%;overflow: hidden;}.game {height: 100%;width: 100%;background-size: 100% auto;position: relative;left: 0;top: 0;}.road{height: 100%;width: 100%;background: url(img/road.jpg) no-repeat;background-size: 100% 100%;position: absolute;left: 0;top: 0;z-index: 10;}.rb {height: 80px;width: 80px;position: absolute;left: 70px;top: 70px;background-position: left top;background-size: 100% 100%;/* animation: move 5s linear;*/z-index: 11;}.ft {height: 139px;width: 63px;/*border-radius: 25px;*/background-image: url(img/tyn.png);background-position: left top;background-size: 100% 100%;position: absolute;bottom: 50px;left: 235px;z-index: 11;}#ft1 {/*animation: football1 1.5s linear infinite;*/}#ft2 {left: 360px;/*animation: football2 1.5s linear infinite;*/}@keyframes football2 {from {transform: rotate(0deg);}to {transform: rotate(360deg);}}@keyframes football1 {from {transform: rotate(0deg);}to {transform: rotate(-360deg);}}@keyframes move {from {top: 0px;}to {top: 1300px;}}.gameEnd {position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;background-color: rgba(0, 0, 0, .8);z-index: 999;display: none;}.getScore {width: 492px;height: 760px;background: url(img/getScore.png) no-repeat;background-size: 100% auto;position: absolute;top: 0;right: 0;left: 0;bottom: 0;margin: auto;}.score {color: #dcc226;font-size: 130px;text-align: center;margin-top: 120px;font-weight: 900;}.againBtn {width: 309px;height: 87px;background: url(img/bg.png) no-repeat;background-size: 100% 100%;font-size: 40px;color: #dcc226;text-align: center;border: none;font-weight: 900;position: absolute;left: 50%;margin-left: -154.5px;}.jfb {position: absolute;top: 30px;right: 100px;font-size: 45px;font-weight: 800;color: #FFF;text-align: center;line-height: 45px;z-index: 11;}</style></head><body><div class="game"><div id="ft1" class="ft"></div><div id="ft2" class="ft"></div><div class="jfb">0</div></div><div class="gameEnd"><div class="getScore"><p class="score">10</p><button class="againBtn">再來一局</button></div></div><script src="js/game.js" type="text/javascript" charset="utf-8"></script></body></html> View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/xiaotiejiang/p/9629482.html
總結(jié)
以上是生活随笔為你收集整理的左右躲避障碍-神手ts版本的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Httpd之检测与安装
- 下一篇: JS自学笔记04