0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙系统中制作demo特效组件

OpenHarmony技术社区 ? 来源:鸿蒙技术社区 ? 作者:木棉花潘颖琳 ? 2021-11-01 14:37 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

之前看到“粒子消散”的特效组件,于是就产生想法(自己也弄个特效组件应该挺有意思的)。

这个烟花特效可以添加到游戏胜利的界面中,可能还有其他应用场景哈哈。这也算是我做的第一个组件原创 demo 啦!

有三种模式可以选择,一种是图案只有五角星,一种是图案只有三角形,还有一种是图案既有五角星又有三角星。颜色有 10 种,还有背景音乐(自己 DIY 的烟花音效)!话不多说,开整!

创建一个空白的工程

DevEco Studio 下载安装成功后,打开 DevEco Studio,点击左上角的 File,点击 New,再选择 New Project,选择 Empty Ability。

然后点击 Next,给项目命名 Framework,选择设备类型 Phone,选择语言类型 JS 最后点击 Finish。

代码删除的部分如下:

在 entry>src>main>js>default>pages.index>index.hml 文件里把以下代码删掉:
class="title">
{{$t('strings.hello')}}{}

在 entry>src>main>js>default>pages.index>index.js 文件里把以下代码删掉:

title:""
onInit(){
this.title=this.$t('strings.world');
}

在 entry>src>main>js>default>pages.index>index.css 文件里把 container 部分以下的代码删掉。

布局设计

①index.hml

该组件是画布组件,画布的大小是整个屏幕,而按钮是显示画布上方的,所以要添加个栈组件,依次放入画布组件和按钮组件。

代码如下,注意这里画布组件添加了触摸事件 touchstartfunc,下文会讲解这步。

class="stack">
class="canvas"ref="canvas"@touchstart='touchstartfunc'>
"button"class="STAR"value="五角星"onclick="click_star"/>
"button"class="TRIANGLE"value="三角形"onclick="click_triangle"/>
"button"class="MIX"value="混合"onclick="click_mix"/>

②index.css

给画布组件和按钮组件设置属性,代码如下:

.canvas{
width:100%;
height:100%;
background-color:black;
}
.STAR{
width:80px;
height:38px;
font-size:20px;
background-color:blue;
border-color:blue;
text-color:aquamarine;
top:660px;
left:40px;
}
.TRIANGLE{
width:80px;
height:38px;
font-size:20px;
background-color:blue;
border-color:blue;
text-color:aquamarine;
top:660px;
left:150px;
}
.MIX{
width:80px;
height:38px;
font-size:20px;
background-color:blue;
border-color:blue;
text-color:aquamarine;
top:660px;
left:260px;
}

此时打开模拟器,你就能得到上面效果图左 1 图,接下来做功能实现部分。

绘制图案

①五角星

函数 draw_star 传的参数分别是烟花释放的圆心坐标,图案的颜色,图案移动的斜率,图案是否填充颜色。

定义的变量中,x 和 y 是图案中心的坐标,根据时间推移(会设定定时器,下文会讲)move_times 增加,图案会沿着传进来的斜率方向作直线移动,以达到烟花绽放的效果。

变量 a-h 都是为了便于绘制五角星的图案而设的公式参数值,全局变量 r_star 是五角星的边长,最后根据公式去绘制单个五角星图案。

index.js:先在 export default 上方定义变量。

varctx;
varmove_times=1;
varr_star=5;
varr_triangle=14;

然后在 export default 下方添加代码:

onShow(){
ctx=this.$refs.canvas.getContext('2d');
},

draw_Star(x_1,y_1,color,x_2,y_2,fill){
letx=x_1+move_times*x_2;
lety=y_1+move_times*y_2;
leta=r_star*Math.sin(Math.PI/10);
letb=r_star*Math.cos(Math.PI/10);
letc=(r_star+a)*Math.tan(Math.PI/10);
letd=(r_star+a)*Math.tan(Math.PI/5)-c;
lete=r_star*Math.sin(Math.PI/5);
letf=r_star*Math.cos(Math.PI/5);
letg=(r_star+2*a)*Math.cos(2*Math.PI/5);
leth=(r_star+2*a)*Math.sin(2*Math.PI/5);

ctx.lineWidth=1;
ctx.beginPath();
ctx.moveTo(x-r_star-a,y-c);
ctx.lineTo(x-a,y-c);
ctx.lineTo(x,y-b-c);
ctx.lineTo(x+a,y-c);
ctx.lineTo(x+a+r_star,y-c);
ctx.lineTo(x+a+r_star-f,y+e-c);
ctx.lineTo(x+a+g,y+h-c);
ctx.lineTo(x,y+d);
ctx.lineTo(x-a-g,y+h-c);
ctx.lineTo(x-a-r_star+f,y+e-c);
ctx.closePath();
ctx.stroke();
move_times=move_times+1;
},

