接物游戏demo

news2024/11/7 22:45:08

接物游戏demo:

接物元素设置了不同分值

指定时间内,接到元素则加分,接到炸弹则减分,计时结束,游戏停止

 demo代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=750, user-scalable=no">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="apple-mobile-web-app-title" content="">
<title>接物demo</title>
<style>
  @charset "utf-8";
  *{ margin:0px; padding:0px; box-sizing:border-box; -webkit-tap-highlight-color:rgba(0,0,0,0); tap-highlight-color:rgba(0,0,0,0); cursor:pointer;}
  html{ max-width:750px; margin:0 auto;}
  body{ font-family:"PingFangSC-Regular","STHeitiSC-Light","微软雅黑","Microsoft YaHei","sans-serif"; font-size:28px; line-height:1.6; color:#333;
      -webkit-user-select:none; user-select:none;
      -webkit-touch-callout:none; touch-callout:none;
  }
  li{ list-style:none;}
  i{ font-style:normal;}
  
  [v-cloak]{ display: none;}
  
  html, body{ height:100%; background-color: #fff; position:relative; overflow: hidden;}
  .page{ width:100%; height:100%; position:absolute; left:0; top:0; overflow: hidden;}
  .page.game{ background-color: skyblue; overflow-y: auto; -webkit-overflow-scrolling: touch;}
  .game_body{}
  
  .show_time{ width: 100%; padding: 20px; text-align: center; position: absolute; left: 0; top: 0;}
  .show_time span{ margin: 0 10px;}
  .show_time span i{ margin: 0 5px; color: palevioletred; font-size: 32px; font-weight: bold;}
  
  #imgShowList{ width: 100%; height: 100vh; position: relative; overflow: hidden;}
  
  .basket{ width: 100%; position: fixed; left: 0; top: 1100px;}
  #gameBtn{ width: 200px; height: 80px; position: absolute; left: 0; top: 0;}
  
  .game_start_btn{ padding: 0 15px; height: 60px; line-height: 60px; border-radius: 30px 0 0 30px; background-color: pink; position: absolute; right: 0; top: 60vh;}
</style>
</head>

<body>

<section id="app" v-cloak>
  
  <div class="page game">
    <div class="game_body">
      <!-- 坠落图片展示区 -->
      <div id="imgShowList">
        <!-- <img v-if="item.imgY < gameBtnTop" v-for="item in gameImgList" :style="'width:' + item.imgW + 'px;left:' + item.imgX + 'px;'" :src="item.img" /> -->
        <img-down v-on:set_score="addScore" :countdown_time="countdownTime" :game_btn_height="gameBtnHeight" :game_btn_width="gameBtnWidth" :game_btn_top="gameBtnTop" :game_btn_left="gameLeftNum" :down_img="item" v-for="item in gameImgList"></img-down>
      </div>
      
      <!-- 接物篮子 -->
      <div class="basket">
        <img id="gameBtn" src="btn.png" >
      </div>
      
      <div v-if="!inGame" @click="gameStart" class="game_start_btn">开始游戏</div>
      
      <div class="show_time"><span>剩余<i>{{countdownTime}}</i>s</span> | <span>得分<i>{{currScore}}</i></span></div>
    </div>
  </div>
  
</section>


<template id="imgDownTemp">
  <div v-if="showTemp" :style="'text-align: center;position:absolute;width:' + down_img.imgW + 'px;left:' + down_img.imgX + 'px;top:' + imgY + 'px'">
    <p v-if="showScore" style="width: 100%;position: absolute;left: 0;bottom: -100%;">{{down_img.score > 0 ? '+' + down_img.score : down_img.score}}</p>
    <img v-else :src="down_img.img" style="width: 100%;position: absolute;left: 0;bottom: -100%;" />
  </div>
</template>


<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js"></script>
<script type="text/javascript">
  var soundYes = new Howl({
    src: ['game/yes.mp3']
  });
  var soundNo = new Howl({
    src: ['game/no.mp3']
  });
</script>

<script type="text/javascript">
Vue.component('img-down', {
  data: function () {
    return {
      showTemp:true, // 坠落图片Y轴超过区域时不再显示
      imgY:0, // 坠落图片Y轴
      showScore:false, // 坠落图片被“接住”时,展示加分或减分分值
      setpNum:1, // 坠落图片Y轴偏移量
      timer:null,
      timeStep:null, // 定时器执行时长(毫秒)
      // 定时器执行时长(坠落速度快、中、慢)(毫秒)
      timeStepData:{
        timeFast:5,
        timeslow:8,
        timeslowest:10,
      }
    }
  },
  props:['countdown_time','game_btn_height','game_btn_width','game_btn_top','game_btn_left','down_img'],
  template: '#imgDownTemp',
  mounted() {
    // 坠落图片Y轴偏移量根据随机数值设置,以此影响不同的坠落速度效果
    if(Math.random()*10 > 5){
      this.setpNum = 2;
    }
    // 计时到20秒、10秒时,坠落速度不同程度加快
    if(this.countdown_time <= 10){
      this.timeStep = this.timeStepData['timeFast'];
    }else if(this.countdown_time <= 20){
      this.timeStep = this.timeStepData['timeslow'];
    }else{
      if(this.setpNum == 1){
        this.timeStep = this.timeStepData['timeslow'];
      }else{
        this.timeStep = this.timeStepData['timeslowest'];
      }
    }
    this.timer = setInterval(this.imgShowDown,this.timeStep);
  },
  methods:{
    imgShowDown(){
      // 计时结束-游戏结束
      if(this.countdown_time <= 0){
        clearInterval(this.timer);
      }
      this.imgY+=this.setpNum;
      // 坠落图片到达接物篮子Y轴位置
      if(this.imgY > this.game_btn_top){
        // clearInterval(this.timer);
        // 接到了
        if((this.down_img.imgX + this.down_img.imgW) > this.game_btn_left && this.down_img.imgX < (this.game_btn_width + this.game_btn_left)){
          this.$emit('set_score',this.down_img.score);
          this.showScore = true;
          clearInterval(this.timer);
          setTimeout(()=>{
            this.showTemp = false;
          },100)
          if(this.down_img.score > 0){
            soundYes.play();
          }else{
            soundNo.play();
          }
        }else{
          // this.showTemp = false;
        }
      }
      //
      if(this.imgY > (this.game_btn_top + this.game_btn_height)){
        clearInterval(this.timer);
        this.showTemp = false;
      }
    }
    
  }
})

document.oncontextmenu = function(e){
  e.preventDefault();
}

var VM = new Vue({
  el:"#app",
  data:{
    winW:0, // 页面宽度
    gameBtn:'', // 接物篮子
    gameBtnHeight:0, // 接物篮子高度
    gameBtnWidth:0, // 接物篮子宽度
    gameBtnWidthHalf:0, // 接物篮子宽度一半
    gameBtnMaxLeft:0, // 接物篮子最大left值
    gameBtnTop:0, // 接物篮子对顶部距离
    gameLeftNum:0, // 接物篮子left值
    
    inGame:false, // 是否游戏进行中
    currScore:0, // 当前得分
    
    countdownTiming:0,
    countdownTimeDefault:30, // 初始化倒计时时间(秒)
    countdownTime:0,
    
    gameImgW:60, // 坠落图片宽
    gameImgMaxLeft:0, // 坠落图片的最大left值
    gameImgList:[], // 坠落图片-最终展示的列表数据
    // 坠落图片-原始配置数据(图片及对应分值),游戏时从中随机取一个追加至gameImgList中
    gameImgData:[
      {
        img:'game/1.png',
        score:1,
      },
      {
        img:'game/2.png',
        score:2,
      },
      {
        img:'game/3.png',
        score:3,
      },
      {
        img:'game/4.png',
        score:4,
      },
      {
        img:'game/5.png',
        score:5,
      },
      {
        img:'game/6.png',
        score:-5,
      },
      {
        img:'game/6.png',
        score:-5,
      },
    ],
  },
  created() {
  },
  mounted() {
    this.initParameter();
  },
  watch: {
  },
  methods:{
    // 游戏参数初始化数据
    initParameter(){
      this.winW = document.documentElement.offsetWidth || document.body.offsetWidth;
      this.gameBtn = document.getElementById('gameBtn');
      this.gameBtnHeight = this.gameBtn.offsetHeight;
      this.gameBtnWidth = this.gameBtn.offsetWidth;
      this.gameBtnWidthHalf = this.gameBtnWidth / 2;
      this.gameBtnMaxLeft = this.winW - this.gameBtnWidthHalf * 2;
      this.gameBtnTop = document.getElementsByClassName('basket')[0].offsetTop;
      
      this.gameImgMaxLeft = this.winW - this.gameImgW;
      
      this.gameBtn.style.left = (this.winW / 2 - this.gameBtnWidthHalf) + 'px';
    },
    // 拖动接物篮子
    touchmove(e){
      e.preventDefault();
      this.gameLeftNum = e.touches[0].pageX - this.gameBtnWidthHalf;
      this.gameLeftNum = this.gameLeftNum < 0 ? 0 : this.gameLeftNum > this.gameBtnMaxLeft ? this.gameBtnMaxLeft : Math.floor(this.gameLeftNum);
      this.gameBtn.style.left = this.gameLeftNum + 'px';
      // console.log(this.gameLeftNum , this.gameBtn.offsetLeft)
    },
    // 开始游戏,计时等设置
    startGame(){
      this.inGame = true;
      this.currScore = 0;
      this.currScoreData = [];
      
      this.gameImgList = [];
      
      this.gameBtn.addEventListener('touchmove',this.touchmove,false);
      this.gameBtn.style.left = (this.winW / 2 - this.gameBtnWidthHalf) + 'px';
      
      this.countdownTiming = 0;
      this.countdownTime = this.countdownTimeDefault;
      this.changeTime();
    },
    // 计时
    // timing , rafId;
    changeTime(k){
      // console.log(k);
      if(!this.timing && k){
        this.timing = k
      }
      // 1秒执行60次
      this.rafId = requestAnimationFrame(this.changeTime);
      // 倒计时计算
      this.countdownTiming++;
      // 1秒(1000ms)执行一次
      if(this.countdownTiming % 60 == 0){
        this.countdownTime-= 1;
      }
      if(this.countdownTime <= 0){
        this.gameEnd();
        cancelAnimationFrame(this.rafId);
      }
      // 动态添加坠落图片(时间越短,添加的坠落图片越多)
      if(this.countdownTiming % 40 == 0){
        this.setImgToPage();
      }
    },
    // 动态添加坠落图片
    setImgToPage(){
      let randomKey = Math.floor(Math.random() * this.gameImgData.length);
      let imgX = Math.floor(Math.random() * this.gameImgMaxLeft);
      this.gameImgList.push({imgX,imgY:0,imgW:this.gameImgW,...this.gameImgData[randomKey]})
    },
    // 加分减分统计
    addScore(score){
      this.currScore += score;
      this.currScoreData.push(score);
    },
    
    ///
    
    // 开始游戏
    gameStart(){
      this.startGame();
    },
    // 计时结束-游戏结束
    gameEnd(){
      console.log(this.currScoreData);
      this.inGame = false;
      this.gameBtn.removeEventListener('touchmove',this.touchmove,false);
    },
    
  }
})
</script>


</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言帮忙写代码之微信小程序图片移动顺序

先上效果图&#xff0c;图片顺序可移动&#xff0c;左移右移调准顺序。 代码是文心一言帮忙写的&#xff0c;自己稍微改造就可以用了。 首先是往左移&#xff0c;也就是从下标1移到下标0 &#xff0c;下标2移到下标1 var imglist [‘aa’, ‘bb’, ‘cc’, ‘dd’]; function…

智能电表上的模块发热正常吗?

智能电表是一种可以远程抄表、计费、控制和管理的电力计量设备&#xff0c;它可以实现智能化、信息化和网络化的电力用电管理。智能电表的主要组成部分包括电能计量模块、通信模块、控制模块和显示模块等。其中&#xff0c;通信模块和控制模块是智能电表的核心部件&#xff0c;…

C++11——多线程

目录 一.thread类的简单介绍 二.线程函数参数 三.原子性操作库(atomic) 四.lock_guard与unique_lock 1.lock_guard 2.unique_lock 五.条件变量 一.thread类的简单介绍 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如windows和linu…

如何使用 NFTScan 的 TON API 实现 NFT 应用开发?

上周 NFTScan 开发者平台已上线了 TON 网络的 NFT API 服务&#xff0c;TON&#xff08;The Open Network&#xff09;是由 Telegram 团队打造的一条 Layer 1 高性能公链&#xff0c;采用自己的 TVM 虚拟机&#xff0c;与 EVM 不兼容。通过先进的技术架构实现每秒百万级 TPS 的…

为什么需要 SOME/IP

传统汽车协议的问题 如今的汽车不仅仅是通勤和交通工具&#xff0c;车辆现在设计得功能齐全&#xff0c;使旅程成为一种豪华体验。所有这些都是通过将先进的电子技术与车辆的发动机控制单元&#xff08;ECU&#xff09;集成而实现的。这种新的情景显著改变了ECU的不同单元之间…

生成扩散模型理论框架

1、随机微分方程&#xff08;Stochastic Differential Equation&#xff0c;SDE&#xff09; DDPM的一般化形式 2、常微分方程&#xff08;Ordinary differential equation&#xff0c;ODE&#xff09; DDIM的一般化形式 3、得分匹配&#xff08;Score matching&#xff09; …

如何快速高效的掌握一门新技术

目录 前言1 确定合适的学习目标1.1 SMART目标1.2 不同类型的学习目标 2 建立知识体系3 学习金字塔&#xff1a;教授他人3.1 深化理解3.2 记忆巩固3.3 自信提升3.4 知识共享 4 刻意练习4.1 构建个人项目4.2 参与实际项目4.3 参与开源项目4.4 解决复杂问题 结论 前言 学习一门新…

cAdvisor监控Docker容器做性能测试

cAdvisor监控Docker容器做性能测试 缘起 当前有个服务做技术选型&#xff0c;服务要求比较高的性能&#xff0c;要做性能测试。部署的环境是容器话部署&#xff0c;但申请新的容器流程较长&#xff0c;于是我打算在流程走完之前简单评估下性能&#xff0c;来确定技术选型是否…

微信聚合聊天系统的便捷功能:自动回复

当下&#xff0c;微信已然成为我们在工作中必不可少的沟通工具。但由于微信平台尚未开放自动回复、快捷回复等便捷功能&#xff0c;在通过平台展开工作时&#xff0c;一旦咨询量非常大&#xff0c;往往会出现回复不及时的情况。如此一来便会影响客户的满意度&#xff0c;降低客…

记一次EDU证书站

如果文章对你有帮助&#xff0c;欢迎关注、点赞、收藏一键三连支持以下哦&#xff01; 想要一起交流学习的小伙伴可以加zkaq222&#xff08;备注CSDN&#xff0c;不备注通不过哦&#xff09;进入学习&#xff0c;共同学习进步 目录 目录 1.前言&#xff1a; 2.信息搜集 3.漏…

H5前端开发——BOM

H5前端开发——BOM BOM&#xff08;Browser Object Model&#xff09;是指浏览器对象模型&#xff0c;它提供了一组对象和方法&#xff0c;用于与浏览器窗口进行交互。 通过 BOM 对象&#xff0c;开发人员可以操作浏览器窗口的行为和状态&#xff0c;实现与用户的交互和数据传…

sahi切片辅助训练推理

本文的目的切片yolov5标注格式的数据&#xff0c;并保存图片和标注文件 代码实现步骤如下 把yolov5格式转换成coco格式标签&#xff1b;切片图片和coco标签&#xff1b;把切片出来的coco标签转换回yolov5标签格式 # 1. 把yolov5格式转换成coco格式标签&#xff1b; # 2. 切片…

Java关键字 `super` 的骚操作

文章目录 1. 调用父类构造方法2. 访问父类属性和方法3. 创建父类引用4. 在接口中使用 super5. 在 Lambda 表达式中使用 super6. 异常处理结语 &#x1f389;欢迎来到Java学习路线专栏~Java关键字 super 的骚操作 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#…

Android gradle动态配置不同打包环境参数值

一、背景 在android开发中&#xff0c;包的构建通过gradle脚本来完成的&#xff0c;这个脚本也提供了很多东西来配合我们开发。最常见的类似渠道和不同版本包。 打包的配置常见的是buildTypes节点&#xff0c;通过buildTypes设置不同的action完成不同包的输出 二、gradle的Jav…

(八)vtk常用类的常用函数介绍(附带代码示例)

vtk中类的说明以及函数使用 https://vtk.org/doc/nightly/html/annotated.html 一、vtkObject派生类 1.vtkPoints 点 InsertNextPoint(double, double, double)&#xff1a;插入点。 2.vtkCellArray 单元数组 InsertNextCell (vtkIdType npts, const vtkIdType *pts)&…

【底层服务/编程功底系列】「大数据算法体系」带你深入分析MapReduce算法 — Shuffle的执行过程

【底层服务/编程功底系列】「大数据算法体系」带你深入分析MapReduce算法 — Shuffle的执行过程 Shuffle是什么Shuffle的流程处理map任务的执行流程reduce任务的执行流程 Shuffle过程分析和优化map任务深入分析细化步骤分析1. 数据分片读取2. 分配计算Reduce服务Partitioner分区…

LINUX | hexdump以16进制查看文件内容

LINUX | hexdump以16进制查看文件内容 时间&#xff1a;2023-10-20 文章目录 LINUX | hexdump以16进制查看文件内容1.参考2.示例1.以ASCII字符显示文件中字符2.以16进制和相应的ASCII字符显示文件里的字符3.只显示文件中前n个字符4.以偏移量开始格式输出 1.参考 1.Linux命令–h…

C语言指针精简版(二)

目录 数组名的理解 使⽤指针访问数组 ⼀维数组传参的本质 冒泡排序 ⼆级指针及其解引用 指针数组 实例&#xff1a;指针数组模拟⼆维数组 数组名的理解 对于数组名表示的意义一共有三种情况&#xff1a; *1、数组名&#xff1a;表示数组⾸元素地址。 *2、sizeof(数组名…

中文编程工具开发语言开发的实际案例:触摸屏点餐软件应用场景实例

中文编程工具开发语言开发的实际案例&#xff1a;触摸屏点餐软件应用场景实例 软件特色&#xff1a; 1、功能实用&#xff0c;操作简单&#xff0c;不会电脑也会操作&#xff0c;软件免安装&#xff0c;已内置数据库。软件在关闭的时候&#xff0c;可以设置会员数据备份到U盘&…