zoukankan      html  css  js  c++  java
  • 左右躲避障碍-神手ts版本

    TypeScript-左右躲避障碍-神手

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

     前言:

      最近微信小程序里面,出现了一个左右手躲避障碍物的游戏:神手。玩了一下觉得很有意思,决定用typescript写一版。

    核心点:

      1.识别手势动作:双指同时点击,单指随机放开

      2.障碍物的成对生成。

      3.动画帧的优化

    游戏截图

      

    Typescript脚本:

      

      1 //1.创建障碍
      2 //2.移动障碍
      3 //3.小球控制
      4 //4.碰撞检测
      5 module game {
      6 
      7     interface FootBall {
      8         node: JQuery<HTMLElement>;
      9         track: Track;
     10     }
     11     enum Direction {
     12         left, right
     13     }
     14     enum Track {
     15         one, two, three, four
     16     }
     17     let mask: JQuery<HTMLElement> = $(".game");
     18     let speed: number = 10;
     19     let score: number = 0;
     20     let rblist: Array<RandBox> = [];
     21     let roadList: Array<Road> = [];
     22     let ft1: FootBall = { node: $("#ft1"), track: Track.two };
     23     let ft2: FootBall = { node: $("#ft2"), track: Track.three };
     24     //h5的专门适应绘制动画的属性
     25     window.requestAnimationFrame =
     26         window.requestAnimationFrame ||
     27         window.webkitRequestAnimationFrame ||
     28         (function () {
     29             return function (callback: Function, element: { __lastTime: number }) {
     30                 var lastTime = element.__lastTime;
     31                 if (lastTime === undefined) {
     32                     lastTime = 0;
     33                 }
     34                 var currTime = Date.now();
     35                 var timeToCall = Math.max(1, 33 - (currTime - lastTime));
     36                 window.setTimeout(callback, timeToCall);
     37                 element.__lastTime = currTime + timeToCall;
     38             };
     39         })();
     40     window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame;
     41     let requestAnimationFrameFlag = 0;
     42     class MathHelp {
     43         /**
     44          * 返回范围内随机数[min,max]
     45          * @param min 最小值
     46          * @param max 最大值
     47          */
     48         static RandRange(min: number, max: number): number {
     49             return Math.floor(Math.random() * (max - min + 1) + min);
     50         }
     51     }
     52     export class Road {
     53         top: number = 0;
     54         id: number = 0;
     55         heigth: number = document.documentElement.clientHeight;
     56         node: JQuery<HTMLElement> = $('');
     57         static num: number = 0;
     58         constructor() {
     59             this.id = Road.num;
     60             this.top = -(Road.num) * this.heigth;
     61             this.node = $(`<div id="${this.id}" class="road" style="top:${this.top}px;"></div>`);
     62             mask.append(this.node);
     63             Road.num++;
     64         }
     65         move() {
     66             this.top += speed;
     67             this.node.css({
     68                 top: this.top + "px"
     69             });
     70             //循环路面
     71             if (this.top >= this.heigth) {
     72                 this.top -= Road.num * this.heigth;
     73             }
     74         }
     75     }
     76     export class RandBox {
     77 
     78         left: number = 0;
     79         top: number = -100;
     80         heigth: number = 80;
     81          number = 80;
     82         node: JQuery<HTMLElement> = $('');
     83         type: Direction = Direction.left;
     84         id: string = "p" + new Date().getTime();
     85         track: Track = Track.one;
     86         constructor(p: number = 0) {
     87             this.top = p;
     88         }
     89         createrb(type: Direction) {
     90             this.type = type;
     91             let r = 0;
     92             if (type == Direction.left) {
     93                 r = MathHelp.RandRange(0, 1);
     94             } else {
     95                 r = MathHelp.RandRange(2, 3);
     96             }
     97             this.track = r;
     98             //计算所属赛道
     99             this.left = 70 + 126 * r + (126 - this.width) / 2;
    100             this.node = $(`<div id="${this.id}" class='rb'style='left:${this.left}px;top:${this.top}px;    background-image:url(img/c${MathHelp.RandRange(1, 4)}.png);'></div>`);
    101             mask.append(this.node);
    102         }
    103         move() {
    104             this.top += speed;
    105             this.node.css({
    106                 top: this.top + "px"
    107             });
    108             //碰撞检测
    109             if (this.top >= 870 && this.top < 950) {
    110                 if (this.track == ft1.track || this.track == ft2.track) {
    111                     scence.gameover();
    112                     return false;
    113                 }
    114             }
    115             return true;
    116         }
    117     }
    118 
    119     export class scence {
    120         static timer: number;
    121         static Init() {
    122             //重新开始
    123             $(".againBtn").on("click", () => {
    124                 scence.restart();
    125             });
    126             //创建路面
    127             for (let i = 0; i < 3; i++) {
    128                 let road = new Road();
    129                 roadList.push(road);
    130             }
    131             //最开始给一对障碍,此后是每秒一对
    132             scence.makeDoubleRb(450);
    133             //开始游戏(可以绑定到开始按钮)
    134             scence.start();
    135         }
    136         static start() {
    137             scence.loadlisten();
    138             //场景平移
    139             let move = () => {
    140                 let status = true;
    141                 $.each(rblist, (i, item) => {
    142                     if (!item.move()) {
    143                         status = false;
    144                         return false;
    145                     }
    146 
    147                 });
    148                 if (status) {
    149                     $.each(roadList, (i, item) => {
    150                         item.move();
    151                     });
    152                     requestAnimationFrameFlag = requestAnimationFrame(move);
    153                 } else {
    154                     cancelAnimationFrame(requestAnimationFrameFlag);
    155                 }
    156             }
    157             move();
    158             //积分及创建障碍
    159             scence.timer = setInterval(() => {
    160                 score++;
    161                 speed++;
    162                 $(".jfb").html(score.toString());
    163                 scence.makeDoubleRb();
    164                 //移除超出屏幕路障
    165                 rblist.forEach((item, i) => {
    166 
    167                     if (item.top > 1200) {
    168                         $("#" + item.id).remove();
    169                         rblist.splice(i, 1);
    170                     }
    171                 })
    172             }, 1000);
    173 
    174         }
    175         static gameover() {
    176             clearInterval(scence.timer);
    177             $(".gameEnd").show();
    178             $(".score").html(score.toString());
    179             scence.removelisten();
    180             //小车回到原始位置
    181             ft1.node.animate({
    182                 left: "235px"
    183             }, 50);
    184             ft1.track = Track.two;
    185             ft2.node.animate({
    186                 left: "360px"
    187             }, 50);
    188             ft2.track = Track.three;
    189         }
    190         static restart() {
    191             speed = 10;
    192             score = 0;
    193             $(".rb").remove();
    194             rblist = [];
    195             $(".jfb").html(score.toString());
    196             $(".gameEnd").hide();
    197             scence.start();
    198         }
    199         //创建成对出现的障碍
    200         static makeDoubleRb(top?: number) {
    201             let RB1 = new game.RandBox(top);
    202             RB1.createrb(Direction.left);
    203             rblist.push(RB1);
    204             let RB2 = new game.RandBox(top);
    205             RB2.createrb(Direction.right);
    206             rblist.push(RB2);
    207         }
    208         private static loadlisten() {
    209             document.addEventListener('touchstart', scence.touch, false);
    210             document.addEventListener('touchmove', scence.touch, false);
    211             document.addEventListener('touchend', scence.touch, false);
    212         }
    213         private static removelisten() {
    214             document.removeEventListener('touchstart', scence.touch, false);
    215             document.removeEventListener('touchmove', scence.touch, false);
    216             document.removeEventListener('touchend', scence.touch, false);
    217         }
    218         private static touch(e: TouchEvent) {
    219             e.preventDefault();
    220             if (e.type == "touchstart") {
    221                 if (e.touches.length == 1) {
    222                     //一指的情况
    223                     let x1 = e.touches[0].clientX;
    224                     if (x1 < 320) {
    225                         //左边
    226                         ft1.node.animate({
    227                             left: "112px"
    228                         }, 50);
    229                         ft1.track = Track.one;
    230 
    231                     } else {
    232                         //右边
    233                         ft2.node.animate({
    234                             left: "490px"
    235                         }, 50);
    236                         ft2.track = Track.four;
    237                     }
    238                 } else if (e.touches.length == 2) {
    239                     //两指手指的情况
    240                     let x1 = e.touches[0].clientX;
    241                     let x2 = e.touches[1].clientX;
    242                     let a = x1 < 320 ? 0 : 1;
    243                     let b = x2 < 320 ? 0 : 1;
    244                     if (a + b == 0) {
    245 
    246                         //两指都在左边
    247                         ft1.node.animate({
    248                             left: "112px"
    249                         }, 50);
    250                         ft1.track = Track.one;
    251 
    252                     } else if (a + b == 1) {
    253                         //两指一左一右
    254                         ft1.node.animate({
    255                             left: "112px"
    256                         }, 50);
    257                         ft1.track = Track.one;
    258                         ft2.node.animate({
    259                             left: "490px"
    260                         }, 50);
    261                         ft2.track = Track.four;
    262                     } else if (a + b == 2) {
    263                         //两指都在右边
    264                         ft2.node.animate({
    265                             left: "490px"
    266                         }, 50);
    267                         ft2.track = Track.four;
    268                     }
    269                 }
    270 
    271             } else if (e.type == "touchend") {
    272 
    273                 if (e.touches.length == 0) {
    274                     //放开两指
    275                     ft1.node.animate({
    276                         left: "235px"
    277                     }, 50);
    278                     ft1.track = Track.two;
    279                     ft2.node.animate({
    280                         left: "360px"
    281                     }, 50);
    282                     ft2.track = Track.three
    283                 } else if (e.touches.length == 1) {
    284                     //放开一指
    285                     let x1 = e.touches[0].clientX;
    286                     if (x1 > 320) {
    287                         //放开的左边
    288                         ft1.node.animate({
    289                             left: "235px"
    290                         }, 50);
    291                         ft1.track = Track.two;
    292                     } else {
    293                         //放开的右边
    294                         ft2.node.animate({
    295                             left: "360px"
    296                         }, 50);
    297                         ft2.track = Track.three
    298                     }
    299                 }
    300             }
    301         }
    302     }
    303 
    304 }
    305 
    306 game.scence.Init();
    View Code

    html代码

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="utf-8" />
            <title></title>
            <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
            <script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
            <script type="text/javascript">
                var isios = false;
                ! function(userAgent) {
                    var screen_w = parseInt(window.screen.width),
                        scale = screen_w / 640;
                    console.log(scale);
                    if(/Android (d+.d+)/.test(userAgent)) {
                        var version = parseFloat(RegExp.$1);
                        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">');
                    } else {
                        isios = true;
                        document.write('<meta name="viewport" content="width=640, initial-scale = ' + scale + ' ,minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', user-scalable=no, target-densitydpi=device-dpi">');
                    }
                }(navigator.userAgent);
            </script>
            <style>
                html,
                body {
                    margin: 0;
                    padding: 0;
                    height: 100%;
                    width: 100%;
                    overflow: hidden;
                }
                
                .game {
                    height: 100%;
                    width: 100%;
                    background-size: 100% auto;
                    position: relative;
                    left: 0;
                    top: 0;
                }
                .road{
                    height: 100%;
                    width: 100%;
                    background: url(img/road.jpg) no-repeat;
                    background-size: 100% 100%;
                    position: absolute;
                    left: 0;
                    top: 0;
                    z-index: 10;
                    
                }
                .rb {
                    height: 80px;
                    width: 80px;
                    position: absolute;
                    left: 70px;
                    top: 70px;
                    background-position: left top;
                    background-size: 100% 100%;
                    /*    animation: move 5s linear;*/
                    z-index: 11;
                }
                
                .ft {
                    height: 139px;
                    width: 63px;
                    /*border-radius: 25px;*/
                    background-image: url(img/tyn.png);
                    background-position: left top;
                    background-size: 100% 100%;
                    position: absolute;
                    bottom: 50px;
                    left: 235px;
                    z-index: 11;
                }
                
                #ft1 {
                    /*animation: football1 1.5s linear infinite;*/
                }
                
                #ft2 {
                    left: 360px;
                    /*animation: football2 1.5s linear infinite;*/
                }
            
                
                @keyframes football2 {
                    from {
                        transform: rotate(0deg);
                    }
                    to {
                        transform: rotate(360deg);
                    }
                }
                
                @keyframes football1 {
                    from {
                        transform: rotate(0deg);
                    }
                    to {
                        transform: rotate(-360deg);
                    }
                }
                
                @keyframes move {
                    from {
                        top: 0px;
                    }
                    to {
                        top: 1300px;
                    }
                }
                
                .gameEnd {
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    overflow: hidden;
                    background-color: rgba(0, 0, 0, .8);
                    z-index: 999;
                    display: none;
                }
                
                .getScore {
                    width: 492px;
                    height: 760px;
                    background: url(img/getScore.png) no-repeat;
                    background-size: 100% auto;
                    position: absolute;
                    top: 0;
                    right: 0;
                    left: 0;
                    bottom: 0;
                    margin: auto;
                }
                
                
                .score {
                    color: #dcc226;
                    font-size: 130px;
                    text-align: center;
                    margin-top: 120px;
                    font-weight: 900;
                }
                
                .againBtn {
                    width: 309px;
                    height: 87px;
                    background: url(img/bg.png) no-repeat;
                    background-size: 100% 100%;
                    font-size: 40px;
                    color: #dcc226;
                    text-align: center;
                    border: none;
                    font-weight: 900;
                    position: absolute;
                    left: 50%;
                    margin-left: -154.5px;
                }
                
                .jfb {
                    position: absolute;
                    top: 30px;
                    right: 100px;
                    font-size: 45px;
                    font-weight: 800;
                    color: #FFF;
                    text-align: center;
                    line-height: 45px;
                    z-index: 11;
                }
            </style>
        </head>
    
        <body>
            <div class="game">
            
                <div id="ft1" class="ft"></div>
                <div id="ft2" class="ft"></div>
                <div class="jfb">0</div>
            </div>
            <div class="gameEnd">
    
                <div class="getScore">
    
                    <p class="score">10</p>
                    <button class="againBtn">再来一局</button>
    
                </div>
    
            </div>
            <script src="js/game.js" type="text/javascript" charset="utf-8"></script>
        </body>
    
    </html>
    View Code
  • 相关阅读:
    世界城堡论坛
    瑞典皇家理工学院工程实例:An Advanced Speech Codec for a Voice over IP Transmission System
    压缩域丢包补偿:Demo of Compressed Domain Packet Loss Concealment of Sinusoidally Coded Speech
    音频编解码器五大模块之:T
    瑞典皇家理工学院工程实例:Acoustic measurement system
    VOIP Codec 三剑客之 ISAC/ILBC ISAC (5) LPC Parameter Encode 模块
    通信语音音质评估:
    Frank Klemm's Musepack Page
    瑞典皇家理工学院工程实例:Sound localization
    Frank Klemm's Dither and Noise Shaping Page: Dither and Noise Shaping In MPC/MP+
  • 原文地址:https://www.cnblogs.com/xiaotiejiang/p/9629482.html
Copyright © 2011-2022 走看看