②三角星

同样, draw_triangle 是绘制单个三角形并沿设定斜率移动的函数,函数的参数类型及作用与五角星的一致。

全局变量 r_triangle 为三角形的边长,代码如下:

draw_Triangle(x_1,y_1,color,x_2,y_2,fill){
letx=x_1+move_times*x_2;
lety=y_1+move_times*y_2;
ctx.lineWidth=1;
ctx.beginPath();
ctx.moveTo(x-r_triangle/2,y+Math.sqrt(3)*r_triangle/6);
ctx.lineTo(x,y-Math.sqrt(3)*r_triangle/3);
ctx.lineTo(x+r_triangle/2,y+Math.sqrt(3)*r_triangle/6);
ctx.closePath();
ctx.stroke();

move_times=move_times+1;
},

③图案的美化

设置了 10 种颜色的颜色字典,通过绘制图案函数 draw 中的参数 color 去控制颜色(黑色是作保护作用),颜色可通过单独设置数字 1-10 来选择,也可以通过随机数(1~10)去随机变化颜色。

颜色填充也是如此,1 为不填充,2 为填充,也可随机产生 1 或 2 来随机变化是否填充颜色。

vardrawcolors=[0,1,2,3,4,5,6,7,8,9,10];
constCOLORS={
"0":'black',
"1":"#FF2E10",
"2":"#FB8D15",
"3":"#F4ED1C",
"4":"#C5F31D",
"5":"#51F11F",
"6":"#18F8F8",
"7":"#1166FF",
"8":"#9833DD",
"9":"#FC14EB",
"10":"#C64A6A"
}

draw 函数中,在 ctx.lineWidth 下方,在 ctx.beginPath 上方添加代码:

ctx.strokeStyle=COLORS[drawcolors[color].toString()];

在 ctx.stroke 下方添加代码:

if(fill==2){
ctx.fillStyle=COLORS[drawcolors[color].toString()];
ctx.fill();
};

draw 开头的函数是绘制单个图案,接下来的 Draw 函数是绘制 8 个或 10 个图案围成圆形向外同速率扩展的图像,run 开头的函数是被循环的函数。

绘制烟花

①烟花的布局

绽放的烟花的形状是一个圆形,火花为单个图案。我设计了两种烟花绽放数量,一种是一个圆中有 8 个图案的,一种是一个圆中有 10 个图案的。

它们的斜率都通过数学公式定义好了(如下的全局变量所示),单个图案沿斜率方向每次移动的距离为全局变量 R 的数值。

varR=0.25;
vars=R*Math.cos(Math.PI/5);
vart=R*Math.sin(Math.PI/5);
varv=R*Math.cos(Math.PI/2.5);
varw=R*Math.sin(Math.PI/2.5);

Draw_Star_8(click_x,click_y){
this.draw_Star(click_x,click_y,1,-R,0,Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,2,-R/Math.sqrt(2),-R/Math.sqrt(2),Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,3,0,-R,Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,4,R/Math.sqrt(2),-R/Math.sqrt(2),Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,5,R,0,Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,6,R/Math.sqrt(2),R/Math.sqrt(2),Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,7,0,R,Math.floor(Math.random()*2+1));
this.draw_Star(click_x,click_y,8,-R/Math.sqrt(2),R/Math.sqrt(2),Math.floor(Math.random()*2+1));
},

Draw_Star_10(click_x,click_y,fill){
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),-R,0,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),-s,-t,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),-v,-w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),v,-w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),s,-t,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),R,0,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),s,t,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),v,w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),-v,w,fill);
this.draw_Star(click_x,click_y,Math.floor(Math.random()*10+1),-s,t,fill);
},

