利用 Proxy 代理与 Reflect 反射实现 mv 模型视图,多层数据动态渲染页面,模仿 vue3 双向绑定中 viewModel 核心功能,实现一个 打怪升级 的小游戏“勇士之战”。

数据模型层面

多层数据对象,需要监听对象里面任一属性的改变

const _model = {warrior: {id: "warrior_1",name: "凯萨",originalHealth: 100,health: 100,attack: 12,speed: 0.67,live: true},enemyArr: [{id: "enemy_1",name: "迦泰",originalHealth: 120,health: 120,attack: 15,speed: 0.4,live: true}, {id: "enemy_2",name: "欧罗",originalHealth: 80,health: 80,attack: 10,speed: 1.1,live: true}, {id: "enemy_3",name: "莉丝",originalHealth: 70,health: 70,attack: 8,speed: 2,live: true}],gameover: false,artUrl: "https://lf6-creative.dailygn.com/obj/tmg-gameres-static/build-template-assets/4a661d55935185b515f251e55765233c/action.png",art: {idle: "https://lf6-creative.dailygn.com/obj/tmg-gameres-static/build-template-assets/4a661d55935185b515f251e55765233c/action.png",play: "https://lf6-creative.dailygn.com/obj/tmg-gameres-static/build-template-assets/d58b07f4650e18939159658dd050e09d/action.gif"}
};

视图显示层面

根据数据的变化动态创建、修改删除dom,减少页面重绘与重排,提高性能

const _view = (_model) => {console.log("_model", _model);/*** 勇士数值*/// 我方勇士const warrior = _model.warrior;if (warrior.health > 0) {setDiv(findDiv(warrior.id, "warrior"), `${warrior.name},生命值:${warrior.health},攻击力:${warrior.attack},攻速:${warrior.speed}`);} else {if (warrior.live) {stopFun();alert(`很遗憾☹,我方勇士 ${warrior.name} 战斗失败,继续努力`);warrior.live = false;_model.gameover = true;delDiv(warrior.id);}}// 对手勇士const enemyArr = _model.enemyArr;enemyArr.forEach((v, k) => {if (v.health > 0) { setDiv(findDiv(v.id, "enemy"), `${v.name},生命值:${v.health},攻击力:${v.attack},攻速:${v.speed}`); } else {if (v.live) {stopFun();const addHealth = Math.round(v.originalHealth / 3 * 2);const addAttack = v.attack > warrior.attack ? Math.round(v.attack / 3) : 0;const addSpeed = v.speed > warrior.speed ? Math.round(v.speed / 3) : 0;alert(`我方勇士 ${warrior.name} 战胜对手勇士 ${v.name} ,获得奖励,生命值:+${addHealth}${addAttack ? ",攻击力:+" + addAttack : ""}${addSpeed ? ",攻速:+" + addSpeed : ""}`);_model.warrior.health += addHealth;if (addAttack) _model.warrior.attack += addAttack;if (addSpeed) _model.warrior.speed += addSpeed;v.live = false;delDiv(v.id);delLabel(v);}}});// 战斗结束if (!enemyArr.map(v => v.live).includes(true) && !_model.gameover) {stopFun();alert(`恭喜☺,我方勇士 ${warrior.name} 在“勇士之战”中大获全胜`)_model.gameover = true;}/*** 勇士战场*/// 勇士名称setDiv("self", warrior.name);// 选择列表selectList(_model.enemyArr);// 战斗场面actionArt(_model.artUrl);
};

数据模型与视图显示动态绑定(可通用的核心代码)

数据对象中的任一数据改变,立即触发视图显示方法,实现动态渲染页面

const mv = (obj, callback, pointer) => {let single = true;callback.call(pointer, obj);const proxy = (_obj, callback, pointer) =>new Proxy(_obj, {set(target, property, value, receiver) {if (target[property] !== value) setTimeout(() => {if (!single) callback.call(pointer, obj);}, 0);Reflect.set(target, property, value, receiver);return true;},});const recursion = (_obj) => {for (const key in _obj) {["[object Object]", "[object Array]"].includes(Object.prototype.toString.call(_obj[key])) &&(_obj[key] = proxy(_obj[key], callback, pointer)) && recursion(_obj[key]);}}recursion(obj)setTimeout(() => {single = false;}, 0);return proxy(obj, callback, pointer);
};

游戏界面,在线体验地址,代码仓库地址

游戏界面

在线体验地址

点击前往在线体验地址

代码仓库地址

关于游戏玩法及更多详细的介绍,完整的示例代码,请前往游戏开源仓库查看

点击前往游戏开源代码仓库地址

利用 Proxy 代理与 Reflect 反射实现 mv 模型视图,实现一个 打怪升级 的小游戏“勇士之战”相关推荐

  1. Proxy代理 和 Reflect反射(反射的是obj)的概念

    1. Proxy代理 // 供应商(原始对象)let obj = {time:'2018-01-03',name:'net',_r: "123"}// 创建代理商,传入obj数据l ...

  2. 利用random 的randint 方法写一个猜数字的小游戏

    学习python第二天,编写的一款数字小游戏 昨天学习完条件语句和while循环,老师留下的作业:利用random 的randint 方法写一个猜数字的小游戏. 第一次在CSDN上记录,小白一枚.希望 ...

  3. 利用java开发一个猜数字幸运小游戏:游戏规则如下

    package com.day04.www;import java.util.Random; import java.util.Scanner;public class day04 {public s ...

  4. HTML制作猜拳小游戏,利用Eclipse制作的一个简单UI猜拳小游戏

    玩家类: import java.util.*; public class Players { //玩家角色名 String userName="";--------------- ...

  5. 利用Python制作一个发红包的小游戏

    本系统的内容是综合应用python程序设计的知识,实际并实现了一款简单发红包的小游戏,具体功能如下: (1)拼手气红包:随机金额 (2)普通红包:能够通过输入的红包人数与红包金额实现平均分配 (3)专 ...

  6. 利用js写一个类似打地鼠的小游戏

    代码仅供参考 css代码; *{margin: 0;padding: 0; } a{text-decoration: none; }.root{width: 320px;height: 480px;b ...

  7. 2048小游戏——简简单单利用js做出自己的游戏!!

    博主教你轻轻松松利用js技巧 写出属于自己的2048小游戏!! 自己做出实现在页面中 想必大家都听说过甚至玩过2048这款小游戏 博主无聊时也会拿起手机或者在电脑上玩上几把 但是大家有没有想过自己花费 ...

  8. Proxy(代理,拦截器),Reflect(反射)

    Proxy(代理,拦截器),Reflect(反射) Proxy: 代理: var duixaing = {"name":"小胖","age" ...

  9. 自己写一个java.lang.reflect.Proxy代理的实现

    前言 Java设计模式9:代理模式一文中,讲到了动态代理,动态代理里面用到了一个类就是java.lang.reflect.Proxy,这个类是根据代理内容为传入的接口生成代理用的.本文就自己写一个Pr ...

最新文章

  1. python网页登录验证码不显示_进网页需要验证码?不好意思,Python从来不惧各种验证码!...
  2. 整数的素因子分解:Pollard rho method
  3. java基本数据类型填空题_java基本数据类型练习题
  4. Markdown语言调整图片居中、大小
  5. C++_ 多态与虚函数介绍
  6. ARM64体系结构编程1-加载与存储指令
  7. 自然语言处理中的词袋模型
  8. 学计算机科学与技术的考研方向,计算机科学与技术考研方向?
  9. 阿里api网关接口创建、发布、授权、调试
  10. unity 数字键的输入及刚体的速度的设置
  11. 原生js 给动态添加的元素添加(事件监听器)
  12. 项目管理工具之甘特图
  13. Html单选按钮自定义样式
  14. 计算机维修轿车,解决方案:轿车电脑故障维修两例
  15. python实现注册功能_python注册、登录,python注册登录,#1、实现注册功能#
  16. Gephi (网络分析软件) 下载、安装及简单使用
  17. 2016 免费申请邓白氏码的步骤
  18. 戴维营第三天上课总结
  19. 驱动3脚双色LED电路方式
  20. 项目经理:衡量项目成功与否的关键,在于这三个要素

热门文章

  1. 电脑网页的上网记录怎么查
  2. 消费者洞察:案例透视消费者洞察实践与收益
  3. 黑马程序员mfc中分割窗口---ctreeview未定义基类的解决方法
  4. ##杭电oj id1000
  5. Java PrintWriter类简介说明
  6. 谷歌显示不安全连接到服务器,Chrome 浏览器显示“网站连接不安全”,是什么原因?...
  7. 此请求已被阻止;内容必须通过HTTPS提供 This request has been blocked; the content must be served over HTTPS.
  8. [转载]什么叫资源整合? 看懂了多赚一个亿!
  9. vscode格式化失效问题
  10. 【短视频运营】账号主页搭建 ① ( 昵称 | 昵称原则 | 昵称公式 | 昵称禁忌 | 个人简介 | 个人简介公式 )