使用纯JS还原小时候游戏厅里的水果机

简介: 这份小游戏原型代码写于2018年,当时是想基于区块链做一个菠菜小游戏,后来因为种种原因没有做完。今天把这份代码拿出来分享下这类游戏的设计思路。

效果预览

动图


50559a24db2a97e49d937ab0bc5f557e.jpg


在线试玩


开发准备


pixi.min.js


一个适用于所有设备的快速轻量级2D库


sound.js


一个使用WebAudio API用代码创作音效的框架


tweenlite.js


非常著名和流行的一个补间动画库


界面搭建


绘制方形转盘界面


这里我使用一个二维数组来配置转盘,可以很方便的更改配置。代码也非常直观。


var arr=[
    [13,09,02,01,15,16,11],
    [10,00,00,00,00,00,07],
    [15,00,00,00,00,00,08],
    [17,00,00,00,00,00,18],
    [05,00,00,00,00,00,15],
    [06,00,00,00,00,00,14],
    [11,12,15,03,04,09,13]
   ];
 var tsquares=[];
 for(var i=0;i<arr.length;i++){
  for(var j=0;j<arr[i].length;j++){
   var itemKey=parseInt(arr[i][j]);
   var citem={};
   if(itemKey>0){
    citem=createItemSquare(itemKey-1);
    citem.x = 25+100*j;
    citem.y = 25+100*i;
    citem.key=itemKey-1;
    stage.addChild(citem);
   }
   tsquares.push(citem);
  }
 }


下注按钮界面


首先通过一个数组来配置所有的有效格,并且定义格子对应的奖励倍数。


var squareItemConfigs=[
      {
       name:"王",
       coin:"*120"
      },
      {
       name:"小王",
       coin:"*50"
      },
      {
       name:"77",
       coin:"*40"
      },
      {
       name:"小77",
       coin:"*3"
      },
      {
       name:"星星",
       coin:"*30"
      },
      {
       name:"小星星",
       coin:"*3"
      },
      {
       name:"西瓜",
       coin:"*20"
      },
      {
       name:"小西瓜",
       coin:"*3"
      },
      {
       name:"铃铛",
       coin:"*20"
      },
      {
       name:"小铃铛",
       coin:"*3"
      },
      {
       name:"柠檬",
       coin:"*20"
      },
      {
       name:"小柠檬",
       coin:"*3"
      },
      {
       name:"橙子",
       coin:"*10"
      },
      {
       name:"小橙子",
       coin:"*3"
      },
      {
       name:"苹果",
       coin:"*5"
      },
      {
       name:"小苹果",
       coin:"*3"
      },
      {
       name:"幸运",
       type:"lucky1"
      },
      {
       name:"小幸运",
       type:"lucky2"
      }];

定义下注按钮


var bets=[
  {
   key:"01",
   value:0
  },
  {
   key:"03",
   value:0
  },
  {
   key:"05",
   value:0
  },
  {
   key:"07",
   value:0
  },
  {
   key:"09",
   value:0
  },
  {
   key:"11",
   value:0
  },
  {
   key:"13",
   value:0
  },
  {
   key:"15",
   value:0
  }];

绘制下注按钮


for(var i=0;i<bets.length;i++){
  var betitem=createBetItem(parseInt(bets[i].key)-1,function(item){
   betIn(item.index);
  });
  betitem.index=i;
  bets[i].target=betitem;
  betitem.x=25+i*88;
  betitem.y=750;
  stage.addChild(betitem);
 }

算法

随机一个结果


我的做法是在当前位置上加上一个随机位置,然后将随机位置再加上随机的整数圈数来进行转动。

var pos=Math.round(squares.length*Math.random());
//转换为一圈内的真实位置
function getStopPosition()
  function getTPos(){
    var tpos=pos+curIndex;
    if(tpos>=squares.length){
      tpos-=squares.length;
    }
    return tpos;
  }
  var tpos=getTPos();
  //将最终的结果加上整数圈数,用于滚动计算
  return squares.length*(Math.floor(Math.random()*4)+3)+pos;
}

