做了三年前端,你才知道10分钟就能实现一个PC版魔方游戏

Posted 孙叫兽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了做了三年前端,你才知道10分钟就能实现一个PC版魔方游戏相关的知识,希望对你有一定的参考价值。

导读:最近手头有点紧,看到很多小朋友都在玩魔方,又没有money买,只能自己用javascript+css实现一个,在电脑端就能开启魔方之旅。

 

目录

项目启动演示

项目目录

​源码地址 


项目启动演示

前端使用JavaScript和纯CSS实现翻转魔方,电脑端也可以玩魔方了

项目目录

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>翻转魔方</title>
<link rel="stylesheet" type="text/css" href="styles/cube.css">
<link rel="stylesheet" type="text/css" href="styles/doodle2.css">
<link rel="stylesheet" type="text/css" href="styles/certificate2.css">

<!-- compiled & minified cube code -->
<script charset="utf-8" src="scripts/tween.r12.js"></script>
<script charset="utf-8" src="scripts/three.js"></script>
<script charset="utf-8" src="scripts/cuber.min.js"></script>

</head>
<body>
<div id="bg"></div>
<div id="container"></div>
<div id="fail">
  <img src="media/static-cube.png">
 
</div>
<div id="uipanel" class="fadeTransition" style="display:none">
  <div id="movecounter">0</div>
  <div id="buttonpanel">
	<div id="sharebubble" class="fadeTransition" style="opacity:0">
	  <input id="shareshortlink" type="text" value="google.com/doodles" readonly/>
	  <div id="sharegplus" class="bubbleicon SPRITE_google_plus_64_2x"></div>
	  <div id="sharefacebook" class="bubbleicon SPRITE_facebook_64_2x"></div>
	  <div id="sharetwitter" class="bubbleicon SPRITE_twitter_64_2x"></div>
	  <div id="shareemail" class="bubbleicon SPRITE_email_64_2x"></div>
	</div>
	<div id="uibuttons">
	  <div id="sharebutton" class="bubbleicon SPRITE_share_64_2x"></div>
	  <div id="helpbutton" class="bubbleicon SPRITE_help_64_2x"></div>
	  <div id="searchbutton" class="bubbleicon SPRITE_search_64_2x"></div>
	</div>
  </div>
  <div id="helpbubble" class="bubble" style="display:none">
	<span class="pointerup SPRITE_carrot_grey_up_2x"></span>
	<div id="helpimage" class="one"></div>
	<div id="helptext" class="helptext"></div>
	<div id="helpnext" class="helptext"></div>
	<span class="pointerdown SPRITE_carrot_down_2x"></span><br>
  </div>
</div>
<script charset="utf-8" src="scripts/iecss3d.js"></script>
<script charset="utf-8" src="scripts/ierenderer.js"></script>
<script charset="utf-8" src="scripts/deviceMotion.js"></script>
<script charset="utf-8" src="scripts/locked.js"></script>
<!-- Certificate js -->
<script charset="utf-8" src="scripts/textBox.js"></script>
<script charset="utf-8" src="scripts/ResizeableTextBox.3.js"></script>
<script charset="utf-8" src="scripts/divBox.js"></script>
<script charset="utf-8" src="scripts/frames.js"></script>
<script charset="utf-8" src="scripts/certificate.js"></script>
<script charset="utf-8" src="scripts/main3.js"></script>


</body>
</html>

cube.css

