精华内容
下载资源
问答
  • android studio游戏摇杆开发教程,仿王者荣耀摇杆

    万次阅读 多人点赞 2018-06-16 02:48:42
    经过几天的思考已完美解决所有问题,下面就和大家分享下这个摇杆的开发思路(此教程不包含游戏源码) 若有不正之处,请多多谅解并欢迎指正。 首先这个摇杆要用到较多的数学知识,小编的数学特别烂也就高中水平吧 ...

    李子果 原创。。。

    最近在做一个山寨版的王者荣耀,刚开始做的时候毫无头绪 摇杆的多点触控做的特别烂

    经过几天的思考已完美解决所有问题,下面就和大家分享下这个摇杆的开发思路(此教程不包含游戏源码)

    若有不正之处,请多多谅解并欢迎指正。

    首先这个摇杆要用到较多的数学知识,小编的数学特别烂也就高中水平吧

    我们这个摇杆一共就五个按钮,一个移动摇杆、三个技能摇杆和一个普通攻击按钮

    最终效果

    好了废话少说让我们开始吧

    新建一个项目

    建好项目之后,我们先新建一个类叫做“画”。也是我们的主View

    修改Hua.java的代码

    public class Hua extends RelativeLayout implements Runnable{ //继承RelativeLayout 实现Runnable接口
    
        private Paint p;//画笔
    
        public Hua(Context context) {
            super(context);
            p=new Paint();
            setBackgroundColor(Color.BLACK);//背景颜色设为黑色
        }
    
        @Override
        protected void onDraw(Canvas g) {//重写onDraw方法
            super.onDraw(g);
        }
    
        @Override
        public void run() {
    
        }
    }

    接下来我们做移动摇杆

     

    我们要准备一张图片(待会我会把图片都丢在附件里)

     

    首先用ps画一个这样半透明的圆ps部分就不做教程了

    把背景隐藏掉 保存为png格式

     

    把我们刚刚制作的图片添加进来

    先新建一个类 my.java

    public class my { //这个类当一个全局变量使用
        public static int w,h;//屏幕的宽高
        public static float bili;
        public static MainActivity main;
        public static RectF re=new RectF();
        public static int ontouchAlpha=100;//触控区透明度0-255 0为透明,为了测试我们先设为100
    }

    修改 MainActivity 的代码

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            my.main=this;
            getSupportActionBar().hide();//隐藏标题栏
            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏 隐藏状态栏
            //判断当前是否横屏 如果不是就设为横屏,设为横屏之后会自动调用onCreate方法
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                //获取屏幕的宽高
                DisplayMetrics dis = getResources().getDisplayMetrics();
                my.w = dis.widthPixels;
                my.h = dis.heightPixels;
                //获取屏幕分辨率和1920*1080的比例 以便适应不同大小的屏幕
                my.bili = (float) (Math.sqrt(my.w * my.h) / Math.sqrt(1920 * 1080));
                setContentView(new Hua(this));
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 横屏
            }
        }
    }

    新建类 Move.java

    package com.yaogan.liziguo.yaogan;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    
    /**
     * Created by Liziguo on 2018/6/15.
     */
    
    public class Move {
        private float x1,y1;//按下时的坐标 大圆
        private float x2,y2;//移动后的坐标 小圆
        private final float r1,r2;//r1大圆的半径 r2小圆的半径
        public float angle;//x1y1指向x2y2的角度 弧度制
        public boolean down=false;//判断是否被按下
        public boolean in=false;//判断小圆是否在大圆里面,简单的说就是防止小圆被脱太远
        public boolean move=false;//判断手指按下后是否移动(MY实际开发中用到,该教程用不到此变量)
        public Bitmap img;//大圆小圆的图片
    
        public Move(){
            r1 = 480 * 0.5f * my.bili;//乘上一个比例 适应不同大小的屏幕
            r2 = 300 * 0.5f * my.bili;
            img= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.yaogan);//初始化摇杆图片
        }
    
        public void down(float xx,float yy){ //摇杆按下后的操作
            if(xx<r1) x1=r1;
            else x1 = xx;
    
            if(my.h-yy<r1) y1=my.h-r1;
            else y1 = yy;
            //上面的代码是防止按下的位置太靠近屏幕边缘
            //跟x1=xx;y1=yy;区别不大,待会可以改成x1=xx;y1=yy;看看效果有什么不同
            down=true;
        }
        public void move(float xx,float yy){ //按下摇杆后移动的操作
            angle=getAngle(xx,yy);
            in=in(xx, yy);
            move=isMove(xx,yy);
            if (!in) {
                //下面会做解释
                xx= (float) (x1+ Math.sin(angle)*r1*0.7f);
                yy= (float) (y1+ Math.cos(angle)*r1*0.7f);
            }
            x2=xx;
            y2=yy;
        }
        public void up(){ //松开后的操作
            down=false;
        }
    
        public float getAngle(float xx,float yy){ //获取x1y1指向x2y2的角度
            double angle,k;
            if (y1==yy)//斜率不存在时
                if (x1 > xx)//判断x1指向x2的方向
                    angle=-Math.PI/2;
                else
                    angle=Math.PI/2;
            else{
                k=(x1-xx)/(y1-yy); //两点的坐标求斜率,至于为什么是(x1-x2)/(y1-y2)不是(y1-y2)/(x1-x2)待会我们再做解释
                if (y1 > yy) {//判断x1y1指向x2y2的方向
                    // 用反tan求角度 这个高中好像没学过 既然Math类已经帮我们封装好了就直接拿来用吧
                    angle=Math.atan(k) + Math.PI;
                } else {
                    angle=Math.atan(k);
                }
                //这段可写可不写 让计算出来的角度属于-PI/2到PI/2
                if(angle>Math.PI)
                    angle-=Math.PI*2;
                else if(angle<-Math.PI)
                    angle+=Math.PI*2;
            }
            return (float) angle;
        }
    
        public boolean in(float xx, float yy) { //防止小圆被脱太远 拖动范围不超出r1的70%
            double r = Math.sqrt((x1 - xx) * (x1 - xx) + (y1 - yy) * (y1 - yy));//两点间距离公式
            if (r < r1*0.7f)
                return true;
            else return false;
        }
        public boolean isMove(float xx, float yy) { //判断按下摇杆后 是否移动,如果x1y1 x2y2的距离大于r1*0.15视为移动
            // MY实际开发中用到,该教程用不到此变量
            double r = Math.sqrt((x1 - xx) * (x1 - xx) + (y1 - yy) * (y1 - yy));//两点间距离公式
            if (r > r1*0.15f)
                return true;
            else return false;
        }
        public void onDraw(Canvas g, Paint p){ //画摇杆
            if(down) { //当摇杆被按下时 才显示
                //怎么用Canvas画图这里就不说了
                my.re.left = x1 - r1;
                my.re.top = y1 - r1;
                my.re.right = x1 + r1;
                my.re.bottom = y1 + r1;
                g.drawBitmap(img, null, my.re, p); //画大圆
                my.re.left = x2 - r2;
                my.re.top = y2 - r2;
                my.re.right = x2 + r2;
                my.re.bottom = y2 + r2;
                g.drawBitmap(img, null, my.re, p); //画小圆
            }
        }
    }

    新建类 OnTouchMove.java 

    package com.yaogan.liziguo.yaogan;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.view.MotionEvent;
    import android.view.View;
    
    /**
     * Created by Liziguo on 2018/6/16.
     */
    
    public class OnTouchMove extends View { //这个view负责监听移动摇杆的手势
        
        private Move m;
        
        public OnTouchMove(Context context,Move move) {
            super(context);
            this.m=move;
            setBackgroundColor(Color.WHITE);//背景色设为白色
            getBackground().setAlpha(my.ontouchAlpha);//设置触控区透明度
            setOnTouchListener(new OnTouchListener() { //设置触控监听
                @Override
                public boolean onTouch(View v, MotionEvent ev) {
                    //加上getX() getY()因为这个view不是分布在左上角的
                    final float xx = ev.getX() + getX(), yy = ev.getY() + getY();
    
                    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                        m.down(xx, yy);//按下时的操作
    //                    m.move(xx, yy);
                    }
                    m.move(xx, yy);//移动时的操作
                    if (ev.getAction() == MotionEvent.ACTION_UP) {
                        m.up();//松开时的操作
                    }
                    return true;//不要返回false
                }
            });
        }
    }

    修改 Hua.java 的代码

    package com.yaogan.liziguo.yaogan;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.widget.RelativeLayout;
    
    /**
     * Created by Liziguo on 2018/6/15.
     */
    
    public class Hua extends RelativeLayout implements Runnable{ //继承RelativeLayout 实现Runnable接口
    
        private Paint p;//画笔
        private Move m=new Move();//移动摇杆
    
        public Hua(Context context) {
            super(context);
            p=new Paint();
            setBackgroundColor(Color.BLACK);//背景颜色设为黑色
            //实例化一个OnTouchMove
            OnTouchMove onTouchMove=new OnTouchMove(context,m);
            //把onTouchMove添加进来 宽度为屏幕的1/3 高度为屏幕的1/2
            addView(onTouchMove,my.w/3,my.h/2);
            //设置onTouchMove的位置
            onTouchMove.setX(0);
            onTouchMove.setY(my.h/2);
    
            new Thread(this).start();//启动重绘线程
        }
    
        @Override
        protected void onDraw(Canvas g) {//重写onDraw方法
            super.onDraw(g);
            m.onDraw(g,p);//画移动摇杆
        }
    
        @Override
        public void run() { //每隔20毫秒刷新一次画布
            while(true){
                try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
                postInvalidate();//重绘 在子线程重绘不能调用Invalidate()方法
            }
        }
    }

    好的 现在我们的摇杆可以说已经做好一大半了,因为剩下的原理都一样

    先运行一遍看看效果吧

    左下角的白色矩形是我们的OnTouchMove类,为了更好的测试我们先让他显示出来 等做好了再隐藏掉

    下面我们来解释一下为什么斜率k=(x1-x2)/(y1-y2)而不是(y1-y2)/(x1-x2)吧

    因为我们手机上的平面直角坐标系跟数学上的平面直角坐标系不一样

    数学上的平面直角坐标系是这样的

    而我们手机是这样的

    有没有发现把手机的坐标系 逆时针旋转一下就是数学里的坐标系了,不过x跟y调了一下位置

    所以我们在写代码的时候把x y换一下就行了

    数学坐标系中k=1的直线

    程序中k=1的直线

    再解释下 Move 类的 move方法

     

    public void move(float xx,float yy){ //按下摇杆后移动的操作
            angle=getAngle(xx,yy);
            in=in(xx, yy);
            move=isMove(xx,yy);
            if (!in) {
                //下面会做解释
                xx= (float) (x1+ Math.sin(angle)*r1*0.7f);
                yy= (float) (y1+ Math.cos(angle)*r1*0.7f);
            }
            x2=xx;
            y2=yy;
        }

     

    不知不觉已经凌晨2:46了,今天就写到这吧

     

    明天继续。。。。。。

     

    好的下面我们开始做技能摇杆,这教程做的比较累啊

    下面的技能类是我直接从我游戏里拷贝过来的并做了些小修改

    解释可能没那么清楚毕竟原理都一样

    只不过是多了几个功能而已

     

    准备图片

     

    添加到工程里

    由于图片比较多 我们加载图的代码位置改一下

    修改 MainActivity。java 和 my.java

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            my.main=this;
            getSupportActionBar().hide();//隐藏标题栏
            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏 隐藏状态栏
            //判断当前是否横屏 如果不是就设为横屏,设为横屏之后会自动调用onCreate方法
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                //获取屏幕的宽高
                DisplayMetrics dis = getResources().getDisplayMetrics();
                my.w = dis.widthPixels;
                my.h = dis.heightPixels;
                //获取屏幕分辨率和1920*1080的比例 以便适应不同大小的屏幕
                my.bili = (float) (Math.sqrt(my.w * my.h) / Math.sqrt(1920 * 1080));
                //加载图片
                my.border= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.border);
                my.cancel= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.cancel);
                my.down= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.down);
                my.yaogan= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.yaogan);
                my.cd= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.cd);
                setContentView(new Hua(this));
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 横屏
            }
        }
    }
    public class my { //这个类当一个全局变量使用
        public static int w,h;//屏幕的宽高
        public static float bili;
        public static MainActivity main;
        public static RectF re=new RectF();
        public static int ontouchAlpha=100;//触控区透明度0-255 0为透明,为了测试我们先设为100
    
        public static Bitmap border,cancel,down,yaogan,cd;
    
        public static Skill skill;//当前正在使用的技能 现在会报错 因为我们还没新建技能Skill类
    }

    修改 Move 类的构造方法

        public Move(){
            r1 = 480 * 0.5f * my.bili;//乘上一个比例 适应不同大小的屏幕
            r2 = 300 * 0.5f * my.bili;
    //      img= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.yaogan);//初始化摇杆图片
            img=my.yaogan;
        }

     

     

    新建技能类 Skill.java

     

     

    package com.yaogan.liziguo.yaogan;
    
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    
    /**
     * Created by Liziguo on 2018/6/16.
     */
    
    public abstract class Skill {
        public int jineng;
        private final float x,y;//技能图标中心位置,不是按下时的位置
        private float x2, y2;//技能按下移动后手指的坐标
        private float xxx,yyy;//判断拖动点是否超出两倍r的范围
        private final float calcelx, cancely;
        public float angle;//技能按下后 x y指向xx yy的角度
        public Bitmap img, imgborder, imgdown, imgyaogan,imgcd,imgcancel;
        private final float r2;
        private final float r3=50*my.bili;
        public boolean down=false;
        public boolean down_main=false;//down_main 只触发一次;
        public boolean cancel=false;
        public int cdmax;
        public long last,cd=0;//last最后一次释放技能的时间
        /*
        0 普通攻击
        1 技能1
        2 技能2
        3 技能3
         */
        public Skill(int jineng, int cd, Bitmap image){
            this.jineng=jineng;
            switch (jineng){
                case 0:
                    x= my.w*0.87f;
                    y= my.h*0.8f;
                    break;
                case 1:
                    x= my.w*0.7f;
                    y= my.h*0.88f;
                    break;
                case 2:
                    x= my.w*0.75f;
                    y= my.h*0.62f;
                    break;
                case 3:
                    x= my.w*0.9f;
                    y= my.h*0.5f;
                    break;
                default:x=y=0;
            }
            cdmax=cd;
            if(jineng == 0) r2=125*my.bili;
            else r2=80*my.bili;
            calcelx =my.w-r2*2;
            cancely =my.h/4;
            img=image;
            imgborder=my.border;
            imgdown=my.down;
            imgyaogan=my.yaogan;
            imgcd=my.cd;
            imgcancel=my.cancel;
        }
        //    public abstract void down();
    //    public abstract void move();
    //    public abstract void up();
        public void down(){ //DOWN 由ontouch触发
            if(cd>0)return;
            down=true;
            my.skill=this;
        }
        public abstract void down_main(); //DOWN 教程用不到该抽象方法
    
        public void move(float x,float y){//按下技能后 由ontouch触发
            x2 =x;
            y2 =y;
            angle=getAngle(x2, y2);
            cancel=incancel(x,y);
            if (jineng !=0 && !in2(x,y)) {
                xxx= (float) (this.x+ Math.sin(angle)*r2*2);
                yyy= (float) (this.y+ Math.cos(angle)*r2*2);
            }else{
                xxx=x;
                yyy=y;
            }
        }
        public abstract void move_main();//按下技能后 由MyActor触发 教程用不到该抽象方法
        public abstract void up(); //松开后 由MyActor触发 释放技能
    
        public boolean in(float xx,float yy){ //判断是否被点中
            double r= Math.sqrt((x - xx)*(x-xx)+(y-yy)*(y-yy));
            if(r<r2)
                return true;
            else return false;
        }
        public boolean in2(float xx, float yy) { //判断拖动点是否超出两倍r的范围
            double r = Math.sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
            if (r < r2 * 2)
                return true;
            else return false;
        }
        public boolean incancel(float xx,float yy){ //判断是否取消
            double r= Math.sqrt((calcelx - xx)*(calcelx -xx)+(cancely -yy)*(cancely -yy));
            if(r<r2)
                return true;
            else return false;
        }
        public float getAngle(float xx,float yy){ //x y指向xx yy的角度
            float angle,k;
            if (y==yy)
                if (x > xx)
                    angle= (float) (-Math.PI/2);
                else
                    angle= (float) (Math.PI/2);
            else{
                k=(x-xx)/(y-yy);
                if (y > yy) {
                    angle= (float) (Math.atan(k) + Math.PI);
                } else {
                    angle= (float) Math.atan(k);
                }
                if(angle>Math.PI)
                    angle-=Math.PI*2;
                else if(angle<-Math.PI)
                    angle+=Math.PI*2;
    
            }
            return angle;
        }
        private float drawpx=10*my.bili;
    
        public void next(){
            //计算技能冷却时间
            cd=cdmax-System.currentTimeMillis()+last;
        }
        //按下的时候技能图标下移 显示蓝色框框
        public void onDraw(Canvas g, Paint p){
            my.re.left=x-r2;
            my.re.top=y-r2;
            my.re.right=x+r2;
            my.re.bottom=y+r2;
            if(down){
    //            new RectF(x-r2,y-r2,x+r2,y+r2);
    //            new RectF(x-r2,y-r2+10*my.bili,x+r2,y+r2+10*my.bili);
    //            my.re.left=x-r2;
    //            my.re.top=y-r2;
    //            my.re.right=x+r2;
    //            my.re.bottom=y+r2;
                if(jineng!=0){
                    final float bl=2;
                    my.re.left=x-r2*bl;
                    my.re.top=y-r2*bl;
                    my.re.right=x+r2*bl;
                    my.re.bottom=y+r2*bl;
                    //蓝色框框未下移
                    g.drawBitmap(imgdown,null,my.re,p);
                }
                my.re.left=x-r2;
                my.re.top=y-r2;
                my.re.right=x+r2;
                my.re.bottom=y+r2;
                ///
                //技能图片和技能边框下移
                my.re.top+=drawpx;
                my.re.bottom+=drawpx;
                g.drawBitmap(img,null,my.re,p);
                my.re.left-=drawpx;
                my.re.top-=drawpx;
                my.re.right+=drawpx;
                my.re.bottom+=drawpx;
    
                g.drawBitmap(imgborder,null,my.re,p);
                if(jineng!=0){
                    my.re.left=xxx-r3;
                    my.re.top=yyy-r3;
                    my.re.right=xxx+r3;
                    my.re.bottom=yyy+r3;
                    g.drawBitmap(imgyaogan,null,my.re,p);
                    //cancle
                    my.re.left= calcelx -r2;
                    my.re.top= cancely -r2;
                    my.re.right= calcelx +r2;
                    my.re.bottom= cancely +r2;
                    g.drawBitmap(imgcancel,null,my.re,p);
                }
            }else{
                g.drawBitmap(img,null,my.re,p);
                if(jineng!=0 && cd>0) {
                    p.setTextSize(40*my.bili);
                    p.setColor(Color.WHITE);
                    g.drawBitmap(imgcd,null,my.re,p);
                    float f=cd/100f;
                    f=(int)f;
                    f=f/10;
                    g.drawText(String.valueOf(f),x-p.getTextSize()*4/5,y+p.getTextSize()/3,p);
    
                }
                my.re.left-=drawpx;
                my.re.top-=drawpx;
                my.re.right+=drawpx;
                my.re.bottom+=drawpx;
                g.drawBitmap(imgborder,null,my.re,p);
            }
        }
    }

    新建一个类 OnTouchSkill.java 他也是一个监听view

    这样多点触控会好写很多,刚开始我是用一个view做监听的 写到我心态爆炸。。。

    package com.yaogan.liziguo.yaogan;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.view.MotionEvent;
    import android.view.View;
    
    /**
     * Created by Liziguo on 2018/6/16.
     */
    
    public class OnTouchSkill extends View {
        /*
        A 普通攻击
        Q 技能1
        W 技能2
        E 技能3
        R 没有R
         */
    
        public Skill A,Q,W,E;
    
        public OnTouchSkill(Context context,Skill a,Skill q,Skill w,Skill e) {
            super(context);
            A=a;Q=q;W=w;E=e;
            setBackgroundColor(Color.WHITE);
            getBackground().setAlpha(my.ontouchAlpha);//0-255
            setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent ev) {
                    final float xx = ev.getX() + getX(), yy = ev.getY() + getY();
                    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                        if ( A.in(xx, yy)) {
                            A.down();
                        } else if ( Q.in(xx, yy)) {
                            Q.down();
                        } else if ( W.in(xx, yy)) {
                            W.down();
                        } else if ( E.in(xx, yy)) {
                            E.down();
                        }
    
                    }
                    if (my.skill != null) my.skill.move(xx, yy);
                    if(ev.getAction()==MotionEvent.ACTION_UP){
                        A.down = false;
                        Q.down = false;
                        W.down = false;
                        E.down = false;
                    }
                    return true;
                }
            });
        }
    }

    把监听控件添加到Hua,修改 Hua.java

    package com.yaogan.liziguo.yaogan;
    
    import android.content.Context;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.widget.RelativeLayout;
    
    /**
     * Created by Liziguo on 2018/6/15.
     */
    
    public class Hua extends RelativeLayout implements Runnable{ //继承RelativeLayout 实现Runnable接口
    
        private Paint p;//画笔
        private Move m=new Move();//移动摇杆
    
         /*
        A 普通攻击
        Q 技能1
        W 技能2
        E 技能3
        R 没有R
         */
    
        public Skill A=new Skill(0,100, BitmapFactory.decodeResource(getResources(),R.mipmap.putonggongji)) {
            @Override
            public void down_main() { }
            @Override
            public void move_main() { }
            @Override
            public void up() { }
        };
        public Skill Q=new Skill(1,1000, BitmapFactory.decodeResource(getResources(),R.mipmap.skill1)) {
            @Override
            public void down_main() { }
            @Override
            public void move_main() { }
            @Override
            public void up() {
                down_main=false;
                if(!cancel){ //技能冷却时间
                    last= System.currentTimeMillis();
                }
            }
        };
        public Skill W=new Skill(2,1000, BitmapFactory.decodeResource(getResources(),R.mipmap.skill2)) {
            @Override
            public void down_main() { }
            @Override
            public void move_main() { }
            @Override
            public void up() {
                down_main=false;
                if(!cancel){
                    last= System.currentTimeMillis();
                }
            }
        };
        public Skill E=new Skill(3,1000, BitmapFactory.decodeResource(getResources(),R.mipmap.skill3)) {
            @Override
            public void down_main() { }
            @Override
            public void move_main() { }
            @Override
            public void up() {
                down_main=false;
                if(!cancel){
                    last= System.currentTimeMillis();
                }
            }
        };
    
        public Hua(Context context) {
            super(context);
            p=new Paint();
            setBackgroundColor(Color.BLACK);//背景颜色设为黑色
            //实例化一个OnTouchMove
            OnTouchMove onTouchMove=new OnTouchMove(context,m);
            //把onTouchMove添加进来 宽度为屏幕的1/3 高度为屏幕的1/2
            addView(onTouchMove,my.w/3,my.h/2);
            //设置onTouchMove的位置
            onTouchMove.setX(0);
            onTouchMove.setY(my.h/2);
    
            //添加技能摇杆监听
            OnTouchSkill onTouchSkill=new OnTouchSkill(context,A,Q,W,E);//后添加的优先级高
            addView(onTouchSkill);
            onTouchSkill.setX(my.w*0.7f-85*my.bili);
            onTouchSkill.setY(my.h/2-85*my.bili);
            new Thread(this).start();//启动重绘线程
        }
    
        @Override
        protected void onDraw(Canvas g) {//重写onDraw方法
            super.onDraw(g);
            m.onDraw(g,p);//画移动摇杆
            //画技能
            A.onDraw(g,p);
            Q.onDraw(g,p);
            W.onDraw(g,p);
            E.onDraw(g,p);
        }
    
        @Override
        public void run() { //每隔20毫秒刷新一次画布
            while(true){
                try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
                //计算冷却时间
                A.next();
                Q.next();
                W.next();
                E.next();
                //释放技能
                if (my.skill != null) {
                    my.skill.down_main();//教程用不到该方法
                    my.skill.move_main();//教程用不到该方法
                    if (my.skill.down == false) {
                        my.skill.up();
                        my.skill = null;
                    }
                }
    
                postInvalidate();//重绘 在子线程重绘不能调用Invalidate()方法
            }
        }
    }

    运行下看看效果吧

    修改 my.java

    public class my { //这个类当一个全局变量使用
        public static int w,h;//屏幕的宽高
        public static float bili;
        public static MainActivity main;
        public static RectF re=new RectF();
        public static int ontouchAlpha=0;//把触控区透明度改成0
    
        public static Bitmap border,cancel,down,yaogan,cd;
    
        public static Skill skill;//当前正在使用的技能
    }

     

    再运行下

     

    大功告成

    下载地址:https://download.csdn.net/download/u010756046/10482434

    PS:图片不要太大 尽量压缩到20kb以下,不然使用摇杆会很卡

     

    展开全文
  • (this,android.R.layout.simple_list_item_1,names); setListAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action ...

    看了视频和百度的资料,自己摸索了下。

    第一种:系统默认布局

    public class MainActivity extends ListActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            String[] names = {"name1","name2","name3"};
            ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,names);
            setListAdapter(adapter);
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    }
    

    第二种:使用自定义布局

    public class MainActivity extends ListActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            
            //与上一个演示唯一的区别在这里,你可以设置自己想要的布局
            setContentView(R.layout.activity_main);
            
            String[] names = {"name1","name2","name3"};
            ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,names);
            setListAdapter(adapter);
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    }
    

    自己演示了看看吧

    展开全文
  • 新建工程安装完毕后,打开我们的Android Studio,第一次启动需要下载SDK等一些东西,时间比较长,笔者等了大概40分钟才下载完毕选择第一项,新建一个Android项目选择开发程序将运行在哪个平台上:...



    下载Android Studio

    中文下载社区:http://www.android-studio.org/

    2.安装Android Studio

    傻瓜式的下一步而已,只列出需要注意的页面:

      


    3.新建工程

    安装完毕后,打开我们的Android Studio,第一次启动需要下载SDK等一些东西,时间比较长,笔者等了大概40分钟才下载完毕

    选择第一项,新建一个Android项目

    选择开发程序将运行在哪个平台上:

    选择Activity的风格:

    设置进入程序一个页面后的Activity的一些信息

    Finish然后是漫长的等待~


    4.IDE的界面分析

    先看下整个界面吧:

    接着看下我们的项目结构,而我们一般关心的只是app这个目录:


    5.运行下程序试试

    点击菜单栏的X,即可运行程序:

    此处输入图片的描述


    END




    展开全文
  • 3. Android Studio 3.1 Android Studio安装 3.2 SDK下载及配置 4. 运行第一个App 1. 配置要求 系统:64-bit-Windows 7或更高 CPU:Intel-i5或更高 内存:8GB或更高 硬盘:剩余空间50GB或更高,推荐使用...

    目录

    0. 引言

    1. 配置要求

    1.1 官方配置

    1.2 建议配置

    2. JDK

    2.1 JDK 安装

    2.2 配置环境变量

    3. Android Studio

    3.1 Android Studio安装

    3.2 SDK下载及配置

    4. HelloWorld

    4.1 第一版

    4.2 第二版

    5. 友情链接


    =================================================================持续更新中=================================================================

    0. 引言

    本文第一版是基于 Android Studio 3.4.1 编写的。目前最新版已经更新至 Android Studio 4.1,在安装上并没有太大的变化,Android Studio 4.1 自集成了JDK,可省去用户配置JDK的过程。同时这一版也将再填充一下关于 Android Studio 下载、安装、配置及应用创建过程中一些注意事项和解决方法。

    1. 配置要求

    1.1 官方配置

    Android 开发者官网给开发者提供了不同平台下的设备配置要求,截止2020年12月21日,官网配置要求如下表所示。详情链接:https://developer.android.google.cn/studio

    Windows

    Mac

    Linux

    Chrome OS

    Microsoft® Windows® 7/8/10 (64-bit)

    Mac® OS X® 10.10 (Yosemite) or higher, up to 10.14 (macOS Mojave)

    GNOME or KDE desktop

    Tested on gLinux based on Debian.

    8 GB RAM or more recommended

    4 GB RAM minimum, 8 GB RAM recommended

    4 GB RAM minimum, 8 GB RAM recommended

    64-bit distribution capable of running 32-bit applications

    4 GB of available disk space minimum

    2 GB of available disk space minimum,
    4 GB Recommended (500 MB for IDE + 1.5 GB for Android SDK and emulator system image)

    2 GB of available disk space minimum,
    4 GB Recommended (500 MB for IDE + 1.5 GB for Android SDK and emulator system image)

    GNU C Library (glibc) 2.19 or later

    1280 x 800 minimum screen resolution

    1280 x 800 minimum screen resolution

    1280 x 800 minimum screen resolution

    4 GB RAM minimum, 8 GB RAM recommended

    Intel i5 or higher (U series or higher) recommended

       

    2 GB of available disk space minimum,
    4 GB Recommended (500 MB for IDE + 1.5 GB for Android SDK and emulator system image)

    For more information on recommended devices as well as Android emulator support, visit chromeos.dev
       

    1280 x 800 minimum screen resolution

     

    1.2 建议配置

    Android Studio对硬件配置要求较高,尤其是内存和硬盘,目前多数 Android 开发者主要以 Windows 平台为主,笔者根据实际安装情况给出个人建议配置,如下表所示。除硬件配置要求外,还需要满足两个必要条件:

    ① 电脑必须连接网络,某些过程需要联网完成;

    ② 系统用户名需为英文,如为中文,最后 gradle 可能会报错,网上有其他解决方案,但非完美解决方案。

    Windows
    系统:64-bit-Windows 7或更高
    CPU:Intel-i5或更高
    内存:8GB或更高
    硬盘:剩余空间10GB或更高,推荐使用固态硬盘
    分辨率:1280 x 800或更高
    注:本配置要求并非为最低配置

    2. JDK

    2.1 JDK 安装

            Android 版本对 JDK 有相应的要求,Android 5.0 默认使用 jdk 1.7 编译,Android 7.0 默认使用 jdk 1.8 编译。如果 JDK 为 1.6 或 1.7,而 SDK 为最新版本,可能会导致以下问题:

    ① 创建项目后,浏览布局文件设计图会报错:Android N requires the IDE to be running with Java 1.8 or later。

    ② 编译项目失败,提示错误:com/android/dx/command/dexer/Main: Unsupported major.minor version 52.0。

    ③ 运行 App 失败,提示错误:compileSdkVersion 'android-24' requires JDK 1.8 or later to compile。

    目前最新的 Android Q 依旧可以使用 jdk 1.8 编译,因此本文采用 jdk 1.8 进行安装。

    第1步:打开下载的 jdk 1.8 安装程序,点击"下一步"按钮。

    第2步:选择 jdk 1.8 的安装路径,可以使用默认安装路径,也可以自定义安装路径,笔者这里采用默认安装路径,然后点击"下一步"按钮,开始 JDK 的安装。

    第3步:安装 jdk 1.8 过程中会弹出 JRE 的安装,点击"下一步"即可。

    第4步:等待安装进度条完成

    第5步:显示" Java SE Development kit 8 已经成功安装"表明已经安装成功,即可点击"关闭"按钮。

    2.2 配置环境变量

    第1步:进入"系统属性",选择"高级"标签,然后选择"环境变量",如下图所示。

     第2步:选择下方"系统变量",新建变量名为"JAVA_HOME",变量值为安装 JDK 8 的路径,这里需要根据实际安装路径填写变量值,如下图所示,然后点击"确定"按钮。

    第3步:新建变量名为"CLASSPATH",变量值如下图所示,然后点击"确定"按钮。

    第4步:选中变量名为"Path"的系统变量,点击"编辑"按钮,打开"编辑环境变量"对话框,选择右侧"新建"按钮,添加"%JAVA_HOME%\bin"目录,如下图所示,然后点击"确定"按钮。

    3. Android Studio

    3.1 Android Studio 安装

    第1步:双击下载完成的 Android Studio 安装程序,弹出安装界面,点击"Next"按钮,如下图所示。

    第2步:勾选安装界面中的所有选项(默认已全部勾选),然后点击"Next"按钮,如下图所示。

    第3步:进入安装路径配置页面,选择 Android Studio 的安装路径,建议将 Android Studio 安装在除系统盘以外的其他磁盘,然后点击"Next"按钮,最后点击"Install"按钮,开始安装,如下图所示。

     第4步:进入正在安装页面,等待安装完成,然后点击"Next"按钮,如下图所示。

     第5步:完成安装,点击"Finish"按钮,如下图所示。

    3.2 SDK下载及配置

    第1步:启动 Android Studio 程序,初次运行会提示"Import Android Studio Settings",选择"Do not import settings"选项,点击"OK"按钮,开始加载 Android Studio 程序,如下图所示。

     第2步:加载过程中还会弹出"Data Sharing"界面,考虑隐私安全,选择"Don't send",如下图所示。

    第3步:由于缺少 Android SDK 组件,当加载快结束时,会弹出是否需要设置代理,这里点击"Cancel"即可,如下图所示。 

    第4步:加载完成后,进入 Android Studio 安装引导界面,点击"Next"按钮,如下图所示。

     第5步:选择自定义"Custom"选项,然后点击"Next"按钮,如下图所示。

    第6步:这一步不同于第一版,应该是从 Android Studio 4.0 之后,IDE 自集成 JDK,这里笔者分别给出了原生安装和 IDE 自集成的 jdk 版本,可以看到,原生安装的 jdk 版本是 jdk-8u271,而自集成的 jdk 版本则是 jdk-8u242,由于之前已经配置过环境变量,如果选择自集成 jdk,后面在安装SDK之前,会产生类似告警的信息,因此这里选择"JAVA_HOME"选项,然后点击"Next"按钮,如下图所示。

    第7步:选择 UI 主题,用户可根据喜好自行选择,然后点击"Next"按钮,如下图所示。

     第8步:进入 SDK 组件安装,建议看完后再点击"Next"按钮。如果网络很好,正常情况下是可以刷出下面的界面,全部勾选后点击"Next"按钮,如下图所示。

    如果无法显示全部内容或空白一片,那是无法访问:dl.google.com服务器。这里给出以下两种解决方式。

    ① 下载笔者提供的Android SDK包,解压后,在该界面“Android SDK Location”选择解压目录,然后单击“Next”,该SDK包不包含HAXM,可以在完整包中查找。

    ② 进入网站http://ping.chinaz.com/,进行dl.google.com ping检查,选择大陆响应时间最短的IP地址,如图所示

    进入cmd对此IP地址进行ping测试,如果可以将(IP地址 dl.google.com)加入hosts文件中,hosts文件地址:C:\WINDOWS\System32\drivers\etc\hosts。重启电脑后打开Android Studio,应该可以看到列表。

    第9步:进入模拟器设置界面,笔者建议模拟器的RAM最小不要低于 2.0GB,最大不要超过电脑内存的一半,这里选择默认的 2.0GB 对于初学者已经够用了,如下图所示。

    第10步:最后在安装 SDK 之前,提供用户安装信息的校验,看到"JDK Location",如果选择默认的 JDK 位置,会有一串提示信息,将JDK位置改为"Java_HOME"就不会有此信息出现,确认信息后点击"Finish"按钮,如下图所示。

    第11步:开始下载安装 SDK 和模拟器,等待下载完成,如下图所示。

    第12步:完成后进入 Android Studio 欢迎界面,如下图所示。

    4. HelloWorld

    4.1 第一版

    第1步:单击主界面“Start a new Android Studio project”,选择创建工程,这里选择“Empty Activity”,单击“Next”,如图所示。

    第2步:配置工程,点击“Finish”,如图所示。

    第3步:由于我国网络的特殊原因,可能会导致无法编译成功,左下角一直转动,如图所示。解决方法如下:

    ①单击“File”,选择关闭工程后跳转到主界面,如图所示。

    ②点击左侧HelloWorld,重新进入工程,选择build.gradle,并添加如下代码,然后单击工具栏上“锤子”形状的按钮,进行重新编译,如图所示。

    buildscript {
        repositories {
            maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
            google()
            // jcenter()
        }
    }
    
    allprojects {
        repositories {
            maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
            google()
            // jcenter()
        }

    ③编译可能需要一段时间,请耐心等待,如果失败请重新尝试并考虑是否是网络问题。

    第4步:点击工具栏上“大象”形状按钮,将gradle同步至工程,即“sync project with gradle files”,然后等待进度条完全走完,完成后工具栏上会出现绿色三角按钮,如下图所示。

    第5步:点击工具栏上“大象”右侧“手机”形状按钮,打开虚拟设备,如图所示。

    ①如果当前没有设备,选择左下角创建虚拟设备,单击“Next”,如图所示。

    ②选择对应的Android版本,请注意各区别,单击“Next”,如下图所示。

    第6步:选择右侧三角按钮打开虚拟设备,请耐心等待,如图所示。

     

    第7步:选择工具栏绿色三角按钮,并选择“OK”,如图所示。

    第8步:成功运行“HelloWorld”,如图所示。

    4.2 第二版

    第1步:选择欢迎界面"Create New Project",进入"Select a Project Template"引导页,选择"Empty Activity",然后点击"Next"按钮,如下图所示。

    第2步:配置工程,注意这里"Save location"的工程路径不要出现空格,否则会有告警"project location should not contain whitespace, as this can cause problems with the NDK tools",然后点击"Finish"按钮,如下图所示。

    第3步:进入 Android Studio 主界面,开始"Gradle sync started",此时工具栏下方的快捷键大部分都呈现灰色状态。点击左下角"build",可以查看 Gradle 下载信息,等待下载、解压、同步完成,Log 框中会提示"BUILD SUCCESSFUL in XXm XXs",快捷键也由灰色变为绿色,主要确定一下"Make Project"(锤子)及"Run 'app'"(三角)是否为绿色,如下图所示。

    注:似乎最新版 Android Studio 不会产生 Gradle 下载、解压、同步失败的问题,可能是笔者网络较好,因此没有产生此种情况,如果发生 Gradle 错误,可以尝试第一版的解决方法。

     第4步:点击快捷栏的"AVD Manger",打开虚拟设备,如下图所示。

      第5步:点击"Launch this AVD in the emulator"(三角),等待虚拟设备打开,如下图所示。

       第6步:点击"Run 'app' "(三角),等待编译、安装完成,即一个 "HelloWorld" app 完成,如下图所示。

    5. 友情链接

    序号 网站名称 网址
    1 Android 开发者 - Android 开发工具&官方文档  https://developer.android.google.cn/
         
         
         

    资源链接:3.4.1 Android Studio资源包

    Tip:欢迎大家在下方留言,还有个别可能产生的问题会在后期重新整理。

    展开全文
  • Android开发Android Studio安装教程下载Android Studio安装安装JDK安装Android Studio 下载Android Studio Android Studio官网下载 安装 安装JDK Android开发语言是Java,所以需要安装JDK。版本推荐老版本,老...
  • Android Studio安装教程(超级详细)

    万次阅读 多人点赞 2020-08-28 12:02:04
    Android Studio安装教程(超级详细)欢迎使用Markdown编辑器获取Android Studio安装Android Studio 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown...
  • Android基础入门教程——1.2.2 使用Android Studio开发Android APP标签(): Android基础入门教程写在前面 本节将介绍如何使用Android Studio开发Android APP,和前面Eclipse + ADT + SDK搭建Android开发环境一样...
  • Android Studio开发初级教程
  • Android Studio安装教程

    千次阅读 2021-03-02 22:26:51
    AndroidStudio官网下载:http://android-studio.org/可以更具自己喜欢的版本下载,高版本开发和运行效率快,高很多。 0.要安装Android Studio并使用的话先要配置Java环境变量, 请看Java环境变量配置 1.百度搜索...
  • Android开发-android studio 安装教程

    千次阅读 2017-11-05 14:14:12
    Android studio安装教程 原创 2017年02月24日 12:50:13
  • 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的...
  • android studio详细教程汇总

    千次阅读 2016-09-26 11:08:39
    来自stormzhang的Studio系列教程Android Studio系列教程一 —- 下载与安装Android Studio系列教程二 —- 基本设置与运行Android Studio系列教程三 —- 快捷键Android Studio系列教程四 —- Gradle基础Android Studio...
  • 这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android ...
  • @(DataMaster)[Android] Android Studio 使用教程学习1. Android Studio工具下载与安装工具下载 AndroidDevTools里面有很多网站作者自己收集和整理的在android开发过程中需要用到的工具 19个Android开发工具 环境...
  • Android Studio使用教程

    万次阅读 多人点赞 2019-01-16 11:06:00
    以前用Eclipse做过Android开发的人,就可以用现成的Android SDK。 Android Studio安装完成后,第一次启动AS前,为了避免重新下载新版本的SDK,需要做如下操作: AS启动前,打开安装目录,请先将b...
  • Android Studio 新手教程

    千次阅读 2018-06-15 19:09:15
    本文将介绍如何使用Android Studio开发Android APP,只是介绍一些基本东西。最后运行project的时候建议真机测试。 1、下载Android Studio 网页下载:http://www.android-studio.org 百度云下载:...
  • Android Studio 开发详解

    万人学习 2016-09-21 00:57:54
    Android Studio教程,该教材会详细介绍Android Studio如何使用,包括在Windows平台下载安装Android Studio、配置、代码重构、项目调试、jar包管理等。
  • AndroidStudio安装教程
  • AndroidStudio基础教程

    2015-10-25 10:13:57
    AndroidStudio基础教程百度云 1.Android视图结构,适用于大部分的开发工作 2.对AndroidStudio进行相关的设置(Ctrl+Alt+S)  字体 16号建议 4.导入eclipse的adt工程  关闭现有工程(打开AS的欢迎界面)->选择...
  • 完整版—Android studio入门教程

    万次阅读 多人点赞 2017-10-17 12:54:34
    AS的安装及第一个AS中android项目的搭建 前言:前段时间公司搞了个 "校企合作" 的项目,要求公司人员去学校对学生进行阶段性的专业培训,荣幸的我被派去当了回“老师”;哈哈,真的有点“打肿脸充胖子”的感觉;...
  • 工欲善其事,必先利其器。先学习androidstudio的安装。
  • 这个系列教程Android Studio Beta版本的时候就开始着手编写,当时就认为AS绝对会成为Android开发的未来,时至今日印证了当时的观点,作为国内最早一批AS教程之一,可以帮助从未接触过AS和Gradle的初学者很快上手。...
  • Android Studio开发环境搭建

    万次阅读 多人点赞 2019-01-05 23:29:49
    目前关于AS(Android Studio)的环境搭建网上已经有很多教程了,但是实际操作起来还是会有各种意想不到的问题,对于大多数开发者来说可能还是会有困难,本教程根据笔者亲身实践,将搭建过程中的各种问题总结出来,方便...
  • Android Studio 安装教程

    2016-03-26 11:41:36
    介绍Android Studio的安装过程
  • 安装Android Studio相关教程

    千次阅读 2016-03-30 19:47:08
    安装Android Studio相关教程
  • Android Studio安装教程(超详细教程

    千次阅读 多人点赞 2020-12-07 21:21:01
    Android Studio 是一个基于Intellij IEDA的Android集成开发工具。我们可以直接在Google的Android中国开发者社区[(https://developer.android.google.cn/studio)](https://developer.android.google.cn/studio)官网,...
  • Android Studio V3.12环境下TV开发教程(转自Android官网https://developer.android.com/training/tv/start)文章源自:光谷佳武 https://blog.csdn.net/jiawuhan/article/details/806
  • Android studio安装教程良心版

    千次阅读 2016-11-06 10:38:27
    【良心版的Android studio零基础安装教程】 上篇 如果你准备自己搞Android开发,我建议你跳过eclipse直接使用android studio。毕竟android studio绝对是Android开发的趋势,android studio 的强大和潜力这里我就不...
  • 快速入门Android开发 视频 教程 android studio 任苹蜻...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,300
精华内容 8,520
关键字:

androidstudio开发教程