转动起来


function startRoll(){
 isrolling=true;
 deselectItem(curIndex);
 var count=0;
 var totalCount=getStopPosition();
 function rollloop(){
    //开始转动时由慢变快,最后停下时由快变慢,这里其实可以有更优雅的方法来实现
  var easeval=0.1;
  if(count>=totalCount-5)easeval=0.05;
  else if(count>=totalCount-10)easeval=0.1;
  else if(count>=totalCount-15)easeval=0.2;
  else if(count>=10)easeval=1;
  else if(count>=5)easeval=0.2;
  count=count+easeval;
  count=parseFloat(count.toFixed(2));
  if(isInteger(count)){
   curIndex+=1;
   if(curIndex>=squares.length){
    curIndex=0;
   }
   var item=selectItem(curIndex);
   soundplay();
   if(count>=totalCount){
        //结束滚动
    rollstop();
    calcBonus(item);
   }else{
        //做一个淡出效果
    item.fadeout();
   }
  }
 }
 function rollstop(){
    //解绑ticker重绘
  app.ticker.remove(rollloop);
  isrolling=false;
 }
  //绑定ticker重绘
 app.ticker.add(rollloop);
}

控制概率


既然是菠菜游戏,如果使用真的随机,可能会赔死。必须是在滚动开始前就已经计算好了,想让你赢你就赢,想让你输你就输。


绝对不让你赢


/*
下注者最小收益模型
如果可能中奖,则破坏本次选定值
*/
var betResult=isInBetWithKey(titem.key);
if(betResult!=false){
  console.log("本次转动将停止到:",squareItemConfigs[parseInt(titem.key)].name);
  console.log(squareItemConfigs[parseInt(titem.key)].name,"可中奖,重新改变位置");
  return getStopPosition();
}
//判断当前位置是否有奖
function isInBetWithKey(key){
  var isGetBonus=false;
  for(var i=0;i<bets.length;i++){
  var rk=parseInt(key);//当前停在的项目
  var tk=parseInt(bets[i].key)-1;//下注的目标项目
  if(bets[i].value>0){//当下注大于0时才进入判断
   if((rk==tk||rk-1==tk)){
    isGetBonus=true;
    break;
   }
  }
 }
 return isGetBonus;
}
相关文章
|
JavaScript
顶象Js的一键还原
顶象Js的一键还原
311 0
|
7月前
|
JSON JavaScript 前端开发
js将json字符串还原为json
【6月更文挑战第15天】js将json字符串还原为json
56 4
|
8月前
|
JSON JavaScript 前端开发
js将json字符串还原为json对象
【5月更文挑战第14天】js将json字符串还原为json对象
88 1
|
JavaScript
js 通过左右前序和中序, 或者后序和中序来还原二叉树
js 通过左右前序和中序, 或者后序和中序来还原二叉树
js 通过左右前序和中序, 或者后序和中序来还原二叉树
|
Web App开发 JavaScript 前端开发
|
JavaScript 容器
js混淆代码还原-js反混淆:利用js进行赋值实现
先贴一个混淆后的测试代码: eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.
1327 0
|
2月前
|
JavaScript 前端开发
JavaScript中的原型 保姆级文章一文搞懂
本文详细解析了JavaScript中的原型概念,从构造函数、原型对象、`__proto__`属性、`constructor`属性到原型链,层层递进地解释了JavaScript如何通过原型实现继承机制。适合初学者深入理解JS面向对象编程的核心原理。
36 1
JavaScript中的原型 保姆级文章一文搞懂
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
118 2
|
2月前
JS+CSS3文章内容背景黑白切换源码
JS+CSS3文章内容背景黑白切换源码是一款基于JS+CSS3制作的简单网页文章文字内容背景颜色黑白切换效果。
24 0
|
6月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
165 4