<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>zero_dev (ZERO开发)</title>
    <link>http://beta.w2solo.com/zero_dev</link>
    <description>公众号：ZERO开发</description>
    <language>en-us</language>
    <item>
      <title>如何在 Unity3D 导入 Spine 动画</title>
      <description>&lt;h2 id="一、前言"&gt;一、前言&lt;/h2&gt;
&lt;p&gt;《如何在 Unity3D 项目中导入 Spine 动画》，虽然在网上有很多这种文章，直接将问题交给&lt;strong&gt; DeepSeek&lt;/strong&gt; 也能得到具体的操作流程，但是照着他们提供的方法还是能遇到几个问题，比如：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;AI 回答没有提到 Unity 无法识别.altas，要修改动画文件后缀部分；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;导入到游戏场景中，动画总是被 Canvas 的背景图或元素挡住，层级低；&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;所以针对这几点问题和操作流程，再带上&lt;strong&gt; Spine 的基本操作&lt;/strong&gt;，我整理成文章，那么，下面先参照一下我的工具版本开始。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/7a60d50e-e648-4d7a-bfe3-dcb2a26554da.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="二、工具"&gt;二、工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unity3D 2020.3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spine 3.8.75&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;spine-unity-3.8-2021-11-10&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2D 场景游戏&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/98312a2d-5e14-4f5e-a28e-737d82cec29e.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="三、Spine 操作"&gt;三、Spine 操作&lt;/h2&gt;
&lt;p&gt;因为练习时，多数动画文件是直接下载的别人制作好的 json 导出文件（非工程）。所以如果要在游戏场景前看效果，可以先导进 Spine 工具中查看一下。&lt;/p&gt;
&lt;h3 id="json 导出文件目录"&gt;json 导出文件目录&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fileName.altas // 图集描述文件
fileName.json  // 骨骼动画数据
fileName.png   // 纹理图集
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="导入文件"&gt;导入文件&lt;/h3&gt;
&lt;p&gt;1. 导入数据 &amp;gt; 选择 “JSON 或二进制文件”&amp;gt; 文件选 “json” 格式文件 &amp;gt; 导入&lt;/p&gt;

&lt;p&gt;2. 保存更改 &amp;gt; 浏览 &amp;gt; 自定义名称的 “spine” 格式文件&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/42fb1c3c-deb0-4d7b-b2d4-054e78a39659.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="展示纹理"&gt;展示纹理&lt;/h3&gt;
&lt;p&gt;1. 纹理解包器 &amp;gt; 图集文件选择 “.atlas” 格式文件 &amp;gt; 输出文件夹随便指定即可 &amp;gt; 解开&lt;/p&gt;

&lt;p&gt;2.Hierarchy &amp;gt; 图片 &amp;gt; 图片文件 &amp;gt; 路径，找到纹理解包后的输出文件夹&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/56c29571-68a3-4614-9de9-40b79a025538.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="其他"&gt;其他&lt;/h3&gt;
&lt;p&gt;通常一个 json 导出文件里可以包含很多个动画，可以看到预览右边的列表，每一个选项就是一个动画，选中可以预览，左边的工程窗的设置可以进入 K 帧窗。&lt;/p&gt;

&lt;p&gt;更多的比如骨骼绑定，蒙皮刷权重，K 帧，我后面再出一个单独的文章说明，下面就进入正题到 Unity 的导入了。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/644bfb33-b35d-4812-afb7-66d681d0ead9.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="四、导入 Unity3D"&gt;四、导入 Unity3D&lt;/h2&gt;
&lt;p&gt;要在 Unity3D 导入前需要先下载 Spine Unity 运行库，可以网上找 Spine 官方下载页；第二个是前面提到的 Unity 不识别.atlas 文件，将动画放到 Unity 项目的资源文件夹下需要将.atlas 改成.txt 后缀的文件。&lt;/p&gt;
&lt;h3 id="Spine Unity 运行库安装"&gt;Spine Unity 运行库安装&lt;/h3&gt;
&lt;p&gt;在 Unity 中，点击菜单栏 &lt;strong&gt;Assets &amp;gt; Import Package &amp;gt; Custom Package&lt;/strong&gt;，选择下载的&lt;code&gt;.unitypackage&lt;/code&gt;文件，导入全部内容。&lt;/p&gt;

&lt;p&gt;最后在工具栏的 GameObject 下，查看是否有 Spine 选项，就可以验证安装成功与否。&lt;/p&gt;
&lt;h3 id="Spine 数据资源生成"&gt;Spine 数据资源生成&lt;/h3&gt;
&lt;p&gt;前面提到的 Spine 动画的三个文件，再放入游戏资产文件夹中修改了图片描述文件格式后，打开项目后，Unity 会自动生成一个.meta 和两个.asset 文件。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_Atlas.asset             与之前的atlas对应的图集描述文件
_Material.mat            与之前的png对应的素材纹理
_SkeletonData.asset      与之前的json对应的骨骼数据文件&amp;lt;/pre&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="创建动画对象"&gt;创建动画对象&lt;/h3&gt;
&lt;p&gt;因为游戏是 2D 的，我主体场景用的是 Canvas，开头也提到过的导入后总是显示在 Canvas 背景图的下层，所以第一步就从设置画面开始。&lt;/p&gt;

&lt;p&gt;1. 选中 Canvas 后，Render Mode 选择 “Screen Space-Camera”，Hierachy 中的 Main Camera 拖入 Render Camera 中。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/bd6a0a8f-d58b-4c5d-8e81-94eb8e1051f0.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;2. 在场景中创建空对象（如右键 Hierarchy &amp;gt; &lt;strong&gt;Create Empty&lt;/strong&gt;），命名为 SpineCharacter&lt;/p&gt;

&lt;p&gt;3. 添加组件：点击 &lt;strong&gt;Add Component&lt;/strong&gt;，搜索并添加 &lt;strong&gt;Skeleton Animation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;4. 配置组件：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skeleton Data Asset&lt;/strong&gt;：拖入前面 “Spine 数据资源” 生成的&lt;code&gt;_SkeletonData.asset&lt;/code&gt;文件。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Animation Name&lt;/strong&gt;：输入默认播放的动画名称（如&lt;code&gt;idle&lt;/code&gt;）。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Loop&lt;/strong&gt;：勾选以循环播放。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scale&lt;/strong&gt;：调整 Rect Transform 的 Scale，大小自行尝试。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5.Shader 设置 &lt;strong&gt;UI/Default&lt;/strong&gt;，默认的 Spine Skeleton 素材拼接得有点锯齿，详细的可以自行选择尝试。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/f5671e06-b591-4c98-819c-62a2552269fe.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="脚本控制动画"&gt;脚本控制动画&lt;/h3&gt;
&lt;p&gt;创建 C# 脚本（如&lt;code&gt;SpineController.cs&lt;/code&gt;）并附加到角色对象&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Spine.Unity;
public class SpineController : MonoBehaviour {
 public SkeletonAnimation skeletonAnim;
 public string runAnimation = "run";

 void  Start() {
 skeletonAnim.AnimationState.SetAnimation(0, runAnimation, true);
 }

