three编写一个微信跳一跳小游戏效果代码

代码语言:html

所属分类:游戏

代码描述:three编写一个微信跳一跳小游戏效果代码

代码标签: 微信 一跳 小游戏 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">

	<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no">

<style>
    body{
	padding: 0;
	margin: 0;
	-webkit-user-select: none;
	-moz-user-select: none;
	user-select: none;
}
.mask{
	display: none;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	position: fixed;
	width: 100%;
	height: 100%;
	background: rgba(0,0,0,0.4);
}
.content{
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	width: 500px;
	height: 500px;
	border-radius: 20px;
	background: rgba(0,0,0,0.4);
	border: 5px solid rgba(255,255,255,0.05);

}
.score-container{
	color: #ffffff;
	/* color: #232323; */
	text-align: center;
}
.title{
  font-size: 20px;
  font-weight: bold;
  /* color: rgba(255,255,255,0.6); */
}
.score{
	font-size: 100px;
	font-weight: bold;
	margin-top: 20px;
}
button.restart{
	width: 200px;
	height: 40px;
	border-radius: 20px;
	background: white;
	border: none;
  font-weight: bold;
  font-size: 20px;
  cursor: pointer;
}
button.restart:hover{
	color:#232323;
}
.info{
  margin: 20px 0;
  position: absolute;
  text-align: center;
  width:100%;
  color: rgba(255,255,255,0.2);
}
.info a{
  /* display: block; */
  font-size: 16px;
  line-height: 28px;
  color: rgba(255,255,255,0.2);
	/* color: #232323; */
  text-decoration: none;
}
a.title{
  font-size: 20px;
  font-weight: bold;
}
.score-gaming{
	margin-top: 10px;
	color: rgba(255,255,255,1);
	font-size: 16px;
}
</style>
</head>
<body>
  <div class="mask">
    <div class="content">
      <div class="score-container">
				<p class="title">本次得分</p>
				<p>历史最高: <span class="record">0</span></p>
	    	<p class="score">0</p>
	    </div>
	  	<button class="restart">
	  		重新开始
	  	</button>
    </div>
  </div>
  
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.88.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/createjs-1.3.2.js"></script>
	<script>
	
	// 通过canvas创建材质
var canvasTexture = null;