.cube {
 width:  100%;
 height: 100%;
}
.faceLabel {
 display: none;
 position: absolute;
 font-size: 60px;
 text-align: center;
 text-shadow: 0 0 24px rgba( 0, 0, 0, 0.3 );
 color: #FFF;
}
.cube .cubelet {
 width:  1em;
 height: 1em;
 position: absolute;
 box-sizing: border-box;
}
.cube /*.cubelet >*/ .face {
 position: absolute;
 width:  1em;
 height: 1em;
 background-color: #000;
 text-align: center;
 -webkit-backface-visibility: hidden;
   -moz-backface-visibility:    hidden;
   -o-backface-visibility:      hidden;
   backface-visibility:         hidden;
   padding: 0.05em;
   -moz-box-sizing: border-box;
   -webkit-box-sizing: border-box;
   -o-box-sizing: border-box;
   -ms-box-sizing: border-box;
 box-sizing: border-box;
}
.cube /*.cubelet >*/ .face.faceIntroverted { background-color: #000; }
.cube /*.cubelet >*/ .face.faceTransparent { background-color: transparent; }
.purty .face { opacity: 0.5; }
.purty .face.faceFront { background-color: #FFF; }
.purty .face.faceUp    { background-color: #E87000; }
.purty .face.faceRight { background-color: #3D81F6; }
.purty .face.faceDown  { background-color: #DC422F; }
.purty .face.faceLeft  { background-color: #009D54; }
.purty .face.faceBack  { background-color: #F5B400; }
.cube /*.cubelet > */.face > .wireframe {
 display: none;
 position: absolute;
 width:  140px;
 height: 140px;
 background-color: rgba( 255, 255, 255, 0.05 );
}
.cube .sticker {
 width:  100%;
 height: 100%;
 background-color: #F0F;
 border-radius: 0.1em;
 text-align: center;
}
.cube .sticker.red   { background: #DC422F; }
.cube .sticker.white  { background: #F3F3F3; }
.cube .sticker.blue  { background: #3D81F6;  }
.cube .sticker.green  { background: #009D54; }
.cube .sticker.orange  { background: #E87000;  }
.cube .sticker.yellow  { background: #F5B400;  }
.cube .sticker.stickerLogo {
 background: #F3F3F3 url( "../media/rubiksLogoClassic.png" );
 background-size: 100% 100%;
 background-repeat: none;
}
.cube /*.cubelet >*/ .face > .id {
 display: none;
 position: absolute;
 z-index: 1000;
 width:  90%;
 height: 90%;
 font-size:   1em;
 line-height: 0.9em;
 text-align: center;
 color: #000;
}
.cube /*.cubelet >*/ .face > .id > .underline {
 border-bottom: 1px solid #000;
}
.cube /*.cubelet > */.face.faceIntroverted > .id {
 color: #FEFEFE;
}
.cube /*.cubelet >*/ .face.faceIntroverted > .id > .underline {
 border-bottom: 1px solid #FEFEFE;
}
.cube /*.cubelet >*/ .face > .text {
 display: none;
 position: absolute;
 z-index: 2000;
 width:  100%;
 height: 100%;
 text-align: center;
 color: #FFF;
 font-size:   1em;
 line-height: 1em;
}

certificate.js

var cubeletsUnused = new ERNO.Group();
var certName, certSolved, certMovesNumber, certMovesHeader, certDate,
    certTimeNumber, certTimeHeader;
var lineLeft, lineRight;
var textBoxes = [];
var buttons = [];
var coords;
var frames = [];
var tweenSpeed = 600;
var allObjects = [];
var certificateCreated = false;
function doCertificate() {
  if (certificateCreated) {
    return;
  }
  certificateCreated = true;
  cube.mouseControlsEnabled = false;
  cube.keyboardControlsEnabled = false;
  document.getElementById('container').appendChild(cube.domElement);
  makeCertificate();
}
function animateCubeBack(callback) {
  var bg = document.getElementById('bg');
  var tweenCoords = {
    camZ: cube.camera.position.z,
    fov: cube.camera.fov,
    x: cube.position.x,
    y: cube.position.y,
    z: cube.position.z,
    xRot: cube.rotation.x,
    yRot: cube.rotation.y,
    zRot: cube.rotation.z,
    bgOpacity: 1
  }
  new TWEEN.Tween(tweenCoords).to({
    camZ: 2800,
    fov: 49,
    x: 0,
    y: 0,
    z: 0,
    xRot: (90).degreesToRadians(),
    yRot: (0).degreesToRadians(),
    zRot: (135).degreesToRadians(),
    bgOpacity: 0
  }, 1000)
  .onUpdate(function() {
        cube.camera.position.z = tweenCoords.camZ;
        cube.camera.fov = tweenCoords.fov;
        cube.position.set(tweenCoords.x, tweenCoords.y, tweenCoords.z);
        cube.rotation.set(tweenCoords.xRot, tweenCoords.yRot, tweenCoords.zRot);
        bg.style.opacity = tweenCoords.bgOpacity;
      })
  .easing(TWEEN.Easing.Quartic.InOut)
  .onComplete(function() {
        callback();
      })
  .start(cube.time);
}
function makeCertificate() {
  cube.hideInvisibleFaces = false;
  cube.showIntroverts();
  resetPositions();
  setupTextBoxes();
  setupObjects();
  setupCore();
  if(isIe)prepareFaces();
  importFramesFromJson();
  preparePlayBack();
  animateCubeBack(playFrames);
}
function resetPositions() {
  cube.cubelets.forEach(function(cubelet) {
    cubelet.css3DObject.position.copy(cubelet.position);
    cubelet.position.set(0, 0, 0);
  });
}
function setupObjects() {
  allObjects.push.apply(allObjects, cube.cubelets);
  allObjects.push.apply(allObjects, textBoxes);
}
function zeroPad(val, digits) {
  while (('' + val).length < digits) {
    val = '0' + val;
  }
  return val;
}
var dataStore = {
  'msgs': {
    'Certificate Moves': 'Moves',
    'Certificate Time': 'Time',
    'Certificate Title': 'Cube Solved',
    'Directions 1': 'Swipe outside the cube to rotate it.',
    'Directions 2': 'Swipe inside to twist the cube.',
    'Directions 3': 'Keyboard commands work too.',
    'Directions UI 1': 'Next',
    'Directions UI 2': 'Done',
    'Error Version 1': 'Oops! This doodle uses some experimental web ' +
        'technology that may not work on your device.',
    'Error Version 2': 'To play, please use a supported hardware ' +
        'configuration and the latest version of one of these browsers:',
    'Mobile Certificate Cube': 'Cube',
    'Mobile Certificate Solved': 'Solved',
    'Share Message': 'The Rubik’s Cube is 40! #CubeDoodle',
    'Share Message Completed': '#CubeDoodle solved!!',
    'Sign In Button': 'Sign in',
    'Sign In Message': 'Sign in to add your name'
  },
  'origin': '',
  'session': '',
  'dir': '',
  'hl': 'en',
  'user': '',
  'shortlink': 'google.com/doodles'
};
var parsedData = {};
var matches = window.location.hash.match(/[#&]data=([^&]*)/);
if (matches && matches.length > 1) {
  try {
    parsedData = JSON.parse(decodeURIComponent(matches[1])) || {};
  } catch (parseError) {}
}
mergeObject(parsedData, dataStore);
function mergeObject(from, to) {
  for (var key in from) {
    if (typeof from[key] == 'object') {
      mergeObject(from[key], to[key]);
    } else {
      to[key] = from[key] || to[key];
    }
  }
}
function setupTextBoxes() {
  if( isIe ){
    var ieScene        = new THREE.Object3D(),
        ieTextRenderer = new THREE.CSS3DRenderer(),
        ieCubeObject   = new THREE.Object3D(),
        ieAutoRotateObj= new THREE.Object3D(),
        container      = document.getElementById('container');
    container.appendChild( ieTextRenderer.domElement );
    ieTextRenderer.domElement.style.position = 'absolute';
    ieTextRenderer.domElement.style.top      = '0px';
    ieTextRenderer.domElement.style.left     = '0px';
    ieCubeObject.matrix      = cube.matrix;
    ieCubeObject.matrixWorld = cube.matrixWorld;
    ieCubeObject.matrixAutoUpdate = false;
    ieAutoRotateObj.matrix      = cube.autoRotateObj3D.matrix;
    ieAutoRotateObj.matrixWorld = cube.autoRotateObj3D.matrixWorld;
    ieAutoRotateObj.matrixAutoUpdate = false;
    ieCubeObject.name = 'cube'
    ieScene.add( ieAutoRotateObj );
    ieAutoRotateObj.add( ieCubeObject);
    function ieRender(){
      var containerWidth  = container.clientWidth,
          containerHeight = container.clientHeight;
      if( cube.domElement.parentNode &&
        ( ieTextRenderer.domElement.clientWidth  !== containerWidth ||
          ieTextRenderer.domElement.clientHeight !== containerHeight )){
          ieTextRenderer.setSize( containerWidth, containerHeight );
      }
      ieTextRenderer.render( ieScene, cube.camera );
      requestAnimationFrame( ieRender );
    }
    requestAnimationFrame( ieRender );
  }
  var cubeObject = isIe ? {object3D: ieCubeObject }: cube;
  if(isMobile){
    certName = new ResizeableTextBox(cubeObject, 'certName', dataStore['msgs']['Mobile Certificate Cube']);
    certSolved = new ResizeableTextBox(cubeObject, 'certSolved', dataStore['msgs']['Mobile Certificate Solved']);
  }else{
    certSolved = new ResizeableTextBox(cubeObject, 'certSolved', dataStore['user']);
    certName = new ResizeableTextBox(cubeObject, 'certName',
          dataStore['msgs']['Certificate Title']);
  }
  var moves = cube.moveCounter;
  moves = zeroPad(moves, 4);
  certMovesNumber = new TextBox(cubeObject, 'certMovesNumber', moves);
  certMovesHeader = new TextBox(cubeObject, 'certMovesHeader',
      dataStore['msgs']['Certificate Moves']);
  var now = new Date();
  var month = [
    'JANUARY',
    'FEBRUARY',
    'MARCH',
    'APRIL',
    'MAY',
    'JUNE',
    'JULY',
    'AUGUST',
    'SEPTEMBER',
    'OCTOBER',
    'NOVEMBER',
    'DECEMBER'
  ][now.getMonth()];
  var dateString = now.getFullYear() + '-' +
      zeroPad(now.getMonth(), 2) + '-' +
      zeroPad(now.getDate(), 2);
  var lang = dataStore['hl'] || en;
  if (lang == 'en') {
    dateString = month + ' ' + now.getDate() + ', ' + now.getFullYear();
  } else if (now.toLocaleDateString) {
    dateString = now.toLocaleDateString(lang);
  }
  certDate = new TextBox(cubeObject, 'certDate', dateString);
  if (navigator.userAgent.indexOf('MSIE') > -1 ||
      navigator.userAgent.indexOf('Trident') > -1) {
      certDate.domElement.style.marginTop = '-210px';
  }
  var endTime = now.getTime();
  var elapsedTime = (endTime - startTime) / 1000;
  var timeSec = zeroPad(Math.floor(elapsedTime % 60), 2);
  var timeMin = zeroPad(Math.floor(elapsedTime / 60), 2);
  certTimeNumber =
      new TextBox(cubeObject, 'certTimeNumber', timeMin + ':' + timeSec);
  certTimeHeader = new TextBox(cubeObject, 'certTimeHeader',
      dataStore['msgs']['Certificate Time']);
  certLarryName = new TextBox(cubeObject, 'certLarryName', 'Lawrence Page');
  certErnoName = new TextBox(cubeObject, 'certErnoName', 'Erno Rubik');
  googleLogo = new DivBox(cubeObject, 'googleLogo');
  larrySignature = new DivBox(cubeObject, 'larrySignature');
  ernoSignature = new DivBox(cubeObject, 'ernoSignature');
  lineLeft = new DivBox(cubeObject, 'lineLeft');
  lineRight = new DivBox(cubeObject, 'lineRight');
  textBoxes = [certName, certSolved, certMovesNumber, certMovesHeader,
    certDate, certTimeNumber, certTimeHeader, certLarryName,
    certErnoName, googleLogo, larrySignature,
    ernoSignature, lineLeft, lineRight
  ];
  textBoxes.forEach(function(textbox) {
    textbox.opacity = 0;
    textbox.css3DObject.element.style.opacity = 0;
  });
}
function setupCore() {
  var core = cube.cubelets[13];
  core.faces.forEach(function(face) {
    var logoFace = document.createElement('div');
    logoFace.classList.add('logoFace');
    face.element.appendChild(logoFace);
  });
  if (isIe) {
    var f = document.querySelectorAll(".faceDown .logoFace");
    f[0].classList.add("ie");
  }
}
function prepareFaces(){
  var f = document.querySelectorAll(".cube .face");
  for(var i=0;i<f.length;i++){
    f[i].style.webkitBackfaceVisibility = "visible";
    f[i].style.mozBackfaceVisibility = "visible";
    f[i].style.oBackfaceVisibility = "visible";
    f[i].style.backfaceVisibility = "visible";
  }
}
function preparePlayBack() {
  allObjects.forEach(function(object) {
    object.frames = [];
  });
  frames.forEach(function(frame, frameIndex) {
    frame.forEach(function(coords, objIndex) {
      var object = allObjects[coords.id];
      var tweenCoords = {
        x: coords.position.x,
        y: coords.position.y,
        z: coords.position.z,
        xr: coords.rotation.x,
        yr: coords.rotation.y,
        zr: coords.rotation.z,
        xrcss: coords.rotationCSS.x,
        yrcss: coords.rotationCSS.y,
        zrcss: coords.rotationCSS.z,
        opacity: coords.opacity
      };
      object.frames.push(tweenCoords);
    });
  });
  allObjects.forEach(function(object) {
    object.tweens = [];
    for (var i = 0; i < object.frames.length - 1; i++) {
      var frameTween = new TWEEN.Tween(object.frames[i])
      .to({
            x: object.frames[i + 1].x,
            y: object.frames[i + 1].y,
            z: object.frames[i + 1].z,
            xr: object.frames[i + 1].xr,
            yr: object.frames[i + 1].yr,
            zr: object.frames[i + 1].zr,
            xrcss: object.frames[i + 1].xrcss,
            yrcss: object.frames[i + 1].yrcss,
            zrcss: object.frames[i + 1].zrcss,
            opacity: object.frames[i + 1].opacity
          }, tweenSpeed)
      .easing(TWEEN.Easing.Quartic.Out)
      .onUpdate(function() {
            object.css3DObject.position.x = this.x;
            object.css3DObject.position.y = this.y;
            object.css3DObject.position.z = this.z;
            object.rotation.x = this.xr;
            object.rotation.y = this.yr;
            object.rotation.z = this.zr;
            object.css3DObject.rotation.x = this.xrcss;
            object.css3DObject.rotation.y = this.yrcss;
            object.css3DObject.rotation.z = this.zrcss;
            if (object.css3DObject.element) {
              object.css3DObject.element.style.opacity = this.opacity;
            } else {
              var i = 6;
              while (i-- > 0) {
                object.faces[i].element.style.opacity = this.opacity;
              }
            }
            object.opacity = this.opacity;
          });
      object.tweens.push(frameTween);
    }
    for (var i = 0; i < object.tweens.length - 1; i++) {
      object.tweens[i].chain(object.tweens[i + 1]);
    }
  });
}
function playFrames() {
  allObjects.forEach(function(object) {
    object.tweens[0].start(cube.time);
  });
}
function importFramesFromJson() {
  if (isMobile) {
    frames = certDataMobile.frames;
  } else {
    frames = certData.frames;
  }
}

源码地址 

点我下载https://download.csdn.net/download/weixin_41937552/32536942

以上是关于做了三年前端,你才知道10分钟就能实现一个PC版魔方游戏的主要内容,如果未能解决你的问题,请参考以下文章

花五分钟看这篇之前,你才发现你不懂RESTful

pc端引入微信公众号文章

做了3年前端开发,靠着这份面试题和答案,我从12K涨到了30K!

前辈的经验

Html+Css+js实现春节倒计时效果(移动端和PC端)

C51移动PC寄存器数值(通过asm实现跳转)