Draw_Triangle_8(click_x,click_y,fill){
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),-R,0,fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),-R/Math.sqrt(2),-R/Math.sqrt(2),fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),0,-R,fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),R/Math.sqrt(2),-R/Math.sqrt(2),fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),R,0,fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),R/Math.sqrt(2),R/Math.sqrt(2),fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),0,R,fill);
this.draw_Triangle(click_x,click_y,Math.floor(Math.random()*10+1),-R/Math.sqrt(2),R/Math.sqrt(2),fill);
},

Draw_Triangle_10(click_x,click_y){
this.draw_Triangle(click_x,click_y,1,-R,0,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,2,-s,-t,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,3,-v,-w,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,4,v,-w,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,5,s,-t,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,6,R,0,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,7,s,t,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,8,v,w,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,9,-v,w,Math.floor(Math.random()*2+1));
this.draw_Triangle(click_x,click_y,10,-s,t,Math.floor(Math.random()*2+1));
},

②火花的移动

上述提过一个 movetimes,火花的移动无非就是坐标的变化,通过设置一个定时器,循环绘制图案就能实现移动的效果,先构造一个被循环的函数 run_star(举五角星的实例,三角形同理;位置,美化等的参数随意)。

代码如下:

run_star(){
this.Draw_Star_10(200,300,1);
this.Draw_Star_10(150,200,2);
this.Draw_Star_8(300,218);
this.Draw_Star_8(110,380);
},

然后添加定时器:

vartimer_star=null;
vartimer_triangle=null;
vartimer_mix=null;

点击按钮“五角星”时会释放图案为五角星的烟花:

click_star(){
timer_star=setInterval(this.run_star,120);
},

此时,打开模拟器,你会看到图案移动了,但上一个图案没有清除:

05b09e9a-3ac5-11ec-82a9-dac502259ad0.png

所以要给被循环的函数添加一个清空操作(为了保护清空函数,要先在清空前加点东西),在 this.Draw 函数之前添加以下代码:

this.draw_Star(0,0,0,0,0,0);
ctx.clearRect(0,0,400,800);

③烟花的结束

按上述步骤下来,会发现烟花的圆形越来越大,最终出界。为了实现烟花的结束,可以根据 movetimes 的增加次数来控制烟花绽放范围的大小。

通过透明度的递减,最终透明度减为 0,图案消失:

varo=1;

在 draw 函数里的开头位置添加以下代码:

if((move_times>=230&&move_times<=330)){
o=o-0.01;
ctx.globalAlpha=o;
};

④烟花的循环绽放

在 draw 函数里的开头位置添加以下代码:

if(move_times==342){
o=1;
ctx.globalAlpha=o;
move_times=1;
};

同理可以设置“三角形”和“混合”的被循环函数:

run_triangle(){
this.draw_Triangle(0,0,0,0,0,0);
ctx.clearRect(0,0,400,800);
this.Draw_Triangle_8(200,300,1);
this.Draw_Triangle_8(150,200,2);
this.Draw_Triangle_10(300,218);
this.Draw_Triangle_10(110,380);
},

run_mix(){
this.draw_Triangle(0,0,0,0,0,0);
ctx.clearRect(0,0,400,800);
this.Draw_Triangle_8(200,300,1);
this.Draw_Star_10(150,200,2);
this.Draw_Triangle_10(300,218);
this.Draw_Star_8(110,380);
},

点击处绽放烟花

先获取点击处相对于画布组件左上角的坐标,然后作为新烟花绽放的圆心坐标传参,这里的 click_b1,click_b2 下文会讲解。

vartimer_click=null;
run_touch(){
if(click_b2==true){
this.draw_Star(x,y,0,0,0);
ctx.clearRect(0,0,400,800);
this.Draw_Star_10(x,y,1);
}
},

touchstartfunc(msg){
click_b1==true;
x=msg.touches[0].globalX;
y=msg.touches[0].globalY;
if(click_b1==true){
timer_click=setInterval(this.run_touch,120);
click_b1=false;
timer_click=null;
}
},

烟花图案的切换

通过设定布尔型变量来控制点击另一个按钮时,清空上一个按钮运行的定时器。

varstar_b=true;
varmix_b=true;
vartriangle_b=true;
varclick_b1=true;
varclick_b2=true;

click_star(){
click_b2=false;
clearInterval(timer_triangle);
timer_triangle=null;
clearInterval(timer_mix);
timer_mix=null;
ctx.clearRect(0,0,400,800);
if(star_b==true){
timer_star=setInterval(this.run_star,120);
star_b=false;
}
triangle_b=true;
mix_b=true;
},

