zoukankan      html  css  js  c++  java
  • 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<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  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  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 + ', 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>
    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

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

  • 相关阅读:
    Atitit.ati orm的设计and架构总结 适用于java c# php版
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.js 与c# java交互html5化的原理与总结.doc
  • 原文地址:https://www.cnblogs.com/xiaotiejiang/p/9257857.html
Copyright © 2011-2022 走看看