typescript 简版跳一跳

学习typescript,第一步应该是学习官方文档,理解最基础的语法。第二步开始用typescript实现一些js+css 或者canvas类型的游行。现在开始我们用ts写跳一跳

核心点:1.场景的随机创建

    2.旗子的跳动

    3.落脚点的判断,重点要提及的是射线判断法,参见博客

    4.场景平移

    5.游戏重置

    6.销毁场景外方块

Ts代码:

  1. //1.创建底座:
  2. //2.创建跳棋:
  3. //3.点击移动
  4. //4.开始按压动画,
  5. //5.放开动画
  6. //6.跳动
  7. //7.是否跳对
  8. //8.移动场景
  9. //9.创建新底座
  10. module Jump {
  11. interface Pos {
  12. x: number;
  13. y: number;
  14. }
  15. enum Flag {
  16. on, in, out
  17. }
  18. enum Direction {
  19. left,
  20. right
  21. }
  22. let direction: Direction = Direction.right;
  23. let diamondsList: diamonds[] = [];
  24. let mask: JQuery<HTMLElement> = $(".game-p");
  25. let chess: Chess;
  26. let score:number=0;
  27. class MathHelp {
  28. /**
  29. * 返回范围内随机数[min,max]
  30. * @param min 最小值
  31. * @param max 最大值
  32. */
  33. static RandRange(min: number, max: number): number {
  34. return Math.floor(Math.random() * (max - min + 1) + min);
  35. }
  36. /**
  37. * 根据角度求对边长度。Math.sin(randian)
  38. * @param r 斜边长
  39. * @param angle 角度
  40. */
  41. static righttriangle(r: number, angle: number): number {
  42. return Math.sin(Math.PI / 180 * angle) * r;
  43. }
  44. /**
  45. * 射线法判断点是否在多边形内部
  46. * @param p 待判断的点
  47. * @param poly 多边形顶点
  48. */
  49. static rayCasting(p: Pos, poly: Pos[]): Flag {
  50. var px = p.x,
  51. py = p.y,
  52. flag = false
  53.  
  54. for (var i = 0, l = poly.length, j = l - 1; i < l; j = i, i++) {
  55. var sx = poly[i].x,
  56. sy = poly[i].y,
  57. tx = poly[j].x,
  58. ty = poly[j].y
  59.  
  60. // 点与多边形顶点重合
  61. if ((sx === px && sy === py) || (tx === px && ty === py)) {
  62. return Flag.on;
  63. }
  64.  
  65. // 判断线段两端点是否在射线两侧
  66. if ((sy < py && ty >= py) || (sy >= py && ty < py)) {
  67. // 线段上与射线 Y 坐标相同的点的 X 坐标
  68. var x = sx + (py - sy) * (tx - sx) / (ty - sy)
  69.  
  70. // 点在多边形的边上
  71. if (x === px) {
  72. return Flag.on;
  73. }
  74.  
  75. // 射线穿过多边形的边界
  76. if (x > px) {
  77. flag = !flag
  78. }
  79. }
  80. }
  81.  
  82. // 射线穿过多边形边界的次数为奇数时点在多边形内
  83. return flag ? Flag.in : Flag.out;
  84. }
  85.  
  86. }
  87. class diamonds {
  88.  
  89. private width: number = 180;
  90. private height: number = 180;
  91. id: string = "p" + new Date().getTime();;
  92. node: JQuery<HTMLElement>;
  93. left: number = 0;
  94. top: number = 0;
  95. constructor(isauto: boolean = true, isRe = true, left: number = 0, top: number = 0) {
  96. this.left = left;
  97. this.top = top;
  98. if (isauto) {
  99.  
  100. let dl = MathHelp.RandRange(200, 300);
  101. let x = MathHelp.righttriangle(dl, 57);
  102. let y = MathHelp.righttriangle(dl, 33);
  103. let lastbox = diamondsList[diamondsList.length - 1];
  104. if (isRe) {
  105. if (direction == Direction.left) {
  106. direction = Direction.right;
  107. } else if (direction == Direction.right) {
  108. direction = Direction.left;
  109. }
  110. }
  111. if (direction == Direction.right) {
  112. this.left = lastbox.left + x;
  113. } else {
  114. this.left = lastbox.left - x;
  115. }
  116. this.top = lastbox.top - y;
  117. }
  118. this.node = $(`<div id='${this.id}' class='gb' style="top:${this.top}px;left:${this.left}px">
  119. <div class='box' style="background:url(img/c${MathHelp.RandRange(1, 4)}.png)"></div>
  120. <div class='shadw'></div>
  121. </div>`);
  122. mask.append(this.node);
  123.  
  124. }
  125. GetPointList(): Pos[] {
  126. var result = [{
  127. x: this.left,
  128. y: this.top + 57
  129. }, {
  130. x: this.left + (this.width / 2),
  131. y: this.top + 4
  132. }, {
  133. x: this.left + this.width,
  134. y: this.top + 57
  135. }, {
  136. x: this.left + (this.width / 2),
  137. y: this.top + (57 * 2 - 4)
  138. }];
  139. return result;
  140. }
  141. move(p: Pos) {
  142. this.node.css({
  143. left: p.x + "px",
  144. top: p.y + "px",
  145. transition: "",
  146. transform: ""
  147. });
  148. }
  149. }
  150. class Chess {
  151. private width: number = 180;
  152. private height: number = 182;
  153. left: number = 49;
  154. top: number = 531;
  155. node: JQuery<HTMLElement>;
  156. constructor() {
  157.  
  158. this.node =$(`<div class="chess gb"></div>`);
  159. mask.append(this.node);
  160. }
  161. jump(pt: Pos, call: Function) {
  162. let numb = 0;
  163. let t1 = setInterval(() => {
  164.  
  165. if (numb == 0) {
  166. this.node.animate({
  167. left: pt.x + "px",
  168. top: pt.y + "px"
  169. }, 504);
  170.  
  171. }
  172. this.node.css({
  173. "background-position": "-" + this.width * numb + "px" + " 0px"
  174. });
  175. numb++;
  176. if (numb >= 11) {
  177. window.clearInterval(t1);
  178. call();
  179. }
  180.  
  181. }, 42)
  182.  
  183. }
  184. GetCenter(): Pos {
  185. return {
  186. x: this.left + this.width / 2,
  187. y: this.top + this.height
  188. }
  189. }
  190. move(p: Pos) {
  191. this.node.css({
  192. left: p.x + "px",
  193. top: p.y + "px",
  194. transition: "",
  195. transform: ""
  196. });
  197. }
  198. }
  199.  
  200. class Game {
  201. static distince = 0;
  202. static time: number;
  203. /**
  204. * 初始化游戏场景
  205. */
  206. static scence() {
  207. let d1 = new diamonds(false, false, 50, 650);
  208. diamondsList.push(d1);
  209. let d = new diamonds(true, false);
  210. diamondsList.push(d);
  211. Game.loadlisten();
  212. chess = new Chess();
  213. $(".againBtn").on("click",()=>{
  214. //重置
  215. Game.GameRest();
  216.  
  217. });
  218. }
  219. /**
  220. * 重置游戏
  221. */
  222. static GameRest(){
  223. $(".gameEnd").css({
  224. "z-index":-1
  225. });
  226. diamondsList=[];
  227. score=0;
  228. $(".jfb").html(score.toString());
  229. $(".gb").remove();
  230. direction=Direction.right;
  231. Game.scence();
  232.  
  233. }
  234. static CreateSP() {
  235. let d = new diamonds();
  236. diamondsList.push(d);
  237. Game.loadlisten();
  238. }
  239. private static loadlisten() {
  240. document.addEventListener('touchstart', Game.touch, false);
  241. document.addEventListener('touchmove', Game.touch, false);
  242. document.addEventListener('touchend', Game.touch, false);
  243. }
  244. private static removelisten() {
  245. document.removeEventListener('touchstart', Game.touch, false);
  246. document.removeEventListener('touchmove', Game.touch, false);
  247. document.removeEventListener('touchend', Game.touch, false);
  248. }
  249. private static touch(e: Event) {
  250. e.preventDefault();
  251. let currentDiamonds = diamondsList[diamondsList.length - 2];
  252. if (e.type == "touchstart") {
  253. //挤压形变动画
  254. let scaley = 1;
  255. let chessy = 0;
  256. Game.distince = 0;
  257. Game.time = setInterval(() => {
  258. if (scaley > 0.7) {
  259. scaley -= 0.01;
  260. }
  261. if (chessy < 30) {
  262. chessy++;
  263. chess.node.css({
  264. "transform": " scaleX(" + (1 + chessy * 0.006) + ") scaleY(" + (1 - (chessy * 0.007)) + ")"
  265. })
  266. }
  267. Game.distince++;
  268. currentDiamonds.node.css({
  269. "transform-origin": "bottom center",
  270. "transform": "scaleY(" + scaley + ")"
  271. });
  272.  
  273. }, 50);
  274.  
  275. } else if (e.type == "touchend") {
  276. //1.底座还原动画
  277. //2.旗子动画轨迹
  278. //3.落脚点判断
  279. //4.场景平移,创建新底座,移除画外底座
  280. currentDiamonds.node.css({
  281. "transform": "scaleY(1)"
  282. });
  283. clearInterval(Game.time);
  284. Game.removelisten();
  285. Game.Jump(Game.distince);
  286.  
  287. }
  288. }
  289. private static Jump(distince: number) {
  290. let dl = distince * 17;
  291. let x = MathHelp.righttriangle(dl, 57);
  292. let y = MathHelp.righttriangle(dl, 33);
  293. if (direction == Direction.left) {
  294. x = -x;
  295. }
  296. chess.left = chess.left + x;
  297. chess.top = chess.top - y;
  298. chess.jump({ x: chess.left, y: chess.top }, () => {
  299. let p = chess.GetCenter();
  300. let last = diamondsList[diamondsList.length - 1];
  301. let poly = last.GetPointList();
  302. //判断是否跳在基座上
  303. let result = MathHelp.rayCasting(p, poly);
  304. if (result == Flag.in) {
  305. direction = Math.random() > 0.5 ? 1 : 0;
  306. Game.moveblock();
  307. score++;
  308. $(".jfb").html(score.toString());
  309. } else {
  310. //game over
  311. $(".gameEnd").css({
  312. "z-index":999
  313. });
  314. $(".score").html(score.toString());
  315. console.log("game over!");
  316. }
  317. })
  318.  
  319. }
  320. /**
  321. * 移动场景
  322. */
  323. private static moveblock() {
  324. let last = diamondsList[diamondsList.length - 1];
  325. let p1: Pos;
  326. let x: number = 0;
  327. let y: number = 0;
  328. //以左右标准基座为左边平移
  329. if (direction == Direction.left) {
  330. p1 = { x: 50, y: 650 };
  331. } else {
  332. p1 = { x: 400, y: 650 };
  333. }
  334. x = p1.x - last.left;
  335. y = p1.y - last.top;
  336.  
  337. $(".gb").css({
  338. "transform": "translate(" + x + "px," + y + "px)",
  339. "transition": "transform 0.9s"
  340. });
  341.  
  342. setTimeout(() => {
  343. //更新class中left,top属性
  344. $.each(diamondsList, (a, b) => {
  345. b.left = b.left + x;
  346. b.top = b.top + y;
  347. b.move({ x: b.left, y: b.top });
  348. });
  349. chess.left = chess.left + x;
  350. chess.top = chess.top + y;
  351. chess.move({
  352. x: chess.left,
  353. y: chess.top
  354. });
  355. Game.Destroy();
  356. //创建新底座
  357. Game.CreateSP();
  358. }, 1100)
  359. }
  360. //销毁画外的底座
  361. private static Destroy(){
  362. diamondsList.forEach((item,i,list)=>{
  363.  
  364. if(item.top>1008){
  365. diamondsList.splice(i,1);
  366. $("#"+item.id).remove();
  367. }
  368. })
  369. }
  370. }
  371. Game.scence();
  372.  
  373. }

html:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="utf-8" />
  6. <title>Typescript跳一跳</title>
  7. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
  8. <script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
  9. <link rel="stylesheet" type="text/css" href="css/ts.css" />
  10. <script type="text/javascript">
  11. var isios = false;
  12. ! function(userAgent) {
  13. var screen_w = parseInt(window.screen.width),
  14. scale = screen_w / 640;
  15. if(/Android (\d+\.\d+)/.test(userAgent)) {
  16. var version = parseFloat(RegExp.$1);
  17. 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">');
  18. } else {
  19. isios = true;
  20. document.write('<meta name="viewport" content="width=640, initial-scale = ' + scale + ' ,minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', user-scalable=no, target-densitydpi=device-dpi">');
  21. }
  22. }(navigator.userAgent);
  23. </script>
  24. </head>
  25.  
  26. <body>
  27.  
  28. <!--游戏页面-->
  29. <div class="game">
  30.  
  31. <div class="game-p">
  32. <!--<div class="chess gb"></div>
  33. <div id="one" class="gb">
  34. <div class="box"></div>
  35. <div class="shadw"></div>
  36. </div>-->
  37. </div>
  38. <img class="logo" src="img/logo.png" />
  39. <div class="jfb">0</div>
  40. <div class="toolp">距离开启宝箱还有5步</div>
  41. </div>
  42.  
  43. <div class="gameEnd">
  44.  
  45. <div class="getScore">
  46.  
  47. <p class="score">10</p>
  48. <button class="againBtn">再来一局</button>
  49.  
  50. </div>
  51.  
  52. </div>
  53.  
  54. <script src="js/myjump.js" type="text/javascript" charset="utf-8"></script>
  55. </body>
  56.  
  57. </html>

css:

  1. html,
  2. body {
  3. margin:;
  4. padding:;
  5. height: 100%;
  6. min-height: 1008px;
  7. }
  8.  
  9. .game {
  10. height: 100%;
  11. width: 100%;
  12. position: relative;
  13. left:;
  14. top:;
  15. }
  16.  
  17. .logo {
  18. position: absolute;
  19. left: 30px;
  20. top: 26px;
  21. }
  22.  
  23. .jfb {
  24. position: absolute;
  25. top: 30px;
  26. right: 60px;
  27. font-size: 100px;
  28. font-weight:;
  29. color: #4f4e3f;
  30. text-align: center;
  31. line-height: 100px;
  32. }
  33.  
  34. .toolp {
  35. position: absolute;
  36. bottom: 5%;
  37. left: 30%;
  38. width: 40%;
  39. height: 50px;
  40. border-radius: 50px;
  41. color: #FFFFFF;
  42. text-align: center;
  43. font-size: 20px;
  44. line-height: 50px;
  45. background-color: #4a764e;
  46. }
  47. .game-p {
  48. height: 100%;
  49. width: 100%;
  50. position: absolute;
  51. left:;
  52. top:;
  53. background-color: #8aad8e;
  54. }
  55. .gb{
  56. position: absolute;
  57. left: 50px;
  58. top: 650px;
  59.  
  60. }
  61. .box{
  62. height: 180px;
  63. width: 180px;
  64. background-image:url(../img/c1.png);
  65. background-size: 100% 100%;
  66. z-index:;
  67. position: absolute;
  68. }
  69. .shadw{
  70. position: absolute;
  71. left: 120px;
  72. top:;
  73. height: 133px;
  74. width: 234px;
  75. background-image: url(../img/s2.png);
  76. background-size: 100% 100%;
  77. opacity: 0.3;
  78. transform: translateY(35px) translateX(-180px);
  79. transform-origin: bottom center;
  80. }
  81. .chess{
  82. width: 182px;
  83. height: 227px;
  84. background-image: url(../img/e3.png);
  85. background-position:0 0;
  86. position: absolute;
  87. top: 531px;
  88. left: 49px;
  89. z-index:;
  90.  
  91. }
  92. .gameEnd{
  93. position: absolute;
  94. top:;
  95. left:;
  96. width: 100%;
  97. height: 100%;
  98. overflow: hidden;
  99. background-color: rgba(0,0,0,.8);
  100. z-index: -1;
  101. }
  102. .getScore{
  103. width: 492px;
  104. height: 760px;
  105. background: url(../img/getScore.png) no-repeat;
  106. background-size: 100% auto;
  107. position: absolute;
  108. top:;
  109. right:;
  110. left:;
  111. bottom:;
  112. margin: auto;
  113. }
  114. .score{
  115. color: #dcc226;
  116. font-size: 130px;
  117. text-align: center;
  118. margin-top: 120px;
  119. font-weight:;
  120.  
  121. }
  122. .againBtn{
  123. width: 309px;
  124. height: 87px;
  125. background: url(../img/bg.png) no-repeat;
  126. background-size: 100% 100%;
  127. font-size: 40px;
  128. color: #dcc226;
  129. text-align: center;
  130. border: none;
  131. font-weight:;
  132. position: absolute;
  133. left: 50%;
  134. margin-left: -154.5px;
  135. }

源码:留下邮箱,看到就发。

typescript 简版跳一跳的更多相关文章

  1. 用Kotlin破解Android版微信小游戏-跳一跳

    前言 微信又更新了,从更新日志上来看,似乎只是一次不痛不痒的小更新.不过,很快就有人发现,原来微信这次搞了个大动作——在小程序里加入了小游戏.今天也是朋友圈被刷爆的缘故. 看到网上 有人弄了一个破解版 ...

  2. 微信小程序跳一跳辅助程序(手动版)

    最近,微信官方推出了demo小程序游戏<跳一跳>,这个游戏操作简单,容易上手,却又不容易获得高分,受到很多人的喜爱(emm...这游戏有毒).自己也尝试了玩了几次,作为一个手残+脑残的资深 ...

  3. 微信跳一跳辅助Demo

    [原创] 前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗 就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个 ...

  4. AI之微信跳一跳

    需要环境:1,Python3.6 2,android手机 3,ADB驱动,下载地址https://adb.clockworkmod.com/ 步骤: 配置Python3,ADB安装目录到环境变量pat ...

  5. 用Python代码实现微信跳一跳作弊器

    最近随着微信版本的更新,在进入界面有个跳一跳的小游戏,在网上看到技术篇教你用Python来玩微信跳一跳 ( 转载自 " 工科给事中的技术博客 " ) 本文旨在总结,技术全靠大神完成 ...

  6. java语言实现简单接口工具--粗简版

    2016注定是变化的一年,忙碌.网红.项目融资失败,现在有点时间整整帖子~~ 目标: 提高工作效率与质量,能支持平台全量接口回归测试与迭代测试也要满足单一接口联调测试. 使用人员: 测试,开发 工具包 ...

  7. python练习_购物车(简版)

    python练习_购物车(简版) 需求: 写一个python购物车可以输入用户初始化金额 可以打印商品,且用户输入编号,即可购买商品 购物时计算用户余额,是否可以购买物品 退出结算时打印购物小票 以下 ...

  8. 挑战App Store,微信通过“跳一跳”秀了一下“小程序”的肌肉

    2017年即将结束的时候,微信放了一个大招.随着最新的微信v6.6.1版本更新,基于小程序的"小游戏"板块正式上线.微信上首发的这款"小游戏"叫"跳一 ...

  9. .NET开发一个微信跳一跳辅助程序

    昨天微信更新了,出现了一个小游戏"跳一跳",玩了一下 赶紧还蛮有意思的 但纯粹是拼手感的,玩了好久,终于搞了个135分拿了个第一名,没想到过一会就被朋友刷下去了,最高的也就200来 ...

随机推荐

  1. D - 湫湫系列故事——减肥记II

    虽然制定了减肥食谱,但是湫湫显然克制不住吃货的本能,根本没有按照食谱行动! 于是,结果显而易见… 但是没有什么能难倒高智商美女湫湫的,她决定另寻对策——吃没关系,咱吃进去再运动运动消耗掉不就好了? 湫 ...

  2. Java分享笔记:关于Java反射机制

    [1] 关于Java反射机制的概述 1.反射机制的概念:允许程序在执行期,借助于反射相关的API,取得任何类的内部信息,并能直接操作任意对象内部的属性和方法. 2.与反射相关的主要的API:java. ...

  3. php post提交xml文件

    <?php header("Content-type: text/xml;"); // xml code demo $xmlData = '<?xml version= ...

  4. ECSHOP和SHOPEX快递单号查询中通插件V8.6专版

    发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...

  5. uva 509 RAID!(磁盘数据)

    来自 https://blog.csdn.net/su_cicada/article/details/80085318 习题4-7 RAID技术(RAID!, ACM/ICPC World Final ...

  6. vue---day03

    1. Vue的生命周期 - 创建和销毁的时候可以做一些我们自己的事情 - beforeCreated - created - beforeMount - mounted - beforeUpdate ...

  7. JOI2017 春季合宿:Railway Trip

    自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...

  8. Xshell启动时显示丢失MSVCP110.dll解决方法

    成功安装xshell之后,在运行时却弹出“无法启动此程序,因为计算机中丢失MSVCP110.dll.尝试重新安装该程序以解决此问题”,很多人按照提示重装了还是出现同样的问题,本集教程将具体讲解如何处理 ...

  9. LeetCode题目解答

    LeetCode题目解答——Easy部分 Posted on 2014 年 11 月 3 日 by 四火 [Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复 ...

  10. Kotlin 1 函数

    #2 函数 函数声明和平时我见到的有点不太一样,使用关键字fun来声明.(感觉好欢乐的样子···O(∩_∩)O~~) 下面的示例,简单的声明了一个函数: // 这是函数声明 fun this_is_a ...