click_triangle(){
click_b2=false;
clearInterval(timer_star);
timer_star=null;
clearInterval(timer_mix);
timer_mix=null;
ctx.clearRect(0,0,400,800);
if(triangle_b==true){
timer_triangle=setInterval(this.run_triangle,120);
triangle_b=false;
}
star_b=true;
mix_b=true;
},

click_mix(){
click_b2=false;
clearInterval(timer_star);
timer_star=null;
clearInterval(timer_triangle);
timer_triangle=null;
ctx.clearRect(0,0,400,800);
if(mix_b==true){
timer_mix=setInterval(this.run_mix,120);
mix_b=false;
}
star_b=true;
triangle_b=true;
},

背景音乐的添加

js 模板中添加音频可以去看我之前的文章:

https://harmonyos.51cto.com/posts/7802

index.hml:

<videoid='videoId'
src='/common/flr_5_1.mp3'
autoplay='true'
controls="false"
onfinish='finishCallback'>video>

index.js:

varvideo_b=true;

在 src/common/ 下加入音频文件:

finishCallback:function(){
if(video_b==true){
this.$element('videoId').start();
}
},

别忘了生命周期的设置,在应用启动时自动播放音频,在应用隐藏的时候暂停播放音频并清空所有定时器,在应用销毁时清空所有定时器,停止播放音频。

onShow(){
ctx=this.$refs.canvas.getContext('2d');
this.$element('videoId').start();
},

onHide(){
clearInterval(timer_star);
timer_star=null;
clearInterval(timer_triangle);
timer_triangle=null;
clearInterval(timer_mix);
timer_mix=null;
clearInterval(timer_click);
timer_click=null;
video_b=false;
this.$element('videoId').pause();
},

onDestroy(){
clearInterval(timer_star);
timer_star=null;
clearInterval(timer_triangle);
timer_triangle=null;
clearInterval(timer_mix);
timer_mix=null;
clearInterval(timer_click);
timer_click=null;
video_b=false;
this.$element('videoId').pause();
},

结语

以上就是我这次的小分享啦!自己的第一个 demo 开发,略微粗糙!更多资料请关注我们的项目 :Awesome-Harmony_木棉花。

https://gitee.com/hiharmonica/awesome-harmony-os-kapok

点击关注鸿蒙技术社区了解鸿蒙一手资讯 06343b4c-3ac5-11ec-82a9-dac502259ad0.gif

求分享

06343b4c-3ac5-11ec-82a9-dac502259ad0.gif

求点赞

06343b4c-3ac5-11ec-82a9-dac502259ad0.gif

求在看


原文标题:我做的第一款鸿蒙demo!

文章出处:【微信公众号:HarmonyOS技术社区】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    7190

    浏览量

    126214
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2642

    浏览量

    68395
  • HarmonyOS
    +关注

    关注

    80

    文章

    2130

    浏览量

    33665

原文标题:我做的第一款鸿蒙demo!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    鸿蒙非侵入式弹窗新解法,企查查正式开源“QuickDialog”弹窗组件

    近日,企查查将其自研的鸿蒙弹窗组件库“QuickDialog”开源,并上线至?OpenHarmony 三方库中心仓。这是鸿蒙生态首个支持“弹窗堆栈暂存能力”的非侵入式弹窗解决方案,凭借其灵活、高效
    的头像 发表于 07-31 10:40 ?221次阅读
    <b class='flag-5'>鸿蒙</b>非侵入式弹窗新解法,企查查正式开源“QuickDialog”弹窗<b class='flag-5'>组件</b>库

    【HarmonyOS 5】鸿蒙页面和组件生命周期函数

    【HarmonyOS 5】鸿蒙页面和组件生命周期函数 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、生命周期阶段: 创建阶段 build
    的头像 发表于 07-11 18:24 ?369次阅读

    【HarmonyOS 5】金融应用开发鸿蒙组件实践

    【HarmonyOS 5】金融应用开发鸿蒙组件实践 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、鸿
    的头像 发表于 07-11 18:20 ?371次阅读
    【HarmonyOS 5】金融应用开发<b class='flag-5'>鸿蒙</b><b class='flag-5'>组件</b>实践

    飞书开源“RTV”富文本组件 重塑鸿蒙应用富文本渲染体验

    近日,飞书正式将其自研的富文本组件库?RichTextVista(简称“RTV”)开源,并上线OpenHarmony?三方库中心仓。该组件以领先的性能、流畅的渲染体验与高度的开放性,为鸿蒙生态提供了
    的头像 发表于 07-11 15:20 ?222次阅读
    飞书开源“RTV”富文本<b class='flag-5'>组件</b> 重塑<b class='flag-5'>鸿蒙</b>应用富文本渲染体验

    鸿蒙Stage模型与FA模型详解

    【HarmonyOS 5】鸿蒙Stage模型与FA模型详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 在HarmonyOS
    的头像 发表于 07-07 11:50 ?272次阅读

    【HarmonyOS 5】鸿蒙的UIAbility详解(三)

    【HarmonyOS 5】鸿蒙的UIAbility详解(三) ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 本文是
    的头像 发表于 06-14 22:32 ?169次阅读

    鸿蒙Next实现瀑布流布局

    设计思路 鸿蒙 Next 的瀑布流布局可以通过自定义组件结合 Column、Row 等容器组件实现。其核心思路是将数据分成若干列,每列独立滚动展示,且根据数据项高度动态调整布局,以达到类似瀑布自然流动
    发表于 06-10 14:17

    HarmonyOS实战:组件化项目搭建

    前言 鸿蒙应用开发已经成为互联网新的风口,开发鸿蒙软件已经成为今年工作的核心目标。在软件开发过程,对于复杂度较大,功能较多的软件都会采用组件化项目架构,那么对于
    的头像 发表于 06-09 14:58 ?283次阅读
    HarmonyOS实战:<b class='flag-5'>组件</b>化项目搭建

    Kuikly鸿蒙版正式开源 —— 揭秘卓越性能适配之旅

    系统化工作,同时为了达到高性能、原生渲染、动态化等适配目标,进行了持续的探索和优化。其核心适配工作包括:对接鸿蒙UI系统,封装原子组件,对接事件
    发表于 06-04 16:46

    开源啦!!!基于鸿蒙ArkTS封装的图表组件《McCharts》,大家快来一起共创

    的地方请大家高抬贵手,宽容一下,谢谢。 这次主要是给大家带来一个重磅消息,就是我自己使用鸿蒙ArkTS语法开发的图表组件今日正式开源了。为什么?原因有两点吧! 鸿蒙是国产的操作系统
    发表于 03-15 15:21

    AIGC入门及鸿蒙入门

    JDK、配置SDK等。 3. 开发实践: 学习鸿蒙系统的架构和API,了解其组件化、分布式等特性。 通过官方文档和社区资源,学习和掌握鸿蒙应用的开发流程和技巧。 总结来说,AIGC作为
    发表于 01-13 10:32

    鸿蒙原生页面高性能解决方案上线OpenHarmony社区 助力打造高性能原生应用

    高性能鸿蒙原生应用。 Nodepool:优化页面滑动流畅性Nodepool旨在解决应用页面滑动卡顿问题。开发,相似页面因业务和代码差异,组件复用性差,引发卡顿、丢帧,影响用户体验。Nodepool通过
    发表于 01-02 18:00

    鸿蒙Flutter实战:14-现有Flutter 项目支持鸿蒙 II

    引言 在之前的文章鸿蒙Flutter实战:09-现有Flutter项目支持鸿蒙,介绍了如何改造项目,适配鸿蒙平台。 文中讲述了整体的理念和思路,本文更进一步,结合可实操的项目代码,详
    发表于 12-26 14:59

    鸿蒙原生开发手记:01-元服务开发

    简介 元服务是鸿蒙的一种轻量应用形态,无需下载,直接运行。类似于微信小程序,但与小程序不同的是,元服务更加轻量。 元服务使用原生开发,是系统级提供的,无论从易用性、性能、体验上,都要比小程序好
    发表于 11-14 17:28

    AIGC在视频内容制作的应用前景

    AIGC技术能够显著缩短视频内容的制作周期。通过AI算法,可以快速生成视频剪辑、特效、字幕和配乐等,减少人工操作的时间。例如,在短视频制作,AIGC技术可以自动找到最佳剪辑点、裁剪
    的头像 发表于 10-25 15:44 ?2004次阅读