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

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

  • 相关阅读:
    android studio 各种问题
    关于Android开发中Arm、X86和Mips(草稿)
    每日更新
    Error creating bean with name 'userRepository': Invocation of init method failed;
    API 'variant.getJavaCompiler()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'
    increase the minSdkVersion to 26
    Exception thrown on Scheduler.Worker thread. Add `onError` handling
    M600 Pro 安装问题解决
    Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed.
    大疆无人机M100相关问题解决过程
  • 原文地址:https://www.cnblogs.com/xiaotiejiang/p/9257857.html
Copyright © 2011-2022 走看看