function clock()
{
	canvasTexture = document.createElement('canvas');
	canvasTexture.width=200;
	canvasTexture.height=200;
	var ctx = canvasTexture.getContext('2d');
	if(ctx){
		var timerId;
		var frameRate = 60;
		function canvObject(){
			this.x = 0;
			this.y = 0;
			this.rotation = 0;
			this.borderWidth = 2;
			this.borderColor = '#000000';
			this.fill = false;
			this.fillColor = '#ff0000';
			this.update = function(){
			if(!this.ctx)throw new Error('你没有指定ctx对象。');
			var ctx = this.ctx
			ctx.save();
			ctx.lineWidth = this.borderWidth;
			ctx.strokeStyle = this.borderColor;
			ctx.fillStyle = this.fillColor;
			ctx.translate(this.x, this.y);
			if(this.rotation)ctx.rotate(this.rotation * Math.PI/180);
			if(this.draw)this.draw(ctx);
			if(this.fill)ctx.fill();
			ctx.stroke();
			ctx.restore();
			}
		};
		function Line(){};
			Line.prototype = new canvObject();
			Line.prototype.fill = false;
			Line.prototype.start = [0,0];
			Line.prototype.end = [5,5];
			Line.prototype.draw = function(ctx){
			ctx.beginPath();
			ctx.moveTo.apply(ctx,this.start);
			ctx.lineTo.apply(ctx,this.end);
			ctx.closePath();
		};

		function Circle(){};
			Circle.prototype = new canvObject();
			Circle.prototype.draw = function(ctx){
			ctx.beginPath();
			ctx.arc(0, 0, this.radius, 0, 2 * Math.PI, true);
			ctx.closePath();
		};

		var circle = new Circle();
		circle.ctx = ctx;
		circle.x = 100;
		circle.y = 100;
		circle.radius = 90;
		circle.fill = true;
		circle.borderWidth = 6;
		circle.fillColor = '#ffffff';

		var hour = new Line();
		hour.ctx = ctx;
		hour.x = 100;
		hour.y = 100;
		hour.borderColor = "#000000";
		hour.borderWidth = 10;
		hour.rotation = 0;
		hour.start = [0,20];
		hour.end = [0,-50];

		var minute = new Line();
		minute.ctx = ctx;
		minute.x = 100;
		minute.y = 100;
		minute.borderColor = "#333333";
		minute.borderWidth = 7;
		minute.rotation = 0;
		minute.start = [0,20];
		minute.end = [0,-70];

		var seconds = new Line();
		seconds.ctx = ctx;
		seconds.x = 100;
		seconds.y = 100;
		seconds.borderColor = "#ff0000";
		seconds.borderWidth = 4;
		seconds.rotation = 0;
		seconds.start = [0,20];
		seconds.end = [0,-80];

		var center = new Circle();
		center.ctx = ctx;
		center.x = 100;
		center.y = 100;
		center.radius = 5;
		center.fill = true;
		center.borderColor = 'orange';

		for(var i=0,ls=[],cache;i<12;i++){
			cache = ls[i] = new Line();
			cache.ctx = ctx;
			cache.x = 100;
			cache.y = 100;
			cache.borderColor = "orange";
			cache.borderWidth = 2;
			cache.rotation = i * 30;
			cache.start = [0,-70];
			cache.end = [0,-80];
		}

		timerId = setInterval(function(){
			// 清除画布
			ctx.clearRect(0,0,200,200);
			// 填充背景色
			ctx.fillStyle = 'orange';
			ctx.fillRect(0,0,200,200);
			// 表盘
			circle.update();
			// 刻度
			for(var i=0;cache=ls[i++];)cache.update();
			// 时针
			hour.rotation = (new Date()).getHours() * 30;
			hour.update();
			// 分针
			minute.rotation = (new Date()).getMinutes() * 6;
			minute.update();
			// 秒针
			seconds.rotation = (new Date()).getSeconds() * 6;
			seconds.update();
			// 中心圆
			center.update();
		},(1000/frameRate)|0);
	}else{
	alert('您的浏览器不支持Canvas无法预览!"');
	}
}
clock();
	    var Game = function () {
  // 基本参数
  this.config = {
    isMobile: false,
    helper: false, // 默认关闭helper
    background: 0x282828, // 背景颜色
    ground: -1, // 地面y坐标
    fallingSpeed: 0.2, // 游戏失败掉落速度
    cubeColor: 0xbebebe,
    cubeWidth: 3, // 方块宽度
    cubeHeight: 1, // 方块高度
    cubeDeep: 3, // 方块深度
    // cubeWidth: 4, // 方块宽度
    // cubeHeight: 2, // 方块高度
    // cubeDeep: 4, // 方块深度
    jumperColor: 0x333333,
    jumperWidth: 1, // jumper宽度
    jumperHeight: 2, // jumper高度
    jumperDeep: 1, // jumper深度
  }
  // 游戏状态
  this.score = 0
  this.size = {
    width: window.innerWidth,
    height: window.innerHeight
  }
  this.scene = new THREE.Scene()
  this.cameraPos = {
    current: new THREE.Vector3(0, 0, 0), // 摄像机当前的坐标
    next: new THREE.Vector3() // 摄像机即将要移到的位置
  }
  this.camera = new THREE.OrthographicCamera(this.size.width / -80, this.size.width / 80, this.size.height / 80, this.size.height / -80, 0, 5000)
  this.renderer = new THREE.WebGLRenderer({antialias: true})

  var planceGeometry = new THREE.PlaneGeometry(this.size.width, this.size.height);    // PlaneGeometry: 翻译 平面几何    (参数: 宽60, 高20)
  var planeMaterial = new THREE.MeshLambertMaterial({ color: 0xdddddd });    // MeshLambertMaterial: 翻译 网格材质    (用来设置平面的外观, 颜色,透明度等)
  var plane = new THREE.Mesh(planceGeometry, planeMaterial);    // 把这2个对象合并到一个名为plane(平面)的Mesh(网格)对象中
  plane.receiveShadow = true;    // 平面接收阴影
  plane.rotation.x = -0.5*Math.PI;    // 绕x轴旋转90度
  plane.position.x = 0;    // 平面坐标位置
  plane.position.y = -1;
  plane.position.z = 0;
  this.plane = plane;
  this.scene.add(this.plane);    // 将平面添加到场景


  this.cubes = [] // 方块数组
  this.cubeStat = {
    nextDir: '' // 下一个方块相对于当前方块的方向: 'left' 或 'right'
  }
  this.jumperStat = {
    ready: false, // 鼠标按完没有
    xSpeed: 0, // xSpeed根据鼠标按的时间进行赋值
    ySpeed: 0  // ySpeed根据鼠标按的时间进行赋值
  }
  this.falledStat = {
    location: -1, // jumper所在的位置
    distance: 0 // jumper和最近方块的距离
  }
  this.fallingStat = {
    speed: 0.2, // 游戏失败后垂直方向上的掉落速度
    end: false // 掉到地面没有
  }
  this.combo = 0; // 连续调到中心的次数,起始为0
}
Game.prototype = {
  init: function () {
    this._checkUserAgent() // 检测是否移动端
    this._setCamera() // 设置摄像机位置
    this._setRenderer() // 设置渲染器参数
    this._setLight() // 设置光照
    this._createCube() // 加一个方块
    this._createCube() // 再加一个方块
    this._createJumper() // 加入游戏者jumper
    this._updateCamera() // 更新相机坐标

    if(this.config.helper){  // 开启helper
      this._createHelpers();
    }

    var self = this
    var mouseEvents = (self.config.isMobile) ?
    {
      down: 'touchstart',
      up: 'touchend',
    }
    :
    {
      down: 'mousedown',
      up: 'mouseup',
    }
    // 事件绑定到canvas中
    var canvas = document.querySelector('canvas')
    canvas.addEventListener(mouseEvents.down, function () {
      // console.log('mousedown');
      self._handleMousedown()
    })
    // 监听鼠标松开的事件
    canvas.addEventListener(mouseEvents.up, function (evt) {
      // console.log('mouseup');
      self._handleMouseup()
    })
    // 监听窗口变化的事件
    window.addEventListener('resize', function () {
      self._handleWindowResize()
    })
  },
  // 游戏失败重新开始的初始化配置
  restart: function () {
    this.score = 0
    this.cameraPos = {
      current: new THREE.Vector3(0, 0, 0),
      next: new THREE.Vector3()
    }
    this.fallingStat = {
      speed: 0.2,
      end: false
    }
    // 删除所有方块
    var length = this.cubes.length
    for(var i=0; i < length; i++){
      this.scene.remove(this.cubes.pop())
    }
    // 删除jumper
    this.scene.remove(this.jumper)
    // 显示的分数设为 0
    this.successCallback(this.score)
    this._createCube()
    this._createCube()
    this._createJumper()
    this._updateCamera()
  },
  // 游戏成功的执行函数, 外部传入
  addSuccessFn: function (fn) {
    this.successCallback = fn
  },
  // 游戏失败的执行函数, 外部传入
  addFailedFn: function (fn) {
    this.failedCallback = fn
  },
  // 检测是否手机端
  _checkUserAgent: function () {
    var n = navigator.userAgent;
    if (n.match(/Android/i) || n.match(/webOS/i) || n.match(/iPhone/i) || n.match(/iPad/i) || n.match(/iPod/i) || n.match(/BlackBerry/i)){
      this.config.isMobile = true
    }
  },
  // THREE.js辅助工具
  _createHelpers: function () {
    // 法向量辅助线
    var axesHelper = new THREE.AxesHelper(10)
    this.scene.add(axesHelper);

    // 平行光辅助线
    var helper = new THREE.DirectionalLightHelper(this.directionalLight, 5 );
    this.scene.add( helper );
  },
  // 窗口缩放绑定的函数
  _handleWindowResize: function () {
    this._setSize()
    this.camera.left = this.size.width / -80
    this.camera.right = this.size.width / 80
    this.camera.top = this.size.height / 80
    this.camera.bottom = this.size.height / -80
    this.camera.updateProjectionMatrix()
    this.renderer.setSize(this.size.width, this.size.height)
    this._render()
  },
  /**
   *鼠标按下或触摸开始绑定的函数
   *根据鼠标按下的时间来给 xSpeed 和 ySpeed 赋值
   *@return {Number} this.jumperStat.xSpeed 水平方向上的速度
   *@return {Number} this.jumperStat.ySpeed 垂直方向上的速度
  **/
  _handleMousedown: function () {
    var self = this

    function act() {
    // if (!self.jumperStat.ready && self.jumper.scale.y > 0.02) {
      // 以jumperBody蓄力一半为最大值
      if (!self.jumperStat.ready && self.jumperBody.scale.y > 0.02 &&  self.jumperBody.scale.y >= 0.5) {
        self.jumperBody.scale.y -= 0.01  // jumper随按压时间降低高度,即减小jumper.scale.y值
        // self.jumper.scale.y -= 0.01  // jumper随按压时间降低高度,即减小jumper.scale.y值
        self.jumperHead.position.y -= 0.02 // jumper头部跟随下降

        self.jumperStat.xSpeed += 0.004
        self.jumperStat.ySpeed += 0.008

        self.jumperStat.yTimes = (1 - self.jumperBody.scale.y) / 0.01; // 计算倍数, 用于jumper在y轴的旋转
        // console.log( self.jumperBody.scale.y, self.jumperStat.yTimes );

        self.mouseDownFrameHandler =  requestAnimationFrame(act);
      }
      self._render(self.scene, self.camera);
    }
    act();
  },
  // 鼠标松开或触摸结束绑定的函数
  _handleMouseup: function () {
    var self = this
    // 标记鼠标已经松开
    self.jumperStat.ready = true;
    cancelAnimationFrame(self.mouseDownFrameHandler);
    var frameHandler;

    function act() {
      // 判断jumper是在方块水平面之上,是的话说明需要继续运动
      // if (self.jumper.position.y >= 1) { // 此处不应该只判断jumper的位置,而是应该判断jumper的y速度
      if (self.jumperStat.ySpeed > 0 || self.jumper.position.y >= 1) {
        // jumper根据下一个方块的位置来确定水平运动方向

        var jumperRotateBase = self.jumperStat.yTimes / 2;

        if (self.cubeStat.nextDir === 'left') {
          self.jumper.position.x -= self.jumperStat.xSpeed
          // 在20倍以上的程度才有翻转效果
          // if(self.jumperStat.yTimes > 30){
          //   // 小人起跳翻转
          //   if(self.jumper.rotation.z < Math.PI*2){
          //       self.jumper.rotation.z += Math.PI / jumperRotateBase;
          //   }
          //   // 到达最高点
          //   if(self.jumperStat.ySpeed == 0){
          //     self.jumper.rotation.z = Math.PI;
          //   }
          // }

        } else {
          self.jumper.position.z -= self.jumperStat.xSpeed
          // 在20倍以上的程度才有翻转效果
          // if(self.jumperStat.yTimes > 30){
          //   // 小人起跳翻转
          //   if(self.jumper.rotation.x < Math.PI*2){
          //     self.jumper.rotation.x -= Math.PI / jumperRotateBase;
          //   }
          //   // 到达最高点
          //   if(self.jumperStat.ySpeed == 0){
          //     self.jumper.rotation.x = -Math.PI;
          //   }
          // }
        }

        // jumper在垂直方向上运动
        self.jumper.position.y += self.jumperStat.ySpeed
        // 运动伴随着缩放
        if ( self.jumperBody.scale.y < 1 ) {
          self.jumperBody.scale.y += 0.02;
          self.jumperHead.position.y += 0.02 // 头部跟随上升
        }
        // jumper在垂直方向上先上升后下降
        self.jumperStat.ySpeed -= 0.01
        // 每一次的变化,渲染器都要重新渲染,才能看到渲染效果
        self._render(self.scene, self.camera)

        frameHandler = requestAnimationFrame(act);
      }else{
        cancelAnimationFrame(frameHandler);
        landed();
      }
    }

    function landed() {

      // 用于测试combo,手动设置掉到正中心
      // self.jumper.position.x = self.cubes[self.cubes.length - 1].position.x;
      // self.jumper.position.z =  self.cubes[self.cubes.length - 1].position.z;

      // jumper掉落到方块水平位置,开始充值状态,并开始判断掉落是否成功
      self.jumperStat.ready = false
      self.jumperStat.xSpeed = 0
      self.jumperStat.ySpeed = 0
      self.jumper.position.y = .5
      // 还原jumper的旋转角度和head的位置
      self.jumper.rotation.z = 0
      self.jumper.rotation.x = 0
      self.jumperHead.position.y = 0

      self._checkInCube();

      if (self.falledStat.location === 1) {
        // 播放掉落成功音效
        if(ActMusic){
          ActMusic.play();
        }

        // 掉落成功,进入下一步
        self.score += Math.pow(2, self.combo); // 随着combo
        self._createCube()
        self._updateCamera()

        if (self.successCallback) {
          self.successCallback(self.score)
        }
      } else {
        // 掉落失败,进入失败动画
        self._falling();

        // // 播放掉落失败音效
        if(FallMusic){
          FallMusic.play();
        }
      }
    }

    act();
  },
  /**
   *游戏失败执行的碰撞效果
   *@param {String} dir 传入一个参数用于控制倒下的方向:'rightTop','rightBottom','leftTop','leftBottom','none'
  **/
  _fallingRotate: function (dir) {
    var self = this
    var offset = self.falledStat.distance - self.config.cubeWidth / 2
    var rotateAxis = 'z' // 旋转轴
    var rotateAdd = self.jumper.rotation[rotateAxis] + 0.1 // 旋转速度
    var rotateTo = self.jumper.rotation[rotateAxis] < Math.PI/2 // 旋转结束的弧度
    var fallingTo = self.config.ground + self.config.jumperWidth / 2 + offset

    if (dir === 'rightTop') {
      rotateAxis = 'x'
      rotateAdd = self.jumper.rotation[rotateAxis] - 0.1
      rotateTo = self.jumper.rotation[rotateAxis] > -Math.PI/2
      self.jumper.translate.z = offset
      // self.jumper.geometry.translate.z = offset
    } else if (dir === 'rightBottom') {
      rotateAxis = 'x'
      rotateAdd = self.jumper.rotation[rotateAxis] + 0.1
      rotateTo = self.jumper.rotation[rotateAxis] < Math.PI/2
      self.jumper.translate.z = -offset
      // self.jumper.geometry.translate.z = -offset
    } else if (dir === 'leftBottom') {
      rotateAxis = 'z'
      rotateAdd = self.jumper.rotation[rotateAxis] - 0.1
      rotateTo = self.jumper.rotation[rotateAxis] > -Math.PI/2
      self.jumper.translate.x = -offset
      // self.jumper.geometry.translate.x = -offset
    } else if (dir === 'leftTop') {
      rotateAxis = 'z'
      rotateAdd = self.jumper.rotation[rotateAxis] + 0.1
      rotateTo = self.jumper.rotation[rotateAxis] < Math.PI/2
      self.jumper.translate.x = offset
      // self.jumper.geometry.translate.x = offset
    } else if (dir === 'none') {
      rotateTo = false
      fallingTo = self.config.ground
    } else {
      throw Error('Arguments Error')
    }
    if (!self.fallingStat.end) {
      if (rotateTo) {
        self.jumper.rotation[rotateAxis] = rotateAdd
      } else if (self.jumper.position.y > fallingTo) {
        self.jumper.position.y -= self.config.fallingSpeed
      } else {
        self.fallingStat.end = true
      }
      self._render()
      requestAnimationFrame(function(.........完整代码请登录后点击上方下载按钮下载查看

网友评论0