左右躲避障碍-神手ts版本
TypeScript-左右躲避障碍-神手
学习typescript,第一步应该是学习官方文档,理解最基础的语法。第二步开始用typescript实现一些js+css 或者canvas类型的游行。现在开始我们用ts写跳一跳
前言:
最近微信小程序里面,出现了一个左右手躲避障碍物的游戏:神手。玩了一下觉得很有意思,决定用typescript写一版。
核心点:
1.识别手势动作:双指同时点击,单指随机放开
2.障碍物的成对生成。
3.动画帧的优化
游戏截图
Typescript脚本:
1 //1.创建障碍 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的专门适应绘制动画的属性 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 * 返回范围内随机数[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 //循环路面 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 //创建路面 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 //积分及创建障碍 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 //创建成对出现的障碍 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
转载于:https://www.cnblogs.com/xiaotiejiang/p/9629482.html
左右躲避障碍-神手ts版本相关推荐
- android手机最低内存,原神手机端需要哪些配置 手机端最低配置要求介绍
原神是一款由米哈游自主研发的全新开放世界冒险游戏,游戏最近迎来了pc端的首次测试,而且在不久之后就会开启原神手机端的公测版本,那么手机端需要什么配置呢?小编带来了详细的介绍. 移动端预下载:9月25日 ...
- Android开发p图软件,媲美大神P图效果 Android软件抠图神手
媲美大神P图效果 Android软件抠图神手 2013年02月20日 01:50作者:杨霏霏编辑:杨霏霏文章出处:泡泡网原创 分享 泡泡网手机频道2月20日 PS的功能大家耳熟能详,其中抠图便是各位P ...
- 神马笔记 版本1.8.0——删除笔记/文件夹·技术细节篇
神马笔记 版本1.8.0--删除笔记/文件夹·技术细节篇 一.目标 二.体验地址 三.技术问题 1. 拖拽排序问题 2. indexOf问题 四.Finally 一.目标 记录开发过程中的2个技术问题 ...
- 神马笔记 版本1.4.0
神马笔记 版本1.4.0 一.新版本介绍 二.下载地址 三.下一版本功能预告 四.已经完成的功能 五.计划中的功能 六.意见反馈 1. 微信 2. 聊天宝 一.新版本介绍 新增undo/redo功能 ...
- 神马笔记 版本1.3.0
神马笔记 版本1.3.0 一.新版本介绍 二.下载地址 三.已经完成的功能 四.下一版本功能预告 五.计划中的功能 六.意见反馈 1. 微信 2. 聊天宝 一.新版本介绍 新增文件夹收藏功能 添加文件 ...
- 001-查看ts版本、安装、卸载
1.查看本机TS版本 npm view typescript version 2.查看本地是否安装 npm ls typescript 3.安装 npm i -g typescript 4.卸载 np ...
- 原神手游怎么用电脑玩 原神模拟器玩法教程
<原神>手游是一款3D全新开放世界冒险游戏.游戏发生在一个被称作「提瓦特」的幻想世界,我们将扮演一名旅行者的神秘角色,在自由的旅行中邂逅性格各异.能力独特的同伴们,和他们一起击败强敌,找回 ...
- 神马笔记 版本1.8.0——删除笔记/文件夹·代码篇
神马笔记 版本1.8.0--删除笔记/文件夹·代码篇 一.目标 二.体验地址 三.功能设计 1. 实现删除功能 2. 处理最近删除的可见性 四.实现过程 1. 删除到最近删除 2. 从最近删除恢复 3 ...
- android模拟器pc版怎么玩,原神电脑版安卓模拟器怎么使用,电脑上怎么玩原神手游...
原神电脑版对很多电脑上玩想原神手游的玩家来说应该是必须的,相对于手机上原神手游,电脑上使用手机模拟器玩原神手游,大屏幕,键鼠操控,性能更强,还可以多开挂机的优势让使用手游模拟器玩原神电脑版可以获得更好 ...
最新文章
- java的发展_java的发展
- matplotlib——交互按钮中的Home键无法使用
- java Hello World程序分析(翻译自Java Tutorials)
- Android Button 实现透明 + 圆角按钮效果
- Sun发布MySQL 5.4 响应速度提升90% ?
- 软件工程毕设(三)·进度考核表
- 三极管放大电路原理-电子技术方案
- “ 鸡声茅店月,人迹板桥霜” 道尽多少旅人的离愁别绪
- 几种并行计算模型的区别(BSP LogP PRAM)
- 硬件中控一键开关机设计方案
- 从客户端(jianjie=psasdasdfas/p)中检测到有潜在危险的 Request.Form 值
- 树莓派vsftpd 425 Failed to establish connection
- linux 格式化工具 mkfs 简介
- Abaqus2019的abaqus_v6.env在哪里
- Android Studio 连接阿里云数据库【制作基于数据库的多人远程聊天APP】
- Kafka 消息中间件
- 人力外派和猎头的区别是什么?哪个行业更赚钱?
- BT面板创建站点显示已存在问题解决
- 做好自动化运维平台需要哪些技能?
- 改善SilverLight安装体验(翻译)