• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

typescript简版跳一跳

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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 
343             setTimeout(() => {
344                 //更新class中left,top属性
345                 $.each(diamondsList, (a, b) => {
346                     b.left = b.left + x;
347                     b.top = b.top + y;
348                     b.move({ x: b.left, y: b.top });
349                 });
350                 chess.left = chess.left + x;
351                 chess.top = chess.top + y;
352                 chess.move({
353                     x: chess.left,
354                     y: chess.top
355                 });
356                 Game.Destroy();
357                 //创建新底座
358                 Game.CreateSP();
359             }, 1100)
360         }
361         //销毁画外的底座
362         private static Destroy(){
363             diamondsList.forEach((item,i,list)=>{
364 
365                 if(item.top>1008){
366                     diamondsList.splice(i,1);
367                     $("#"+item.id).remove();
368                 }
369             })
370         }
371     }
372     Game.scence();
373 
374 }
View Code

 

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 + 
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
TypeScript-类可选属性和参数属性发布时间:2022-07-18
下一篇:
TypeScript设计模式之中介者、观察者发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap