- 累计送礼:
- 0 个
- 累计收礼:
- 0 个
TA的每日心情 | 开心 2025-2-4 02:05 |
---|
签到天数: 110 天 连续签到: 2 天 [LV.6]常住居民II

管理员
  
- VIP
- 6
- 卡币
- 10477
- OK点
- 16
- 推广点
- 0
- 同能卷
- 0
- 积分
- 13228


|
更新了简洁版
https://rpg.blue/forum.php?mod=viewthread&tid=487798&page=1&extra=#pid2936081
如果有android代码基础的话,我更推荐本篇的版本。
RPGMaker官方引擎制作的只有四个方向,这点对应使用摇杆操作体验还是有微小影响,思来想去,我最后只能是将左下、右下方向都指定为下方向,左上、右上都指定为上方向
前面发了贴请教关于存档问题,自己也去查了,结果还是无法突破 ...不过倒是对javascript和webview交互有了一点了解。
之前就想做个虚拟按键,可自己对javascript了解不深,就开始学习,前几天跟着大佬xjzsq( https://rpg.blue/?2631080)的教程学习完。非常感谢!!!由此产生此篇。
第一次写教程,有不妥的地方请尽情提建议。
有了点这些基础,我就想直接用android层做虚拟键,只要去调用javascript事件就行了!然后我主要用得是java语言,编译器是AS,所以需要一点android开发基础...
如果完全不懂android开发估计不好看明白,但你也可以尝试一下,多一门手艺也不是坏事...
上效果
下面说教程吧:
1、解压后 把 文件添加到包内(原作者下载地址(应该?我发现了很多相似的O(∩_∩)O哈哈~)
https://download.csdn.net/download/weixin_39840650/11489681?utm_source=bbsseo
这个主要是绘制摇杆的自定义组件
2、将解压后的attr文件复制到value文件夹中,这个主要是用来设置摇杆样式的,如果有P好的摇杆图可以在这设置,然后在布局中调用,如果没有图片,那么就会参考颜色值来绘制摇杆
3、在布局文件中调用,就是在你创建webview组件的那个文件里创建摇杆view类,至于如何布局应该不用我说了吧
4、在MainActivity中添加代码 实例化view什么的大家应该都会,这里就展示需要添加的部分
JAVA 代码 下载
- mRockerView.setOnShakeListener(DIRECTION_8, new RockerViewtwo.OnShakeListener(){
- @Override
- publicvoid onStart(){
- }
- @Override
- publicvoid direction(RockerViewtwo.Direction direction){
- if(direction == RockerViewtwo.Direction.DIRECTION_CENTER){
- Log.e("_now9", "当前方向:中心");
- goiuout();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_DOWN){
- Log.e("_now8", "当前方向:下");
- goiuout();
- goiudown();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_LEFT){
- Log.e("_now7", "当前方向:左");
- goiuout();
- goiuleft();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_UP){
- Log.e("_now6", "当前方向:上");
- goiuout();
- goiuup();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_RIGHT){
- Log.e("_now5", "当前方向:右");
- goiuout();
- goiuright();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_DOWN_LEFT){
- Log.e("_now4", "当前方向:左下");
- // goiuleft();
- goiuout();
- goiudown();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_DOWN_RIGHT){
- Log.e("_now3", "当前方向:右下");
- // goiuright();
- goiuout();
- goiudown();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_UP_LEFT){
- Log.e("_now2", "当前方向:左上");
- // goiuleft();
- goiuout();
- goiuup();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_UP_RIGHT){
- Log.e("_now1", "当前方向:右上");
- // goiuright();
- goiuout();
- goiuup();
- }
- }
- @Override
- publicvoid onFinish(){
- }
- });
- mRockerView.setOnAngleChangeListener(new RockerViewtwo.OnAngleChangeListener(){
- @Override
- publicvoid onStart(){
- }
- @Override
- publicvoid angle(double angle){
- Log.e("_now10", "当前角度:" + angle);
- }
- @Override
- publicvoid onFinish(){
- }
- });
- mRockerView.setOnDistanceLevelListener(new RockerViewtwo.OnDistanceLevelListener(){
- @Override
- publicvoid onDistanceLevel(int level){
- Log.e("_now11", "当前距离级别:" + level);
- }
- });
- ublic staticvoid goiuout(){
- gameWebView.loadUrl("javascript:downgetout()");
- }
- publicstaticvoid goiuleft(){
- gameWebView.loadUrl("javascript:downleft()");
- }
- publicstaticvoid goiuup(){
- gameWebView.loadUrl("javascript:downup()");
- }
- publicstaticvoid goiudown(){
- gameWebView.loadUrl("javascript:downdrow()");
- }
- publicstaticvoid goiuright(){
- gameWebView.loadUrl("javascript:downright()");
- }
- publicstaticvoid goiuok(){
- gameWebView.loadUrl("javascript:downok()");
- }
- publicstaticvoid goiuesc(){
- gameWebView.loadUrl("javascript:downesc()");
- }
复制代码
5、既然是交互,下面就是在javascript上操作了
打开游戏文件index.html文件,在body标签内、插件引用最后处添加下面代码
JAVASCRIPT 代码 下载
- function downleft(){
- Input._currentState['left']=true
- }
- function downright(){
- Input._currentState['right']=true
- }
- function downup(){
- Input._currentState['up']=true
- }
- function downdrow(){
- Input._currentState['down']=true
- }
- function downok(){
- Input._currentState['ok']=true
- }
- function downesc(){
- Input._currentState['escape']=true
- }
- function downgetout(){
- Input._currentState['up']=false
- Input._currentState['right']=false
- Input._currentState['down']=false
- Input._currentState['left']=false
- Input._currentState['ok']=false
- Input._currentState['escape']=false
- }
复制代码
补全一下MainActivity.java吧,方便对上面第四条出现的代码进行查询:
MainActivity.java:上面第四条是该文件的节选,其实摇杆核心就是第四条的代码
JAVA 代码 下载
- package com.example.myhtmltwo;
- import static com.example.myhtmltwo.RockerViewtwo.DirectionMode.DIRECTION_8;
- import android.Manifest;
- import android.app.AlertDialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.content.res.Resources;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.drawable.Drawable;
- import android.net.Uri;
- import android.os.Build;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.Handler;
- import android.os.Message;
- import android.provider.Settings;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.Window;
- import android.view.WindowManager;
- import android.webkit.WebChromeClient;
- import android.webkit.WebResourceRequest;
- import android.webkit.WebResourceResponse;
- import android.webkit.WebSettings;
- import android.webkit.WebView;
- import android.webkit.WebViewClient;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
- import androidx.annotation.NonNull;
- import androidx.annotation.RequiresApi;
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.constraintlayout.widget.ConstraintLayout;
- import androidx.core.app.ActivityCompat;
- import androidx.webkit.WebViewAssetLoader;
- import java.io.InputStream;
- /**
- * @author HY
- */
- publicclass MainActivity extends AppCompatActivity {
- /**
- * 动画控件imgview
- */
- LinearLayout ani;
- TextView loadtxt;
- RockerViewtwo mRockerView;
- /**
- * game路径
- */
- String gameUrl;
- /**
- * 承载网页控件
- */
- publicstatic WebView gameWebView;
- @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
- @Override
- protectedvoid onCreate(Bundle savedInstanceState){
- super.onCreate(savedInstanceState);
- /**
- * 去除标题
- */
- supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
- /**
- * 去掉信息栏
- */
- this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- setContentView(R.layout.activity_main);
- showCamera();
- Bundle bundle = this.getIntent().getExtras();
- gameUrl = bundle.getString("gamePath");
- /**
- * 实例化动画控件
- */
- ani = findViewById(R.id.imgview);
- loadtxt = findViewById(R.id.loadtxt);
- /**
- * 加载网页
- */
- htmls();
- /**
- * 动画
- */
- loadAmi();
- }
- publicvoid showCamera(){
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
- if(!Environment.isExternalStorageManager()){
- androidx.appcompat.app.AlertDialog.Builder ad = new androidx.appcompat.app.AlertDialog.Builder(MainActivity.this);
- ad.setMessage("由于Android11及以上系统限制需要对软件进行授权,请开启权限")
- .setCancelable(false)
- .setPositiveButton("前往开启", new DialogInterface.OnClickListener(){
- @Override
- publicvoid onClick(DialogInterface dialogInterface, int i){
- Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
- intent.setData(Uri.parse("package:" + MainActivity.this.getPackageName()));
- startActivityForResult(intent, 98);
- }
- })
- .setNegativeButton("取消", new DialogInterface.OnClickListener(){
- @Override
- publicvoid onClick(DialogInterface dialogInterface, int i){
- }
- }).show();
- }
- }
- String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
- ActivityCompat.requestPermissions(MainActivity.this, permissions, 520);
- }
- @Override
- publicvoid onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- switch(requestCode){
- case520:
- if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
- Log.e("申请:", "成功!!");
- }else{
- finish();
- }
- break;
- }
- }
- /**
- * 加载网页
- */
- RemoteSurfaceView remoteSurfaceView;
- RelativeLayout.LayoutParams params;
- @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
- publicvoid htmls(){
- /**
- * 实例化WebView
- */
- mRockerView = (RockerViewtwo) findViewById(R.id.roview);
- Button gsq = findViewById(R.id.gsq);
- Button gsq2 = findViewById(R.id.gsq2);
- gameWebView = findViewById(R.id.gameWebView);
- Log.e("_now", "当前模式setOnShakeListener:方向有改变时回调;8个方向");
- mRockerView.setOnShakeListener(DIRECTION_8, new RockerViewtwo.OnShakeListener(){
- @Override
- publicvoid onStart(){
- }
- @Override
- publicvoid direction(RockerViewtwo.Direction direction){
- if(direction == RockerViewtwo.Direction.DIRECTION_CENTER){
- Log.e("_now9", "当前方向:中心");
- goiuout();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_DOWN){
- Log.e("_now8", "当前方向:下");
- goiuout();
- goiudown();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_LEFT){
- Log.e("_now7", "当前方向:左");
- goiuout();
- goiuleft();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_UP){
- Log.e("_now6", "当前方向:上");
- goiuout();
- goiuup();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_RIGHT){
- Log.e("_now5", "当前方向:右");
- goiuout();
- goiuright();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_DOWN_LEFT){
- Log.e("_now4", "当前方向:左下");
- // goiuleft();
- goiuout();
- goiudown();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_DOWN_RIGHT){
- Log.e("_now3", "当前方向:右下");
- // goiuright();
- goiuout();
- goiudown();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_UP_LEFT){
- Log.e("_now2", "当前方向:左上");
- // goiuleft();
- goiuout();
- goiuup();
- }elseif(direction == RockerViewtwo.Direction.DIRECTION_UP_RIGHT){
- Log.e("_now1", "当前方向:右上");
- // goiuright();
- goiuout();
- goiuup();
- }
- }
- @Override
- publicvoid onFinish(){
- }
- });
- mRockerView.setOnAngleChangeListener(new RockerViewtwo.OnAngleChangeListener(){
- @Override
- publicvoid onStart(){
- }
- @Override
- publicvoid angle(double angle){
- Log.e("_now10", "当前角度:" + angle);
- }
- @Override
- publicvoid onFinish(){
- }
- });
- mRockerView.setOnDistanceLevelListener(new RockerViewtwo.OnDistanceLevelListener(){
- @Override
- publicvoid onDistanceLevel(int level){
- Log.e("_now11", "当前距离级别:" + level);
- }
- });
- Resources resources = MainActivity.this.getResources();
- Drawable qxrd = resources.getDrawable(R.drawable.qxrd);
- Drawable qx = resources.getDrawable(R.drawable.qx);
- Drawable qdrd = resources.getDrawable(R.drawable.qdrd);
- Drawable qd = resources.getDrawable(R.drawable.qd);
- gsq.setOnTouchListener(newView.OnTouchListener(){
- @Override
- publicboolean onTouch(View v, MotionEvent event){
- int action = event.getAction();
- if(action == MotionEvent.ACTION_DOWN){
- gsq.setBackground(qxrd);
- gameWebView.loadUrl("javascript:downesc()");
- }elseif(action == MotionEvent.ACTION_UP){
- gsq.setBackground(qx);
- gameWebView.loadUrl("javascript:downgetout()");
- }
- returnfalse;
- }
- });
- gsq2.setOnTouchListener(newView.OnTouchListener(){
- @Override
- publicboolean onTouch(View v, MotionEvent event){
- int action = event.getAction();
- if(action == MotionEvent.ACTION_DOWN){
- gsq2.setBackground(qdrd);
- gameWebView.loadUrl("javascript:downok()");
- }elseif(action == MotionEvent.ACTION_UP){
- gsq2.setBackground(qd);
- gameWebView.loadUrl("javascript:downgetout()");
- }
- returnfalse;
- }
- });
- // gsq2.setOnClickListener(v -> {
- // gameWebView.loadUrl("javascript:downok()");
- // });
- /**
- * 清除缓存
- */
- gameWebView.clearCache(true);
- /**
- * 实例化WebView配置管理类
- */
- WebSettings settings = gameWebView.getSettings();
- /**
- * 解决跨域
- */
- settings.setAllowFileAccessFromFileURLs(true);
- /**
- *启用Dom存储
- */
- settings.setDomStorageEnabled(true);
- /**
- *允许加载js文件
- */
- settings.setJavaScriptEnabled(true);
- /**
- * 支持缩放
- */
- settings.setSupportZoom(true);
- /**
- * 设置横屏
- */
- // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- /**
- * 页面事件响应
- */
- gameWebView.setWebChromeClient(new WebChromeClient(){
- @Override
- publicvoid onProgressChanged(WebView view, int newProgress){
- super.onProgressChanged(view, newProgress);
- if(newProgress == 100){
- // loadtxt.setVisibility(View.GONE);
- // ani.setVisibility(View.GONE);
- }else{
- loadtxt.setVisibility(View.VISIBLE);
- ani.setVisibility(View.VISIBLE);
- }
- }
- });
- /**
- * 判断SDK版本
- * SDK版本为21才可使用方法WebViewAssetLoader
- * 否则
- */
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
- final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
- /**
- * html项目存放路径,一般是assets
- */
- .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
- /**
- * html引用的资源文件路径 ,一般是跟随html存放于assets
- */
- .addPathHandler("/assets/", new WebViewAssetLoader.ResourcesPathHandler(this))
- .build();
- /**
- *与页面的交互
- */
- gameWebView.setWebViewClient(new WebViewClient(){
- @Override
- publicvoid onPageFinished(WebView view, String url){
- loadtxt.setVisibility(View.GONE);
- ani.setVisibility(View.GONE);
- super.onPageFinished(view, url);
- }
- @Override
- public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request){
- return assetLoader.shouldInterceptRequest(request.getUrl());
- }
- });
- gameWebView.addJavascriptInterface(new AndroidtoJs(this), "JH");
- gameWebView.loadUrl("https://appassets.androidplatform.net/assets/" + gameUrl);
- }else{
- gameWebView.setWebViewClient(new WebViewClient(){
- @Override
- publicvoid onPageFinished(WebView view, String url){
- loadtxt.setVisibility(View.GONE);
- ani.setVisibility(View.GONE);
- super.onPageFinished(view, url);
- }
- });
- gameWebView.loadUrl("file:///android_asset/" + gameUrl);
- }
- }
- publicstaticvoid goiuout(){
- gameWebView.loadUrl("javascript:downgetout()");
- }
- publicstaticvoid goiuleft(){
- gameWebView.loadUrl("javascript:downleft()");
- }
- publicstaticvoid goiuup(){
- gameWebView.loadUrl("javascript:downup()");
- }
- publicstaticvoid goiudown(){
- gameWebView.loadUrl("javascript:downdrow()");
- }
- publicstaticvoid goiuright(){
- gameWebView.loadUrl("javascript:downright()");
- }
- publicstaticvoid goiuok(){
- gameWebView.loadUrl("javascript:downok()");
- }
- publicstaticvoid goiuesc(){
- gameWebView.loadUrl("javascript:downesc()");
- }
- private ImageView myImageView, myImageView2, myImageView3, myImageView4;
- private Handler myHandler;//定义线程运行标识
- privateBoolean iswalking = true;
- class myThread extendsThread{
- @Override
- publicvoid run(){
- int what = 1;
- while(iswalking){
- myHandler.sendEmptyMessage((what++) % 4);//每次生成0-3间依次增加的的数字,用来充当图片数组的下标。
- try{
- Thread.sleep(250);//每250毫秒睡眠一次
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- }
- }
- }
- public Bitmap BitmapClipBitmap(Bitmap bitmap, int x, int y, int w, int h){
- return Bitmap.createBitmap(bitmap, x, y, w, h);
- }
- public Bitmap ReadBitmap(Context context, int resId){
- BitmapFactory.Options opt = new BitmapFactory.Options();
- opt.inPreferredConfig = Bitmap.Config.RGB_565;
- opt.inPurgeable = true;
- opt.inInputShareable = true;
- //图片的输入流
- InputStream is = context.getResources().openRawResource(resId);
- return BitmapFactory.decodeStream(is, null, opt);
- }
- /**
- * 加载动画
- */
- publicvoid loadAmi(){
- finalint ANIM_COUNT_X = 4, ANIM_COUNT_Y = 4, ANIM_DOWN = 0, ANIM_LEFT = 1, ANIM_RIGHT = 2, ANIM_UP = 3;
- Context context = getApplicationContext();//获取Context
- Bitmap testmap = ReadBitmap(context, R.drawable.girl);
- final Bitmap[][] bitmap = new Bitmap[ANIM_COUNT_X][ANIM_COUNT_Y]; //建立4x4二维数组用来存储4个角度的图片
- int tileWidth = testmap.getWidth() / ANIM_COUNT_X;
- int tileHeight = testmap.getHeight() / ANIM_COUNT_Y;
- int i = 0, x = 0, y = 0;
- for(i = 0; i < ANIM_COUNT_Y; i++){
- y = 0;
- bitmap[ANIM_DOWN][i] = BitmapClipBitmap(testmap, x, y, tileWidth, tileHeight);
- y += tileHeight;
- bitmap[ANIM_LEFT][i] = BitmapClipBitmap(testmap, x, y, tileWidth, tileHeight);
- y += tileHeight;
- bitmap[ANIM_RIGHT][i] = BitmapClipBitmap(testmap, x, y, tileWidth, tileHeight);
- y += tileHeight;
- bitmap[ANIM_UP][i] = BitmapClipBitmap(testmap, x, y, tileWidth, tileHeight);
- x += tileWidth;
- // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- //设置屏幕为横向
- myImageView = (ImageView) findViewById(R.id.im1);
- myImageView2 = (ImageView) findViewById(R.id.im2);
- myImageView3 = (ImageView) findViewById(R.id.im3);
- myImageView4 = (ImageView) findViewById(R.id.im4);
- myHandler = new Handler(){//实例化Handler对象
- @Override
- publicvoid handleMessage(Message msg){//接收消息
- super.handleMessage(msg);
- myImageView.setImageBitmap(bitmap[ANIM_UP][msg.what]);//设置ImageView中所要加载的位图
- myImageView2.setImageBitmap(bitmap[ANIM_UP][msg.what]);
- myImageView3.setImageBitmap(bitmap[ANIM_RIGHT][msg.what]);
- myImageView4.setImageBitmap(bitmap[ANIM_RIGHT][msg.what]);
- }
- };
- new myThread().start();
- }
- }
- @Override
- protectedvoid onDestroy(){
- super.onDestroy();
- }
- /**
- * 退出
- */
- publicvoid exit(){
- finish();//退出,但是进程仍在
- android.os.Process.killProcess(android.os.Process.myPid());
- }
- /**
- * 返回键按下时退出
- *
- * @param keyCode
- * @param event
- * @return
- */
- @Override
- publicboolean onKeyDown(int keyCode, KeyEvent event){
- if(keyCode == KeyEvent.KEYCODE_BACK){
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage("是否退出应用?");
- builder.setTitle("退出");
- /**
- * setIcon方法
- * 必须设置了setTitleicon才有效
- */
- builder.setIcon(R.mipmap.ic_launcher);
- builder.setPositiveButton("退出", new DialogInterface.OnClickListener(){
- @Override
- publicvoid onClick(DialogInterface arg0, int arg1){
- exit();
- }
- });
- builder.setNegativeButton("取消", new DialogInterface.OnClickListener(){
- @Override
- publicvoid onClick(DialogInterface arg0, int arg1){
- }
- });
- builder.show();
- returntrue;
- }
- returnsuper.onKeyDown(keyCode, event);
- }
- }
复制代码
确定和取消就是两个按钮加上图片,然后调用javascript内的方法即可
到此,算是完成了吧
最后再次感谢用爱发电出教程的各位大佬,感谢感谢!!!
然后就是国内android厂家各种对android进行自己的定制,保不准哪些手机可能会有bug什么的,我在vivo测试是没问题的,欢迎测试。
最后的最后我把自己的工程文件和构筑好的apk分享下,如果能帮到你是最好的。
项目文件:
链接: https://pan.baidu.com/s/1Xmp3cfbPnkm7DZsqrc2_MQ
提取码:5ppu
--来自百度网盘超级会员V4的分享
APK:
链接: https://pan.baidu.com/s/1r_Gc0bUuLXRstEI626Yc3A
提取码:g0an
--来自百度网盘超级会员V4的分享
本帖来自P1论坛作者haiyin,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址: https://rpg.blue/forum.php?mod=viewthread&tid=487782 若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|