 // 切换动画
 public  void  PlayAnimation(string  animName) {
 skeletonAnim.AnimationState.SetAnimation(0, animName, true);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="写在后面"&gt;写在后面&lt;/h2&gt;
&lt;p&gt;为什么我做小游戏从 CocosCreator 切到了 Unity3D，原因是这次尝试的是抖音直播小玩法，也就是弹幕小游戏。&lt;/p&gt;

&lt;p&gt;前期为了跑通流程，所以我要避开所有要用到服务端的产品开发，从而采用指令直推方式，但官网只有 Unity SDK 的案例，最后有了这篇文章，当然后续还有更多。&lt;/p&gt;

&lt;p&gt;当然 CocosCreator 制作普通单机小游戏我也会继续，不过当前以 2D 为主，毕竟现在用 AI 抽卡来生成游戏资产太方便了，等图生 3D 模型较完善的时候，以后再用 AI 制作 3D 小游戏。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/8c55885d-dce9-43d3-89e0-d3dab5963517.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Mon, 12 May 2025 17:47:10 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5769</link>
      <guid>http://beta.w2solo.com/topics/5769</guid>
    </item>
    <item>
      <title>个人开发者，还能入局抖音直播小玩法吗？</title>
      <description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;前段时间，我在微信问一问里回答了一个关于 “一天赚几十块钱副业有哪些？” 的问题。主要推荐的是直播小玩法的副业，截至目前收获了官方 1 万的推流和超 5 千人的围观。由此我认为，当前开发直播小玩法还是比较小众，竞争小，个人开发者入局应该能躺赚一笔，真的很适合参考以前的回合制游戏。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/a5771fdd-3003-415f-852c-281bd10c4e11.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;直播小玩法是抖音里的一种统称，其他平台有叫直播弹幕小游戏，而抖音里的直播小玩法包括两种，弹幕小游戏和互动插件。个人主体开发者申请软著后，符合平台规范都能上架。上架后，只要有主播用了你的开播，就能享受直播间的礼物分成，分成比例见下图。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/e2788d5f-2c97-401f-be0b-49b7d5966753.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;比例看着确实比较低，但他也有一个很符合被动收益的优势：一经开发，多端部署，多人开播，无需直接面向观众。就是我们开发后，其实是可以发布到多个平台的，已知对个人开发者开发弹幕游戏上架的平台有：&lt;/p&gt;

&lt;p&gt;1. 抖音
2. 哔哩哔哩
3. 虎牙&lt;/p&gt;

&lt;p&gt;同一平台可以让多个主播同时开播，看似一场直播分百分之八，但如果一天有 100 个主播，就可以从 100 个直播间分走百分点的收入。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/cb29b9c3-552e-4ac4-a70c-da2c9a8bd07a.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="现状"&gt;现状&lt;/h2&gt;
&lt;p&gt;上架直播小玩法虽然是小众行业，但也同样有二八效应，据业内人士说，弹幕游戏有榜单，如果上架后能冲进前 30，那每月被动收入十几 W 很常见。比如 2023 年的两款，《兵临城下》这款游戏全平台月流水超过 6000 万，《星辰无双》日均流水突破 150 万元。&lt;/p&gt;

&lt;p&gt;这些头部爆款多数是开发团队完成的，个人开发者前期不试水，上架后可能就是主播一日游，然后还要承担服务器的费用。当然前面的优势和收益也是很可观的，这里只是在入局前给个预期中和一下，防止后期沉默成本过高。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/b44d7435-c1f3-4ba5-8507-31ac18b6185b.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="开发"&gt;开发&lt;/h2&gt;
&lt;p&gt;根据官方开发文档介绍，互动插件和弹幕小游戏都支持单价版开发，也就是无需购买服务器，通过客户端接收推送完成交互。互动插件这里就不详细介绍了，类似直播里的点歌，点击屏幕上一个按钮，下拉出一些歌曲列表，选中后可以发送到直播间，这种的交互性更似小程序，可专门为开课，舞蹈博客定制相应的业务型互动插件。&lt;/p&gt;

&lt;p&gt;而弹幕小游戏的开发，主要的是通过接收直播间的弹幕、礼物数据后，在游戏中显示对应的增益效果，比如送出仙女棒触发什么，阵营能提升什么。大部分是大同小异，更多的是主题和效果的设计，哪些更能迎合主播和观众，下面就用服务器 + 文档 API，介绍一下大致的开发过程。&lt;/p&gt;
&lt;h2 id="流程"&gt;流程&lt;/h2&gt;
&lt;p&gt;1. 用直播伴侣打开后获取 Token 请求服务器接口&lt;/p&gt;

&lt;p&gt;2. 服务端根据 Token 获取房间 ID 并返回到小玩法&lt;/p&gt;

&lt;p&gt;3. 服务端将监听的房间数据通过长链接推送到小玩法&lt;/p&gt;

&lt;p&gt;4. 小玩法根据礼物、弹幕等数据展示 buff 效果&lt;/p&gt;

&lt;p&gt;5. 时间结束后根据业务数值判断阵营输赢并排名&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/b637f940-3a87-4c15-90a3-856d72b4d41d.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="服务端接口"&gt;服务端接口&lt;/h2&gt;
&lt;p&gt;下面就从官方文档里列出一些服务端业务中需要用的请求接口，详细可见开放平台的小玩法文档的服务端 API 介绍。&lt;/p&gt;
&lt;h4 id="接口调用凭证"&gt;接口调用凭证&lt;/h4&gt;
&lt;p&gt;access_token 是服务端接口的全局唯一调用凭据，如下面直播信息里的 "X-Token"，任务启动的 “access-token” 传递的请求头参数用的都是这个。access_token 的有效期为 2 个小时，需要定时刷新 access_token。&lt;/p&gt;
&lt;h4 id="直播信息"&gt;直播信息&lt;/h4&gt;
&lt;p&gt;主播使用直播伴侣或移动端云启动玩法后，直播伴侣 / 移动端云启动会传入 token 到玩法中，当玩法获取 token 后，传递给玩法的服务端。玩法服务端通过该接口，使用 token 获取直播间信息，在返回到客户端前，服务端还需要调用 “任务启动”、“礼物置顶”。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "ack_cfg": [ // 预留信息，sdk接入使用，开发者不用感知
    ],
    "linker_info": { // 连屏数据预留信息，开发者目前不用感知
        "linker_id": 0,
        "linker_status": 0,
        "master_status": 0
    }，
    "info": {
        "room_id": 7214015683695250235,
        "anchor_open_id": "_000oJIu6APhomK7KIBGqSYm5XYPxCJB_xxx",
        "avatar_url": "https://p11.douyinpic.com/aweme/720x720/aweme-avatar/tos-cn-avt-0015_973c31e8055f78a41d3f7de3def9821d.jpeg?from=3067671334",
        "nick_name": "xxx"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="任务启动"&gt;任务启动&lt;/h4&gt;
&lt;p&gt;调用任务启动后，直播间数据才会同步推送给开发者服务器，注意：不同类型的数据需要启动不同的任务单独监听，比如礼物数据单独启动一个，评论数据单独启动一个，见文档的数据开发。&lt;/p&gt;
&lt;h4 id="礼物置顶"&gt;礼物置顶&lt;/h4&gt;
&lt;p&gt;为什么还要调这个接口，因为置顶的礼物被送出，才会有礼物数据推送（后期会废用不需要这一步），实现时可以在获取房间 ID 后异步调用。然后直播挂载小玩法后，开发者根据玩法场景自主控制当前场景需要置顶的礼物，前提是置顶的礼物在玩法维度礼物配置中。调用置顶礼物接口的条件：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  已开通 “获取礼物互动数据能力”&lt;/li&gt;
&lt;li&gt;  置顶的礼物数量不能超过 6 个，且必须为礼物配置列表中已勾选的礼物&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="分页查询推送失败数据"&gt;分页查询推送失败数据&lt;/h4&gt;
&lt;p&gt;可以用定时任务对已经开播的 RoomId 请求 api 分页查询推送失败的数据，返回空代表全部推送成功，否则可以根据业务需求记录失败的数据和重新推送到小玩法客户端。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
  "err_no": 0,
  "err_msg": "ok",
  "logid": "20220927122238291",
  "data": {
    "page_num": 1,
    "total_count": 100,
    "data_list": [
      // 当页的数据列表
      {
        "roomid": "12345", // string类型，消息的房间id
        "msg_type": "live_gift", // string类型，表示消息类型
        "payload": "[...]" // string类型， 对应推送协议中的payload字符串，需要unmarshal
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="其他接口"&gt;其他接口&lt;/h4&gt;
&lt;p&gt;弹幕数据上报、用户战绩与排行榜看自身业务使用，而小玩法客户端主要就和服务端保持长链接，接收直播间互动数据，以及三个 Http 业务接口。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  开启，获取 roomId&lt;/li&gt;
&lt;li&gt;  结算，传递比赛结果&lt;/li&gt;
&lt;li&gt;  获取排行榜单&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/3cb968fd-fd47-4e1a-850a-1e2d8025a258.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="写在后面"&gt;写在后面&lt;/h2&gt;
&lt;p&gt;上面的是官方玩法，其实还有第三方，而且抖音推出抖音小玩法可能也是打不过就加入的策略。因为以前盛行一时的无人直播，像修狗云蹦迪、挤地铁、马保国格斗等，都是别人用技术手段实现弹幕礼物接收实现的小游戏。&lt;/p&gt;

&lt;p&gt;因为没有人出境和抓取数据等原因，开播的房间经常被封，虽然被封，但收益不错也屡禁不止，所以抖音干脆开放小玩法模块（个人猜想），更大程度实现主播、开发者、观众双收。我已知第三方平台有：咩播、阿比整蛊、青播，有机会我再聊聊关于这些平台软件的内部概况。
&lt;img src="https://img.way2solo.com/photo/zero_dev/42f94c71-d3dc-4e8b-8506-b4134bf74ba4.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Mon, 23 Dec 2024 17:04:15 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5331</link>
      <guid>http://beta.w2solo.com/topics/5331</guid>
    </item>
    <item>
      <title>我的 2024 年终总结，持续尝试</title>
      <description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;时光飞逝，一晃就到 2024 的年底了，按照我近年来的传统，就复盘一下今年做过的所有关于探索收入多样性的事情。包括这一年工作以外的 “工作进展”，收获的事项，遇到的种种问题，以及来年的计划等，最后希望能对大家有一点点参考意义。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/6fda2225-409a-4a78-a86e-2fb213a65693.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="事件"&gt;事件&lt;/h2&gt;
&lt;p&gt;1. Cocos 小游戏《忍者疾风转》开发，并上架到微信和抖音平台。&lt;/p&gt;

&lt;p&gt;2. 微信小程序《有用工具盒》开发并上架。&lt;/p&gt;

&lt;p&gt;3. 视频号《一曲小北》，主打编曲和吉他，首次开通广告分成计划。&lt;/p&gt;

&lt;p&gt;4. QQ 小程序《实用工具箱》上架，暂未开通广告分成。&lt;/p&gt;

&lt;p&gt;5. 微信公众号《ZERO 开发》发布推文 24 篇，首次小绿书 1 篇，爆文 5 篇。&lt;/p&gt;

&lt;p&gt;6. 三个 QQ 短视频账号注册孵化，均已开通广告共享计划。&lt;/p&gt;

&lt;p&gt;7. 鸿蒙 Next 应用开发，暂未上架，发布相关教程 3 篇，视频 1 个。&lt;/p&gt;

&lt;p&gt;8. 全网粉丝数达 20000 + 人，含抖音账号《小北玩游戏》。&lt;/p&gt;

&lt;p&gt;9. 微信问一问《ZERO 开发》，累计回答 45 个，推流 4w+，老铁 135 人。&lt;/p&gt;

&lt;p&gt;10. 重新搭建个人网站，加入独立博客联盟，友链，每日 UV 稳定破零。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/5a3e5bb5-cc66-4eaf-b9da-d4be65e46b38.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="收获"&gt;收获&lt;/h2&gt;&lt;h3 id="技能"&gt;技能&lt;/h3&gt;
&lt;p&gt;1. 主力开发语言增强，新增 Golang 和鸿蒙 Next 的 ArkTs。&lt;/p&gt;

&lt;p&gt;2. 单机游戏的 Mod 简单制作，游戏解包与封包。&lt;/p&gt;

&lt;p&gt;3. Adobe Audition 混音制作，用于视频号《一曲小北》更新。&lt;/p&gt;
&lt;h3 id="收入"&gt;收入&lt;/h3&gt;
&lt;p&gt;1. 公众号《ZERO 开发》婉拒 3 个第三方广告，如果大家同意我再接。&lt;/p&gt;

&lt;p&gt;2. 视频号《北桥苏》、《一曲小北》原创视频，每日广告收益。&lt;/p&gt;

&lt;p&gt;3. 微信小游戏、抖音小游戏《忍者疾风转》每日激励广告收益。&lt;/p&gt;

&lt;p&gt;4. 微信小程序《有用工具盒》每日开屏广告、信息流广告收益。&lt;/p&gt;

&lt;p&gt;5. 其他内容创作平台收益，哔哩哔哩，知乎，今日头条，QQ 短视频，大鱼号。&lt;/p&gt;
&lt;h3 id="社交"&gt;社交&lt;/h3&gt;
&lt;p&gt;1. 加入副业交流群 3 个，小游戏、小程序开发交流群 2 个。&lt;/p&gt;

&lt;p&gt;2. 个人运营程序员技术交流群 1 个，小程序交流 QQ 群 1 个。&lt;/p&gt;

&lt;p&gt;3. 线下交友活动较缺失，大部分集中在线上交流 (宅的通病)。&lt;/p&gt;
&lt;h3 id="投资"&gt;投资&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. 轻资产&lt;/strong&gt;：年初我关闭了自 2019 年末以来购买的所有基金，也错过了今年 10 月前后的一次 A 股大涨时机。转而放了一部分到余额宝和微信零钱通，每天就变成固定几块钱的收益了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 重资产&lt;/strong&gt;：当前市场环境下，我并没有做什么大决定，还处在观望状态，同时也在学习中。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/e8781bab-df87-44cd-b659-f4c85e135c38.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;p&gt;1. 个人产品自然流量普遍偏低&lt;/p&gt;

&lt;p&gt;因为以前技术崇拜，而不看重产品本身，导致入局独立开发比较晚，产品思维也跟不上，进一步影响到我做出来的小程序呈半吊子水平 (只能算是小应用而非产品)。&lt;/p&gt;

&lt;p&gt;所以我现在也开始学习调研，需求分析，推广营销等，因为我觉得独立产品开发是程序员晚期收入很重要的布局之一。&lt;/p&gt;

&lt;p&gt;2. 视频创作方向不明确&lt;/p&gt;

&lt;p&gt;不管是我的短视频还是中视频账号风格都还没定型，因为过去都是用来学习新东西后的记录视频，没有真人出镜和真人发声。平台既不给流量，在观感上也显得不真诚，给人种营销号的感觉，这个只能慢慢摸索方向，之后再尝试出镜和口播。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; 做事容易陷入自嗨模式&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;以前我觉得我还算理智，但其实大部分情况下，我是很容易陷入自嗨模式的。拍脑袋做事，头脑一热就决定，对能拿到的一些小成果自我陶醉，对失败却自我安慰，不总结也不吸取，视而不见。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/3261b8c5-d3b3-43a3-86bb-97e3aba4c8a3.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="计划"&gt;计划&lt;/h2&gt;
&lt;p&gt;1. 2025 年每周都写日志复盘，博客新增周刊栏目。&lt;/p&gt;

&lt;p&gt;2. 注册个人微信服务号，探索新方向，持续内容输出。 &lt;/p&gt;

&lt;p&gt;3. 直播弹幕小游戏，直播插件开发并上架。&lt;/p&gt;

&lt;p&gt;4. 用 Unity3D 引擎 +AI 独立开发一个偏大型的单机游戏。&lt;/p&gt;

&lt;p&gt;5. Blender、3D Max 建模改模学习，Mod 制作升级。&lt;/p&gt;

&lt;p&gt;6. 持续探索 AI 大模型个人项目变现，AI 应用开发。&lt;/p&gt;

&lt;p&gt;7. 加大小红书内容更新力度，完成商单权限开通。&lt;/p&gt;

&lt;p&gt;8. 个人资源（代码，创作源文件）变现，网盘拉新。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/878ef809-7a0a-4e32-adab-7016092dacb9.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;2024 年我的复盘结论就是 “持续尝试”，告别技术崇拜，但依然相信技术改变世界。二者不矛盾，但技术服务于业务，必须建立在价值产出之上。&lt;/p&gt;

&lt;p&gt;世界总是向熵增的方向演进，总是向着混乱发展，唯一不变的就是变，多方面尝试，多试错，快改进，难办就推倒重来，就算是草台班子也能找到一个方向，最后我也希望 2025 年的复盘主题是 “持续深耕”！&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/f143c036-6f14-4b72-a4d6-5ab1a2b6db74.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Tue, 10 Dec 2024 14:44:49 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5303</link>
      <guid>http://beta.w2solo.com/topics/5303</guid>
    </item>
    <item>
      <title>QQ 小程序已发布，但无法被搜索！</title>
      <description>&lt;h2 id=" 前言"&gt; 前言&lt;/h2&gt;
&lt;p&gt;我的 QQ 小程序在 2024 年 8 月就已经审核通过，上架后却一直无法被搜索到。打开后，再在 QQ 上下拉查看 “最近使用”，发现他出现一下又马上消失。&lt;/p&gt;

&lt;p&gt;上线是按正常流程走的，开发、备案、审核，也没有任何违规，后台也没收到说被封或异常的信息。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/1fc87eb5-a84c-4181-8948-4551d14892f6.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="排查"&gt;排查&lt;/h2&gt;
&lt;p&gt;难道是我名字（实用工具箱）问题，当我要去后台修改名字时，提示要重新备案。不过也让我想起之前我搜索的时候，别人也有用这名字，所以根本不是这个原因。&lt;/p&gt;

&lt;p&gt;会不会是后台哪里设置了，第一次玩 QQ 小程序后台，搞不好一开始的时候我乱点了什么。最后找啊找，终于在 “关联设置” 中找到了问题所在。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/4f509709-9113-4afc-82d7-02da14268efb.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="解决"&gt;解决&lt;/h2&gt;
&lt;p&gt;在 QQ 后台的设置下的 “关联设置” 里 “QQ 频道” 有一个 “仅允许在机器人服务中使用”，这一项给出的解释是 “打开后，QQ 小程序推荐页将不会展示此小程序”，没错，我勾选了。&lt;/p&gt;

&lt;p&gt;尴不尴尬，去掉后什么无法被搜索，什么在最近使用框里马上消失的问题，全部解决。所以我之前刚上架时没有自然流量也是因为这个，那我才放开小程序推荐，官方会不会就给推了啊，这个只能看后面几天的情况才能知道，但现在的我还是急需流量。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/0c7f82d7-febc-4375-ab91-77d56e4960d7.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="找流量"&gt;找流量&lt;/h2&gt;
&lt;p&gt;为什么着急找流量？因为 QQ 小程序的流量主开通不同于微信小程序，他的要求更高，必须连续 7 天内，每天的 UV 不能低于 100。&lt;/p&gt;

&lt;p&gt;虽然 700UV 也不多，但他不是累积的，过了 7 天没达量，前面的 UV 总数作废。在不清楚明天有没有自然流量的情况，我决定找人友链，就是我们在自己的小程序里互相跳转。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/9db3f61c-4eef-4952-9782-f022d7eb53f7.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="友链之路"&gt;友链之路&lt;/h2&gt;
&lt;p&gt;小程序友链，也就是小程序跳小程序，由于我的没有做后台管理，界面展示是写死的，加这个要改两个地方，一个是配置，一个是添加点击跳转事件。&lt;/p&gt;
&lt;h3 id="配置，只需在app.json中添加"&gt;配置，只需在 app.json 中添加&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"navigateToMiniProgramAppIdList": [
    "appId"
  ]
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="添加点击跳转事件"&gt;添加点击跳转事件&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qq.navigateToMiniProgram({
    appId: '1112309851',
    success(res) {
        // 跳转成功
    }
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="写在后面"&gt;写在后面&lt;/h2&gt;
&lt;p&gt;其实平台刚上线时，好像是 19 年还是 18 年，个人开发者只要一上架自己的小程序就能开通流量主。现在我的心态，借张伟名言：机会像雨点般打来, 而我却一一闪过。&lt;/p&gt;

&lt;p&gt;不过 QQ 小程序的应用场景还是很多元化的，群和频道，机器人里都能绑定，外加互助一下其实也很快，所以，大家要和我一起吗？&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/b3f35391-9244-480e-8c7d-624608d44e16.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Tue, 12 Nov 2024 20:56:54 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5231</link>
      <guid>http://beta.w2solo.com/topics/5231</guid>
    </item>
    <item>
      <title>鸿蒙 Next 实战：烟花模拟器</title>
      <description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;通过上一篇文章可以看出，要在鸿蒙应用中实现特别炫的特效还是比较复杂。动画固然重要，但如果在赶工期的情况下，大家都会优先业务，那有没有简单快速的方法呢？&lt;/p&gt;

&lt;p&gt;有的，也用像 Android 和 iOS 里 WebView 的方式，h5 的特效现在是应有尽有，把他嵌入鸿蒙 Next 应用里就可以，那如何在鸿蒙 Next 中使用 WebView 来实现电子烟花？&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/101/720/101720689-fba2ef9ffeb50e51" title="" alt="image.png"&gt;&lt;/p&gt;
&lt;h2 id="实现要点"&gt;实现要点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt; 组件拆解&lt;/li&gt;
&lt;li&gt; 资源引入&lt;/li&gt;
&lt;li&gt; 页面路由&lt;/li&gt;
&lt;li&gt; WebView&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/155/091/1550919059-0684fa6bbb73ce95" title="" alt="image.png"&gt;&lt;/p&gt;
&lt;h2 id="开始实践"&gt;开始实践&lt;/h2&gt;
&lt;p&gt;因为前面的木鱼和现在的烟花都是同一个小工具应用，公用组件的拆分、页面跳转和资源的引入全有涉及，所以就连同 WebView 一起总结一下。&lt;/p&gt;
&lt;h2 id="组件拆解"&gt;组件拆解&lt;/h2&gt;
&lt;p&gt;在 ArkUI 中，UI 显示的内容均为组件，由框架直接提供的称为系统组件，由开发者定义的称为自定义组件。这里我们将所有页面的导航拆分成一个公用组件，并定义为 HdNav.ets。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { router } from '@kit.ArkUI'

@Component
export struct HdNav {
  @StorageProp('topHeight')
  topHeight: number = 0
  @Prop
  title: string = 'hello world'
  @Prop
  hasBorder: boolean = false
  @Prop
  leftIcon: ResourceStr = $r('app.media.ic_common_back')
  @Prop
  rightIcon: ResourceStr = $r('sys.media.ohos_ic_public_more')
  @Prop
  showRightIcon: boolean = true
  @Prop
  iconColor: ResourceStr = $r('app.color.black')
  @Prop
  titleColor: string = '#131313'
  @BuilderParam
  menuBuilder: () =&amp;gt; void = this.defaultMenu

  @Builder
  defaultMenu() {

  }

  build() {
    Row({ space: 16 }) {
      Image(this.leftIcon)
        .size({ width: 24, height: 24 })
        .onClick(() =&amp;gt; router.back())
        .fillColor(this.iconColor)
      Row() {
        if (this.title) {
          Text(this.title)
            .fontWeight(600)
            .fontColor(this.titleColor)
            .layoutWeight(1)
            .textAlign(TextAlign.Center)
            .fontSize(18)
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
        }
      }
      .height(56)
      .layoutWeight(1)

      if (this.showRightIcon) {
        Image(this.rightIcon)
          .size({ width: 24, height: 24 })
          .objectFit(ImageFit.Contain)
          .bindMenu(this.menuBuilder)
      } else {
        Blank()
          .width(24)
      }
    }

    .padding({ left: 16, right: 16, top: this.topHeight })
    .height(56 + this.topHeight)
    .width('100%')
    .border({
      width: { bottom: this.hasBorder ? $r('app.float.common_border_width') : 0 },
      color: $r('app.color.common_gray_bg')
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="资源引入"&gt;资源引入&lt;/h2&gt;
&lt;p&gt;应用开发过程中，经常需要用到颜色、字体、间距、图片等资源，在不同的设备或配置中，这些资源的值可能不同。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;应用资源：借助资源文件能力，开发者在应用中自定义资源，自行管理这些资源在不同的设备或配置中的表现。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;系统资源：开发者直接使用系统预置的资源定义。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 引入resouces/base/media下的home_selected的图片
$r('app.media.home_selected')

# 导入resources/rawfile下的index.html文件
$rawfile("index.html")

# 获取resources/rawfile下的audio.mp3音频
await getContext(this).resourceManager.getRawFd("audio.mp3")
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="页面路由"&gt;页面路由&lt;/h2&gt;
&lt;p&gt;页面路由 router 根据页面的 uri 找到目标页面，从而实现跳转。以最基础的两个页面之间的跳转为例，具体实现步骤如下：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; 在 “Project“窗口，打开 src&amp;gt; main &amp;gt;ets，右键点击 pages 文件夹，创建一个页面。&lt;/li&gt;
&lt;li&gt; 在 resources/base/profile 下的 main_pages.json，新建一个 pages 中创建页面的文件名（注意大小写）。&lt;/li&gt;
&lt;li&gt; 调用 router.push () 路由到指定页面。&lt;/li&gt;
&lt;li&gt; 调用 router.back () 回到首页。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/161/065/1610655462-e340b77e6bdab6c6_fix732" title="" alt="ceadbddfd3f7b2b0cc2a128dcd9c18db_up-e8f95781e003d6125ef4ee2d38291b0a946.png"&gt;&lt;/p&gt;
&lt;h2 id="WebView"&gt;WebView&lt;/h2&gt;
&lt;p&gt;页面加载是 Web 组件的基本功能。根据页面加载数据来源可以分为三种常用场景，包括加载网络页面、加载本地页面、加载 HTML 格式的富文本数据。&lt;/p&gt;

&lt;p&gt;页面加载过程中，若涉及网络资源获取，需要配置 ohos.permission.INTERNET 网络访问权限，下面以本地静态文件的方法举例。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  将资源文件放置在应用的 resources/rawfile 目录下。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/287/264/2872649454-0e3ba1620d89bc8f_fix732" title="" alt="11b88fa1324dbc1938fd1626033f4ff5_up-9b71868068b6318c99729b9bd79b9c72445.png"&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  鸿蒙 Next 应用代码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import web_webview from '@ohos.web.webview';
import { HdNav } from '@mygames/basic';

@Entry
@Component
struct WebComponent {
  controller: web_webview.WebviewController = new web_webview.WebviewController();

  build() {
    Column() {
      HdNav({ title: '看烟花秀', showRightIcon: false, iconColor: $r('app.color.black') })

      Button('loadData')
        .onClick(() =&amp;gt; {
          try {
            this.controller.loadUrl($rawfile("index.html"));

          } catch (error) {
            console.error(`ErrorCode: ${error.code},  Message: ${error.message}`);
          }

        })
      // 组件创建时，加载www.example.com
      Web({ src: $rawfile("index.html"), controller: this.controller })
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;  烟花代码&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/118/121/1181218140-a4c3e0f5024f631e_fix732" title="" alt="5b2e80683a0bf5767b543b321b675e91_up-6744c6018ee686ff885e2d3fce4bde7c081.png"&gt;&lt;/p&gt;
&lt;h2 id="写在后面"&gt;写在后面&lt;/h2&gt;
&lt;p&gt;到这里鸿蒙 Next 应用实战暂告一段落了。但是鸿蒙系统提供了开箱即用的原生 AI 能力，更方便了我们开发者实现应用的快速智能化，所以，鸿蒙 Next 智能应用实战，待续～
&lt;img src="https://img.way2solo.com/photo/zero_dev/7744d964-d012-457f-a9fe-5576bcad96e9.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Tue, 08 Oct 2024 13:35:32 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5104</link>
      <guid>http://beta.w2solo.com/topics/5104</guid>
    </item>
    <item>
      <title>鸿蒙 Next 实战： 电子木鱼</title>
      <description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;正所谓：Hello Word 是程序员学任何一门语言的第一个程序实践。这其实也是一个不错的正反馈，那如何让学习鸿蒙 Next 更有成就感呢？下面就演示一下从零开发一个鸿蒙 Next 版的电子木鱼，主打就是一个抽象！&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/254/933/2549334873-98ee6ddb63bc01fc_fix732" title="" alt="92210410404e8ff27918f02e3d85cf17_up-0e821fc204618a9429123f0a852e11df614.png"&gt;&lt;/p&gt;
&lt;h2 id="实现要点"&gt;实现要点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt; 页面布局&lt;/li&gt;
&lt;li&gt; 木鱼点击&lt;/li&gt;
&lt;li&gt; 木鱼音效&lt;/li&gt;
&lt;li&gt; 动画特效&lt;/li&gt;
&lt;li&gt; 自定义弹窗&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/338/193/338193454-9b44c864b1337a0a_fix732" title="" alt="39c305f85ef328c3890d44df61de3f9e_up-2bbe0ef0a0f3df2842362470e5921f57641.jpg"&gt;&lt;/p&gt;
&lt;h2 id="开始实践"&gt;开始实践&lt;/h2&gt;&lt;h2 id="页面布局"&gt;页面布局&lt;/h2&gt;
&lt;p&gt;ArkTS 定义了声明式 UI 描述、自定义组件和动态扩展 UI 元素的能力，配合 ArkUI 开发框架中的系统组件及其相关的事件方法、属性方法等共同构成 UI 开发的主体。我们下面要完成的主要是一个木鱼和设置按钮、自动按钮。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build() {

Column() {
  HdNav({ title: '电子木鱼', showRightIcon: false, iconColor: $r('app.color.white'), titleColor: '#ffffff' })

  Row() {
    Text(this.woodenType[this.type] + '：'+ this.score).fontSize(22).fontColor("#ffffff").width('100%').textAlign(TextAlign.Center)
  }.width("100%").height("8%")

  Row() {
    Image($r('app.media.setting')).width(25).height(25).margin(16).onClick(() =&amp;gt; {
      if (this.dialogController != null) {
        this.dialogController.open()
      }
    })
  }.width('100%')

  Row() {
    Image($r('app.media.foreground')).width(40).height(40).margin({left:8,top:5})
  }.width('100%')
  .onClick(() =&amp;gt; {
    this.handlePopup = !this.handlePopup
  })
  .bindPopup(this.handlePopup, {
    message: '数据统计功能，正在完善中~',
  })

  Row() {
    if (this.isPresent) {
      Text(this.woodenType[this.type] + ': ' + this.woodenFishNum).fontSize(16).fontColor("#ffffff").width('100%').textAlign(TextAlign.Center)
        .transition(this.effect)
    }
  }.width('100%').height('25%')
  .alignItems(VerticalAlign.Top)

  Row() {
    Image($r('app.media.muyu'))
      .width(this.isZoomed == true ? this.targetWidth * 1.2 : this.targetWidth * 1)
      .height(this.isZoomed == true ? this.targetHeight * 1.2 : this.targetHeight * 1)
  }
  .width('100%')
  .height('25%')
  .alignItems(VerticalAlign.Center)
  .justifyContent(FlexAlign.Center)

  Row() {
    Toggle({ type: ToggleType.Switch })
      .onChange((isOn: boolean) =&amp;gt; {
        if(isOn) {
          promptAction.showToast({ message: 'auto is on.' })
        } else {
          promptAction.showToast({ message: 'auto is off.' })
        }
      })

    Text('自动' + this.woodenType[this.type]).fontSize(18).fontColor('#ffffff').height(40).margin({left: 10})

  }.width('100%').height('10%').justifyContent(FlexAlign.Center)

}
.height("100%")
.backgroundColor('rgba(0, 0, 0, 1.00)')

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="木鱼点击"&gt;木鱼点击&lt;/h2&gt;
&lt;p&gt;木鱼是一张图片，也就是给该图绑定一个点击事件，点击一次有三个动作需要执行：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  木鱼有放大的效果&lt;/li&gt;
&lt;li&gt;  有类似功德文字的飘动&lt;/li&gt;
&lt;li&gt;  功德数值的累加&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;而点击的时候要看到实时的效果，所以可以声明三个状态，通过 State 的修改，从而驱动 UI 更新，以下的 animateTo 是给域名的放大添加的一个平滑效果。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 积分
@State score: number = 0
// 积分文字
@State isPresent: boolean = false
// 木鱼是否放大
@State isZoomed: boolean = false

// 木鱼UI
Image($r('app.media.muyu'))
.width(this.isZoomed == true ? this.targetWidth * 1.2 : this.targetWidth * 1)
.height(this.isZoomed == true ? this.targetHeight * 1.2 : this.targetHeight * 1)
.onClick((event) =&amp;gt; {
animateTo({ curve: curves.springMotion() }, () =&amp;gt; {
  this.isZoomed = !this.isZoomed;

  if (this.isZoomed == true) {
    this.isPresent = true;
    this.score += this.woodenFishNum;
    this.onClickPlay();
  }
})

// 定时缩小/定时文字消失
setTimeout(() =&amp;gt; {this.isZoomed = false;}, 50);
setTimeout(() =&amp;gt; {this.isPresent = false}, 600);
})
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="木鱼音效"&gt;木鱼音效&lt;/h2&gt;
&lt;p&gt;木鱼音效是点击时的咚咚的声音，这里就要使用到 HarmonyOS Next 的音频服务。这里需要注意一点，项目运行预览无法播放，一定要模拟器或真机才可以调试音频的播放效果。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/174/807/1748078957-54216970590e78e7_fix732" title="" alt="a50716261bdfd14746bf196b89a808b9_up-957f2f2082d91c8fd3f7bdcd25ac19a7577.png"&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 销毁音效工具
  onClickDestroy= ()=&amp;gt;{
    AudioMgr.Ins().destroy();
    console.log('audio', 'destroy');
  }

  // 初始化音效工具
  onClickInit = ()=&amp;gt;{
    AudioMgr.Ins().init();
    console.log('audio', 'init');
  }

  // 播放指定音效
  onClickPlay = ()=&amp;gt;{
    AudioMgr.Ins().play();
    console.log('audio', 'playing');
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/906/743/90674303-644605593b43aaad_fix732" title="" alt="e095d6c6c7fd61ee09ad2e6750147361_up-bb7dc3e97e316f453c7f6a72aec07052dae.png"&gt;&lt;/p&gt;
&lt;h2 id="动画特效"&gt;动画特效&lt;/h2&gt;
&lt;p&gt;这里的动画效果主要是点击木鱼，从下网上飘出一个文字然后消失的特效。在鸿蒙中可以通过 TransitionEffect 方法添加效果，首先创建特效，然后再文字上挂载。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 上移入场特效
  private effect: object =
    TransitionEffect.OPACITY
      // 初始正常大小// 假设动画持续时间为500ms
      .combine(TransitionEffect.scale({ x: 1, y: 1 }).animation({ curve: curves.springMotion(0.6, 1.2), duration: 0 }))
       // 向上平移150单位// 与上一步同时开始
      .combine(TransitionEffect.translate({ x: 0, y: 400 }).animation({ curve: curves.springMotion(0.6, 1.2), duration: 10000, delay: 50 }))
       // 淡出至完全透明// 在平移结束后开始淡出
      .combine(TransitionEffect.opacity(0).animation({ curve: curves.springMotion(0.6, 1.2), duration: 1000, delay: 0 }));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/382/339/3823392715-053831381a9900f8_fix732" title="" alt="a38c10c34fdb93be33ba7ca5f1e4bd61_up-dbe42f5c89bf43d36dcc62ab8459986682a.png"&gt;&lt;/p&gt;
&lt;h2 id="自定义弹窗"&gt;自定义弹窗&lt;/h2&gt;
&lt;p&gt;经过前面布局，事件绑定，音效播放，一个简单的电子木鱼其实已经完成了。但是为了增添趣味和后期扩展，这里再加一个设置功能，通过按钮打开配置项弹窗，设置包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  类型选项 (功德、财运、桃花运等)&lt;/li&gt;
&lt;li&gt;  音效选项 (各种解压的音效素材)&lt;/li&gt;
&lt;li&gt;  皮肤管理 (木鱼的 UI 界面设置)&lt;/li&gt;
&lt;li&gt;  数值修改 (对展示的累加数值做任意修改)&lt;/li&gt;
&lt;li&gt;  其他 (是否关闭音效，是否自动点击等)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 弹窗层(UI开发-组件-自定义弹窗)
@CustomDialog
struct SettingDialog {
  controller?: CustomDialogController

  // 父子组件双向同步，文档见 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-link-V5
  @Link woodenFishType: number

  // 木鱼敲击的数值
  @Link woodenFishNum: number

  build() {
    Column() {

      Row() {
        Text('愿望：').fontSize(17).fontWeight(600)
        Radio({ value: '功德', group: 'word' }).checked(true).onChange((isChecked: boolean) =&amp;gt; {
          if(isChecked) {
            this.woodenFishType = 0
          }
        })
        Text('功德').fontSize(15)
        Radio({ value: '财富', group: 'word' }).onChange((isChecked: boolean) =&amp;gt; {
          if(isChecked) {
            this.woodenFishType = 1
          }
        })
        Text('财富').fontSize(15)
        Radio({ value: '桃花运', group: 'word' }).onChange((isChecked: boolean) =&amp;gt; {
          if(isChecked) {
            this.woodenFishType = 2
          }
        })
        Text('桃花运').fontSize(15)
      }
      .width('100%')
      .margin({bottom: 12})
      .justifyContent(FlexAlign.Start)

      Row() {
        Text('数值：').fontSize(16).fontWeight(600)
        TextInput({text:'1'}).type(InputType.Number).width(180).onChange((value: string) =&amp;gt; {
          this.woodenFishNum = parseInt(value)
        })
      }
      .width('100%')
      .margin({bottom: 12})
      .justifyContent(FlexAlign.Start)

      Row() {
        Text('音效：').fontSize(16).fontWeight(600)
        Toggle({ type: ToggleType.Switch })
      }
      .width('100%')
      .margin({bottom: 12})
      .justifyContent(FlexAlign.Start)

      Row() {
        Text('皮肤：').fontSize(16).fontWeight(600)
        Radio({ value: '默认', group: 'skin' }).checked(true)
        Text('木鱼').fontSize(15)
        Radio({ value: '悟空', group: 'skin' })
        Text('黑悟空').fontSize(15)
        Radio({ value: '典韦', group: 'skin' })
        Text('典韦').fontSize(15)
      }
      .width('100%')
      .margin({bottom: 12})
      .justifyContent(FlexAlign.Start)

    }.padding({top: 28, left: 15})

  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里需要注意的是：父子组件的数据传递。因为自定义弹窗和木鱼是两个不同的组件，而点击弹窗中的比如类型切换或修改的数值，全部要更新到木鱼组件的展示当中。&lt;/p&gt;

&lt;p&gt;当然鸿蒙也提供了 &lt;a href="/Link" class="user-mention" title="@Link"&gt;&lt;i&gt;@&lt;/i&gt;Link&lt;/a&gt; 装饰器，用于与其父组件中的数据源共享相同的值，可以结合上面代码和下方截图参考其用法。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/722/773/722773406-8b884045f9af81cd_fix732" title="" alt="682dc27d391be1c5be1c3f2f088dc353_up-c59691bbee82b725b86786632bf238bb60e.png"&gt;&lt;/p&gt;
&lt;h2 id="写在后面"&gt;写在后面&lt;/h2&gt;
&lt;p&gt;到这里，一个通用型的鸿蒙 Next 版电子木鱼就完成了。不管是组件交互还是布局都还好，唯一让我觉得不适应的是动画特效。
如果用这种方式实现电子烟花肯定不行，所以下次将换一种方法快速实现烟花秀，以及页面间的跳转，待更新～&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/zero_dev/e337a986-7ed7-4877-b531-d6393de70d4d.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Tue, 08 Oct 2024 10:33:26 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5103</link>
      <guid>http://beta.w2solo.com/topics/5103</guid>
    </item>
    <item>
      <title>鸿蒙 Next 实战： 环境搭建</title>
      <description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;作为独立开发者，如果我们错过了传统移动 App，和后起小程序的红利，那万物互联 + AI 的应用开发就得抓住了。&lt;/p&gt;

&lt;p&gt;虽然个人上架应用平台难易都差不多，但是鸿蒙生态当前正需要广大开发者参与，一旦上架，相比其他平台，流量扶持力度更大，变现能力也更容易。&lt;/p&gt;

&lt;p&gt;所以，我们可以先开发一些应用占个位置，后面再逐渐迭代完善；那么，第一步就先从搭建开发环境开始吧。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/215/704/2157045002-92c2b2f020c04ee2_fix732" title="" alt="b4e9d22450fabee5ca1f8ca70e9d36d2_up-19a09b604db11b5784d86b1c0571bd2b604.png"&gt;&lt;/p&gt;
&lt;h2 id="鸿蒙 Next 简介"&gt;鸿蒙 Next 简介&lt;/h2&gt;
&lt;p&gt;鸿蒙 Next，英文 HarmoneyOS Next，又叫纯血版鸿蒙，2023年8月4日开发者预览版，2024 年 6 月正式对外公布。鸿蒙 NEXT 采用了全鸿蒙内核，完成了对 Linux 内核的全面替换，并去掉了安卓开放源代码项目（AOSP）等代码，实现了真正的自主可控，他能支持华为及合作厂商的多种智能终端设备，包括手机、平板、智慧屏等等。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/370/244/3702443813-2bafc28d7fac28ca_fix732" title="" alt="381839e3421742c58c202b1dd6f1ba42_up-78d21199f2fe533f5f019684daaf9d1db40.png"&gt;&lt;/p&gt;
&lt;h3 id="运行环境要求"&gt;运行环境要求&lt;/h3&gt;
&lt;p&gt;针对开发 HarmonyOS 应用及元服务，华为基于 IntelliJ IDEA Community 开源版本打造了一个集成开发环境（IDE）——DevEco Studio，能将开发的应用和服务同时运行在 HarmonyOS 和 OpenHarmony 系统上，为保证 DevEco Studio 正常运行，建议您的电脑配置满足如下要求：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  操作系统：Windows10 64 位，内部版号大于 18363&lt;/li&gt;
&lt;li&gt;  内存：8GB 及以上&lt;/li&gt;
&lt;li&gt;  硬盘：100GB 及以上&lt;/li&gt;
&lt;li&gt;  分辨率：1280*800 像素及以上&lt;/li&gt;
&lt;li&gt;  其他： 开启了 Hyper-V 虚拟化&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/257/651/2576514724-869bc1ea7a17a4d7_fix732" title="" alt="6a5f38b993cafd355266129c9afeb1b6_up-a64efb47dbb23be6d6288635a5ad0b3b720.png"&gt;&lt;/p&gt;
&lt;h2 id="DevEco Studio"&gt;DevEco Studio&lt;/h2&gt;&lt;h3 id="下载"&gt;下载&lt;/h3&gt;
&lt;p&gt;进入 huawei 开发者平台下载，最好找 5.0 以上又不是最新版本就行。还有 DevEco Studio 支持 Windows 和 macOS 系统，但我本人用的是 Windows，所以就以 win 系统演示。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/180/632/1806329594-ecf864a76d7e3693_fix732" title="" alt="5d660e098929e5a165ec9895077988f7_up-640ec8644a5ffa7d95c657c0baf951ff562.png"&gt;&lt;/p&gt;
&lt;h3 id="安装"&gt;安装&lt;/h3&gt;
&lt;p&gt;下载完成后，双击下载的 “deveco-studio-xxxx.exe”，进入 DevEco Studio 安装向导。因为 DevEco Studio 提供开箱即用的开发体验，将 HarmonyOS SDK、Node.js、Hvigor、OHPM、模拟器平台等进行合一打包，几乎无需额外下载配置就能马上跑项目，但是要运行模拟器需要一点配置，比如 Windows 版本要大于 18363。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/427/197/4271971367-b4f561050ebe05ea_fix732" title="" alt="de060b31f6f4ee540cf9a854feda0c47_up-562424fbf414726c7ed0fb2a540cf7ef85b.png"&gt;&lt;/p&gt;
&lt;h3 id="模拟器设置"&gt;模拟器设置&lt;/h3&gt;
&lt;p&gt;DevEco Studio 提供预览、模拟器、真机三种方式查看项目的运行效果，但是给予的测试权限不一。最高的真机，目前需要搭载了鸿蒙 Next 的手机才行，且鸿蒙无法自己升级到 Next，所以折中的方法就是用模拟器。官方现在要求使用模拟器需申请，而且本地电脑开始了虚拟化技术 Hyper-V。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/310/867/3108673098-edf87300ca9029c1_fix732" title="" alt="f0f5d7d82bfed9e8937eaa86ad565cc6_up-1e899ba3be3ad6b4e0aa2b1b5454f49696b.png"&gt;
&lt;img src="https://image-static.segmentfault.com/155/933/1559338628-ee9e676e4b248264_fix732" title="" alt="86733862f6c963e8bdd76d0098b76a7a_up-a8d2f9776ad0205b548d910964b430e3215.png"&gt;
&lt;img src="https://image-static.segmentfault.com/396/656/3966567023-cb54447504ff6eb2_fix732" title="" alt="ac4580e8c53b75748f08790850feb6fb_up-93bf120dfbcefb6e964a3630dfab1696832.png"&gt;&lt;/p&gt;
&lt;h2 id="项目运行"&gt;项目运行&lt;/h2&gt;
&lt;p&gt;DevEco Studio 安装完成后，可以通过运行 Hello World 工程来验证环境设置是否正确。接下来以创建一个支持 Phone 设备的工程为例进行介绍。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/225/965/225965149-326d21d5a1832c98_fix732" title="" alt="6fee16843ff7417304f5a7d14c64638e_up-f3e75d7bb2920abb7e2ef703ba24b951f5d.png"&gt;&lt;/p&gt;
&lt;h3 id="项目结构"&gt;项目结构&lt;/h3&gt;
&lt;p&gt;可能当时为了适应主流开发语言，加上自己新出的 ArkTS 有三种工程类型可供选择，而我就是为 ArkTS 而来，所以以下和后面要做的应用也都是 ArkTS。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ArkTS 工程目录结构（Stage 模型）&lt;/li&gt;
&lt;li&gt;  C++ 工程目录结构（Stage 模型）&lt;/li&gt;
&lt;li&gt;  JS 工程目录结构（FA 模型）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://upload-images.jianshu.io/upload_images/25643248-9540ca9ee39614d2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" title="" alt="image.png"&gt;&lt;/p&gt;

&lt;p&gt;项目创建后，结构就是上图，而关于每个目录或文件的用法，就要去官方文档查看 “工程目录结构”，这里就略过进入到简单例子的演示。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/175/524/1755243927-c338ea540113b2bc_fix732" title="" alt="533b09646733e44d2819cd7472b121dd_up-86d4841b26214e15c602ff662049433595c.png"&gt;&lt;/p&gt;
&lt;h3 id="第一个 Hello World"&gt;第一个 Hello World&lt;/h3&gt;&lt;h4 id="创建页面"&gt;创建页面&lt;/h4&gt;
&lt;p&gt;在 “Project” 窗口，点击 “entry &amp;gt; src &amp;gt; main &amp;gt; ets &amp;gt; pages”，打开 “Index.ets” 文件，进行页面的编写。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Index.ets
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="预览效果"&gt;预览效果&lt;/h4&gt;
&lt;p&gt;在编辑窗口右上角的侧边工具栏，点击 Previewer，打开预览器。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://image-static.segmentfault.com/955/425/955425681-142e40c79f67e501_fix732" title="" alt="227d200fcdb59bf7d4ebe660c96d5e9f_up-1f37d0632491b467105d631a6253cb5101f.png"&gt;&lt;/p&gt;
&lt;h2 id="写在后面"&gt;写在后面&lt;/h2&gt;
&lt;p&gt;如果你有应用端相关的开发经验，上手鸿蒙应用还是比较容易的。而如果你像我一样是做后端的，或很少接触前端，那也可以跟着我一起代码实战，简单实现一个鸿蒙 Next 的电子木鱼和电子烟花秀，文章待更新～
&lt;img src="https://img.way2solo.com/photo/zero_dev/309eafff-a8c2-4707-8166-310ece436c0a.jpg?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>zero_dev</author>
      <pubDate>Mon, 07 Oct 2024 17:57:18 +0800</pubDate>
      <link>http://beta.w2solo.com/topics/5101</link>
      <guid>http://beta.w2solo.com/topics/5101</guid>
    </item>
  </channel>
</rss>
