半天快速用vue搭建小游戏——“花光马云的钱”
本文字数
本文总计1791字,预计花费15分钟。
先看半成品
预览图
在线地址:点我
扫码查看:
github地址,希望小伙伴门能点个star~~:点我
本文适合人群
有一点点前端基础的,对vue有一点点了解的,知道基本语法的。
本文没有什么高级技巧,毕竟本人也是个小菜鸡。
下文主要讨论逻辑是怎么实现的,也就是js怎么写的,css建议直接复制本人GitHub里的。本人css水平也是一言难尽。。
技术栈
vue + vue-router + vant
没有使用用vuex,组件间使用eventBus进行通信(其实就是三两行代码,一切从简)
构建过程
-
vue-cli初始化项目
这个就不详细介绍了。
首先保证安装了全局vue-cli脚手架,如果没有的话:
npm install -g @vue/cli
创建vue项目:
vue create spend-all-money
本文使用vant ui框架,进入spend-all-money目录,运行
npm i vant -S
-
代码目录及基本结构
目录:
目录结构如上,不复杂。
需要注意的是,我的所有vant组件引用都放到了src/vantImport.js里,并在main.js里引用了该文件。下文所有使用到的vant组件都已在该处进行引用,不再赘述。
eventBus.js代码如下:
import Vue from "vue"; export default new Vue();
同时在main.js里将其绑定到全局vue上:
import bus from "./eventBus"; Vue.prototype.$bus = bus; Vue.config.productionTip = false;
这样在其他组件里可以使用this.$bus.$emit(......)或this.$bus.$on(....)进行发送和接收消息。
-
登录界面
首先要做的是登录界面,大概就是两个按钮——“单机开始”和“网络开始”,其中“网络开始”留个坑,有空把后端写好再填坑。(ps:nest.js写起来真爽,typescript万岁)。
首先新建src/views/Main/index.vue,然后在src/router/index.js里配置下路由。
....some code..... import Main from "../views/Main/index"; const routes = [ { path: "/", name: "main", component: Main } ]; ......somde code.......
完成之后在src/views/Main/index.vue里编写具体代码。
html如下:
<!-- 开始游戏--> <div class="main-start"> <van-button round size="large" color="linear-gradient(to right, #4bb0ff, #6149f6)" class="main-start-btn" to="/single" >单机开始</van-button > <van-button round size="large" color="linear-gradient(to right, #4bb0ff, #6149f6)" class="main-start-btn" @click="goNetGame" >网络开始</van-button > </div>
创建了两个vant-button,并将单机开始的link设置到具体游戏界面的路由。
js部分没有什么需要写的,goNetGame方法使用了一个提示,留坑代填。
// todo:网络游戏 goNetGame() { this.$toast("敬请期待"); }
-
单机游戏界面
啰嗦一堆终于终于来到具体的游戏界面了。
首先将游戏界面以组件化的思想进行拆分,大体可分为头部(马云头像)、总资产(粘性布局,页面往下划动时始终黏在页面最上方)、物品卡片。
游戏界面就是以上几者的组合,其中物品卡片会有很多,用v-for进行循环渲染。
html如下:
<template> <div class="single"> <HeaderLink></HeaderLink> <Header></Header> <TotalMoney></TotalMoney> <Card v-for="(item, i) in goodsList" :key="i" :name="item.name" :price="item.price" :image-url="item.imageUrl" ></Card> </div> </template>
js如下:
<script> import Header from "../../components/Header"; import TotalMoney from "../../components/TotalMoney"; import HeaderLink from "../../components/HeaderLink"; import Card from "../../components/Card"; import { mixin } from "./minxin"; export default { mixins: [mixin], name: "single", components: { Card, HeaderLink, Header, TotalMoney } }; </script>
mixin为src/views/SingleGame/mixin.js文件,里面包含了物品卡片的信息,如物品name、price、imageUrl等。因其太长,不把代码列出来了,直接给个文件链接,点我。如果小伙伴想要自己修改或者新增物品的话,也是在这个文件里进行修改哦。
完成后配置路由如下:
const routes = [
{
path: "/",
name: "main",
component: Main
},
{
path: "/single",
name: "single",
component: () => import("../views/SingleGame/")
}
];
接下来可以编写具体的组件啦。
-
头部——马云照片
新建src/components/Header.vue,其中html代码如下:
<template> <div class="j-header"> <van-image round width="8rem" height="8rem" src="mayun.jpg" /> <div style="font-size: 25px">花 光 马 云 的 钱</div> </div> </template>
主要就是一个展示作用,不需要什么js代码。
-
头部——总资产
新建src/components/TotalMoney.vue,其中html代码如下:
<template> <van-sticky> <div class="totalMoney"> <div class="totalMoney-text">{{ monenyStr }}</div> </div> </van-sticky> </template>
js代码如下:
<script> export default { name: "TotalMoney", data() { return { totalMoney: 275000000000 }; }, computed: { monenyStr() { let moneyStr = this.toThousandsStr(this.totalMoney); moneyStr = `剩余:¥${moneyStr}`; return moneyStr; } }, created() { this.$bus.$on("changeMoney", money => { this.totalMoney = this.totalMoney - money; }); }, methods: { /** * 数字转字符串,并添加逗号 * @param num
*/
toThousandsStr(num) {
let result;
(num = (num || 0).toString()), (result = "");
while (num.length > 3) {
result = "," + num.slice(-3) + result;
num = num.slice(0, num.length - 3);
}
if (num) {
result = num + result;
}
return result;
}
}
};
</script>
```
js代码定义了总钱数,并将其转为字符串,在数字间添加逗号以方便读。
this.$bus.$on("changeMoney", money => {
this.totalMoney = this.totalMoney - money;
});
上面这段代码可以监听其他组件发送来的消息,修改总钱数。
-
物品卡片
新建src/components/Card.vue。
html代码如下:
<template> <div class="card"> <!-- 图片--> <van-image width="100" height="100" lazy-load :src="imageUrl" class="card-image" /> <!-- 名称--> <div class="card-name">{{ name }}</div> <!-- 价格--> <div class="card-price">¥{{ priceStr }}</div> <!-- 按钮--> <van-row class="card-control"> <!-- 卖--> <van-col span="8"> <van-button type="danger" class="card-control-btn" @click="changeCount(-1)" >卖</van-button > </van-col> <!-- 数量--> <van-col span="8"> <van-field placeholder="0" input-align="center" style="border-style: solid; border-width: 1px" v-model="countStr" type="number" :clickable="true" maxlength="10" /> </van-col> <!-- 买--> <van-col span="8"> <van-button type="primary" class="card-control-btn" @click="changeCount(1)" >买</van-button > </van-col> </van-row> </div> </template>
理解一下以上代码,主要将一个卡片分为图片、价格、名称、买卖按钮以及数量输入框。
js代码如下:
<script> export default { name: "Card", props: { name: { type: String, default: "测试" }, imageUrl: { type: String, default: "https://img.yzcdn.cn/vant/cat.jpeg" }, price: { type: Number, default: 999 } }, data() { return { count: 0, keyboardShown: false }; }, computed: { // 将数字转成字符串 // todo:小数负数需要做进一步处理 countStr: { get() { return this.count.toString(); }, set(newVal) { let counInt = parseInt(newVal); if (isNaN(counInt) || counInt <= 0) { counInt = 0; } this.count = counInt; } }, priceStr: { get() { return this.toThousandsStr(this.price); } }, // 该卡片的总价格:数量*单价 cardMoney: { get() { return this.count * this.price; } } }, watch: { // 监听总价值的改变并发送消息给总资产组件 cardMoney(val, oldVal) { const diff = val - oldVal; // eslint-disable-next-line no-console console.log(val, oldVal); this.$bus.$emit("changeMoney", diff); } }, methods: { changeCount(val) { if (this.count <= 0 && val < 0) { return; } this.count += val; }, // todo:两个地方用到,后续可以单独出来 /** * 数字转字符串,并添加逗号 * @param num
*/
toThousandsStr(num) {
let result;
(num = (num || 0).toString()), (result = "");
while (num.length > 3) {
result = "," + num.slice(-3) + result;
num = num.slice(0, num.length - 3);
}
if (num) {
result = num + result;
}
return result;
}
}
};
</script>
```
这段代码说明该调用该组件时需要传入三个参数:物品名称(name)、物品图片链接(imageUrl)、物品价格(price)。
点击买和卖时修改对应物品数量(count),监听count以获取该物品卡片的总价值(count*price),并在总价值发生变化时将变化值发送出去。
### 5. 总结
以上就完成了所有功能的编写,是不是特别简单呢。觉得有帮助的话点个赞和star吧~
github地址:[点我]( https://github.com/QJvic/spend-all-mone )
TODO:
1.阻止总资产变成负数。
2.写个成就功能,当花掉多少钱时弹出彩蛋。
3.完成在线联机功能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。