zoukankan      html  css  js  c++  java
  • 英文字母打字速度测试游戏代码

    <!DOCTYPE html>
    <html lang="en" >
    <head>
      <meta charset="UTF-8">
      <title>CodePen - Alphabet Speed Test </title>
      
      <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
     <style>
     *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    html {
      font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    }
    
    body {
      align-items: center;
      background-color: #b24592;
      background-image: linear-gradient(166deg, blueviolet, darkcyan);
      display: flex;
      justify-content: center;
      margin: 0;
      min-height: 100vh;
      padding: 0;
    }
    
    .container {
      background-color: rgba(255, 255, 255, 0.25);
      border-radius: 8px;
      box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15);
      max-width: 700px;
      padding: 2rem 3rem;
      width: 90%;
    }
    
    .game-container[data-state="pre-game"] .timer {
      opacity: 0;
    }
    .game-container[data-state="pre-game"] .restart-button, .game-container[data-state="pre-game"] .restart-button:hover, .game-container[data-state="pre-game"] .restart-button:focus {
      background-color: #fff;
      color: #333;
      opacity: .6;
    }
    
    .highscore-container {
      font-size: .9rem;
      margin: 1rem 0;
    }
    
    .timer {
      margin: 1rem 0;
      transition: opacity .1s ease-in-out;
    }
    
    .letter__container {
      display: flex;
      flex-wrap: wrap;
      margin-left: -.25rem;
      width: calc(100% + .5rem);
    }
    
    .letter {
      --background-color: rgba(255, 255, 255, .4);
      background-color: var(--background-color);
      border-radius: 3px;
      color: #333;
      display: block;
      font-size: 1.5rem;
      height: 2em;
      line-height: 2em;
      margin: .25rem;
      overflow: hidden;
      position: relative;
      text-align: center;
      text-transform: uppercase;
      width: 2em;
    }
    .letter[data-state=active]::before {
      transform: scaleX(1);
    }
    .letter::before {
      background-color: #fff;
      bottom: 0;
      content: '';
      left: 0;
      position: absolute;
      right: 0;
      top: 0;
      transform: scaleX(0);
      transform-origin: 0 center;
      transition: transform .1s ease-in-out;
    }
    .letter::after {
      content: attr(data-letter);
      position: relative;
    }
    
    .letter--template {
      display: none;
    }
    
    .restart-button__container {
      margin-top: 2rem;
      text-align: center;
    }
    
    .restart-button {
      background-color: #fff;
      border: 0;
      border-radius: 6px;
      color: #333;
      cursor: pointer;
      font-family: inherit;
      font-size: 1rem;
      padding: .5rem 2rem;
      transition: background-color .15s ease-in-out;
    }
    .restart-button:hover, .restart-button:focus {
      background-color: #f15f79;
      color: #ffffff;
    }
     </style>
    
    </head>
    <body>
    
    <div class="container">
      <div class="game-container" data-state="pre-game">
        <h1 class="title"></h1>
        <div class="highscore-container"></div>
        <div class="letter__container">
          <div class="letter letter--template" data-state="inactive"></div>
        </div>
        <div class="restart-button__container">
          <button class="restart-button" type="button">再玩一次</button>
        </div>
      </div>
    </div>
    
    <script>
    const GameState = {
      PRE_GAME: 'pre-game',
      RUNNING: 'running',
      POST_GAME: 'post-game'
    };
    
    const LetterState = {
      ACTIVE: 'active',
      INACTIVE: 'inactive'
    };
    
    class SpeedTest {  
      constructor(gameContainer, letterContainer) {
        this.letters = [];
        this.remainingLetters = [];
        this.state = GameState.PRE_GAME;
        this.timer = null;
        this.gameContainer = gameContainer;
        this.letterContainer = letterContainer;
        this.highscore = Infinity;
        this.onKeyDown = this.onKeyDown.bind(this);
        this.restartGame = this.restartGame.bind(this);
      };
    
      init(restart) {
        const availableLanguages = ['en', 'nb', 'nn', 'no'];
        const preferredLanguage = SpeedTest.getPreferredLanguage(availableLanguages);
        this.letters = SpeedTest.getLetters(preferredLanguage);
        this.remainingLetters = this.letters;
        this.highscore = this.getHighscore();
        
        if (this.highscore && this.highscore !== Infinity) {
          this.updateHighscoreText(this.highscore);
        }
    
        const letterTemplate = this.letterContainer.querySelector(
          '.letter--template'
        );
    
        this.setTitle('按键盘上的A键启动,按空格键重新启动');
        
        this.renderLetters(letterTemplate);
    
        if (!restart) {
          this.addEventListeners();
          this.getHighscore();
          
        }
      };
      static getPreferredLanguage(langs) {
        const defaultLang = 'en';
        const navgLangs = navigator.languages;
    
        const preferredLang = navgLangs.filter(lang => langs.indexOf(lang) > -1)[0];
    
        return preferredLang || defaultLang;
      };
      static getLetters(preferredLang) {
        let letters = [];
    
        switch (preferredLang) {
          case 'nb':
          case 'nn':
          case 'no':
            letters = [
              'a',
              'b',
              'c',
              'd',
              'e',
              'f',
              'g',
              'h',
              'i',
              'j',
              'k',
              'l',
              'm',
              'n',
              'o',
              'p',
              'q',
              'r',
              's',
              't',
              'u',
              'v',
              'w',
              'x',
              'y',
              'z',
              'æ',
              'ø',
              'å'
            ];
            break;
          default:
            letters = [
              'a',
              'b',
              'c',
              'd',
              'e',
              'f',
              'g',
              'h',
              'i',
              'j',
              'k',
              'l',
              'm',
              'n',
              'o',
              'p',
              'q',
              'r',
              's',
              't',
              'u',
              'v',
              'w',
              'x',
              'y',
              'z'
            ];
            break;
        }
    
        return letters;
      };
      renderLetters(template) {
        let letterElement;
    
        this.letters.forEach((letter, index) => {
          letterElement = template.cloneNode(true);
          letterElement.classList.remove('letter--template');
          letterElement.dataset.letter = letter;
          letterElement.dataset.index = index;
    
          this.letterContainer.appendChild(letterElement);
        });
    
        // this.letterContainer.removeChild(template);
      };
      addEventListeners() {
        document.addEventListener('keydown', this.onKeyDown, false);
        
        const restartButton = this.gameContainer.querySelector('.restart-button');
        restartButton.addEventListener('click', this.restartGame, false);
      };
      onKeyDown(event) {
        if (event.key === ' ') {
          
          this.restartGame();
        } else if (this.remainingLetters[0].toUpperCase() === event.key.toUpperCase()) {
          if (this.state === GameState.PRE_GAME) {
            this.startGame();
          }
          
          this.updateLetter(this.remainingLetters[0], LetterState.ACTIVE);
          this.remainingLetters = this.remainingLetters.slice(1);
    
          if (this.remainingLetters.length === 0) {
            this.stopGame();
          } else if (this.remainingLetters.length < this.letters.length / 5) {
            this.setTitle('只剩下几个了,继续!');
          } else if (this.remainingLetters.length < this.letters.length / 2) {
            this.setTitle('过半了!');
          }
        } else {
          const nextLetterElement = this.letterContainer.querySelector(
            `[data-state=${LetterState.INACTIVE}]`
          );
          this.wrongLetter(nextLetterElement);
        }
      };
      startGame() {
        this.gameContainer.dataset.state = GameState.RUNNING;
        this.state = GameState.RUNNING;
        this.setTitle('GO GO GO');
        this.startTimer();
      };
      stopGame() {
        const t2 = this.stopTimer();
        const t1 = this.timer;
        this.gameContainer.dataset.state = GameState.POST_GAME;
        this.state = GameState.POST_GAME;
    
        let time = t2 - t1;
        time /= 1000;
        const timeString = this.formatTime(time);
        
        let newTitle = `您完成了! ✨ 时间是 ${timeString} 秒!`;
      
        if (this.highscore === null || time < this.highscore) {
          newTitle += ' 新纪录!';
          this.highscore = time;
          this.updateHighscoreText(time);
          this.setHighscore(time);
        }
    
        this.setTitle(newTitle);
      };
      restartGame() {
        this.state = GameState.PRE_GAME;
        this.gameContainer.dataset.state = GameState.PRE_GAME;
    
        const letterElements = this.letterContainer.querySelectorAll('[data-letter]');
        
        for (let i = 0; i < letterElements.length; i++) {
          this.letterContainer.removeChild(letterElements[i]);
        }
        
        this.init();
        
      };
      startTimer() {
        this.timer = performance.now();
      };
      stopTimer() {
        return performance.now();
      };
      wrongLetter(element) {
        if (!('animate' in element)) {
          return;
        }
    
        const styles = getComputedStyle(element);
        const backgroundColor = styles.getPropertyValue('--background-color');
        const errorRed = '#f15f79';
    
        const blinkAnimation = [
          {
            ['--background-color']: backgroundColor
          },
          {
            ['--background-color']: errorRed
          },
          {
            ['--background-color']: backgroundColor
          }
        ];
    
        const blinkTiming = {
          duration: 100,
          iterations: 1
        };
    
        element.animate(blinkAnimation, blinkTiming);
      };
      setTitle(text) {
        const title = this.gameContainer.querySelector('.title');
        title.innerText = text;
      };
      updateLetter(letter, state) {
        const element = this.letterContainer.querySelector(
          `[data-letter=${letter}]`
        );
        element.dataset.state = state;
      };
      getHighscore() {    
        let highscore = Infinity;
        if ('localStorage' in window) {
          highscore = window.localStorage.getItem('highscore');
        }
        
        if (highscore) {
          highscore = parseFloat(highscore);
        } else {
          highscore = Infinity;
        }
        
        return highscore;
      };
      setHighscore(highscore) {
        if ('localStorage' in window) {
          window.localStorage.setItem('highscore', highscore);
        }
      };
      updateHighscoreText(newHighscore) {    
        const highscoreContainer = this.gameContainer.querySelector(
          '.highscore-container'
        );
        
        highscoreContainer.innerText = `个人最佳: ${this.formatTime(newHighscore)} 秒`;
      };
      formatTime(time) {
        return time.toLocaleString(undefined, {
          minimumFractionDigits: 2, 
          maximumFractionDigits: 2
        }); 
      }
    }
    
    const gameContainer = document.querySelector('.game-container');
    const letterContainer = document.querySelector('.letter__container');
    const game = new SpeedTest(gameContainer, letterContainer);
    game.init();
    </script>
    
    </body>
    </html>
  • 相关阅读:
    delphi 控制音量 静音的类
    delphi java 日期 转换 获取Unix时间戳
    UI颜色值
    ios10 no route to host
    VMWare MAC系统调整磁盘
    手机传文字到电脑
    Delphi JCL JEDI使用 jclDebug
    PS 使用首记 修改png图片的颜色
    delphi Style TBitmapLink
    delphi IOS 获取电池信息
  • 原文地址:https://www.cnblogs.com/xiewangfei123/p/13091010.html
Copyright © 2011-2022 走看看