typescript 简版跳一跳

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 = $(".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;
 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 = $(`
119
120
121
`); 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; 156 constructor() { 157 158 this.node =$(`
`); 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 ? '' + scale + ',user-scalable=1, minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', target-densitydpi=device-dpi">' : '');
18                 } else {
19                     isios = true;
20                     document.write('' + 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                 
37             div>
38             <img class="logo" src="img/logo.png" />
39             <div class="jfb">0div>
40             <div class="toolp">距离开启宝箱还有5步div>
41         div>
42 
43         <div class="gameEnd">
44 
45             <div class="getScore">
46 
47                 <p class="score">10p>
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>
View Code

css:

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

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

 

转载于:https://www.cnblogs.com/xiaotiejiang/p/9257857.html

你可能感兴趣的:(javascript,移动开发)