Android游戏开发之360°半透明摇杆。。。。

来源:互联网 发布:质数c语言 编辑:程序博客网 时间:2024/05/22 09:23

照着PDF做了个摇杆并实现了 摇杆控制角色行走, 在这里贴下代码做下笔记。

首先新建了一个VIEW  继承SurfaceView   实现相关接口

<pre name="code" class="java">

public class PlayerView extends MapView implements Callback,Runnable


相关变量声明与初始化设置

protected final int DIR_LEFT = 0;protected final int DIR_RIGHT = 1;private int dir = DIR_RIGHT;private int robotX,robotY;private boolean isUp=false,isDown=false,isLeft=false,isRight=false;//摇杆的圆半径private float smallCenterX = 120,smallCenterY=120,smallCenterR = 20;private float BigCenterX = 120,BigCenterY = 120,BigCenterR = 40;//圆运动角度private double angle;public PlayerView(Context context) {super(context);holder = getHolder();holder.addCallback(this);//设置监听paint = new Paint();paint.setColor(Color.BLACK);setFocusable(true);//设置焦点}@Overridepublic void surfaceCreated(SurfaceHolder holder) {bitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.robot);bmpX = -bitmap.getWidth()+this.getWidth();bmpY = this.getHeight() - bitmap.getHeight();Thread thread = new Thread(this);thread.start();//设置摇杆初始位置smallCenterX = 40;smallCenterY = this.getHeight()-40;BigCenterX = 40;BigCenterY = this.getHeight()-40;}


接下来是 摇杆和 角色的绘制, 都放一起了


private void drawFrame(){canvas = holder.lockCanvas();canvas.drawColor(Color.WHITE);int frameW = bitmap.getWidth()/6; //获得每一帧的宽int frameH = bitmap.getHeight()/2; //获得每一帧的高int col = bitmap.getWidth()/frameW; //获得位图列数int x = cureentFrame%col * frameW;int y = cureentFrame /col * frameH;paint.setAlpha(255);//不透明canvas.save();//paint.setColor(Color.RED);//设置画笔颜色//设置每帧可见区域为角色一样大小canvas.clipRect(robotX,robotY,robotX+bitmap.getWidth()/6,robotY+bitmap.getHeight()/2);if(dir==DIR_LEFT){//如果向左移动则设置角色翻转canvas.scale(-1,1,robotX-x+bitmap.getWidth()/2,robotY-y+bitmap.getHeight()/2);}canvas.drawBitmap(bitmap, robotX-x,robotY-y, paint);canvas.restore();//摇杆绘制paint.setAlpha(0x77); //设置摇杆透明度canvas.drawCircle(BigCenterX, BigCenterY, BigCenterR, paint);//大圆canvas.drawCircle(smallCenterX, smallCenterY, smallCenterR, paint);//小圆holder.unlockCanvasAndPost(canvas);}


计算余弦

/** * Math.cos 返回余弦   * @param centerX 围绕大圆中心点X * @param centerY 围绕大圆中心点Y * @param R围绕大圆半径 * @param rad   旋转弧度 * 方法: 设置小圆中心点的坐标位置 */private void setSmallCircleXY(float centerX,float centerY,float R,double rad){smallCenterX = (float)(R*Math.cos(rad))+centerX;smallCenterY = (float)(R*Math.sin(rad))+centerY;}


剩下的代码直接贴吧  都有注释的

public void logic(){cureentFrame++;//渲染帧数if(cureentFrame>=12) //超过12帧 则重置cureentFrame = 0;if(isUp)robotY -=5;if(isDown)robotY+=5;if(isLeft)robotX-=5;if(isRight)robotX+=5;//angle++;/*if(angle>=360)angle=0;setSmallCircleXY(BigCenterX, BigCenterY, BigCenterR, angle*Math.PI/180);//Math.PI 圆的周长与直径之比*/}/** * 得到两点之间弧度 * @param px1 * @param py1 * @param px2 * @param py2 * @return */public double getRad(float px1,float py1,float px2,float py2){float x = px2 - px1;//得到两点X的距离float y = py1 -py2; //y//算出斜边长float Hypotenuse = (float) Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2));float cosAngle = x/Hypotenuse; //得到角度的余弦值//通过反余弦获得角度弧度float rad = (float)Math.acos(cosAngle);if(py2<py1)rad = -rad;return rad;}private void stopMove(){isUp = false;isDown = false;isLeft = false;isRight = false;}@Overridepublic boolean onTouchEvent(MotionEvent event) {//用户抬起小圆恢复初始位置if(event.getAction()==MotionEvent.ACTION_UP){smallCenterX = BigCenterX;smallCenterY = BigCenterY;stopMove();//停止移动}else{int pointX = (int)event.getX();int pointY = (int)event.getY();//判断用户点击位置是否在大圆内if(Math.sqrt(Math.pow((BigCenterX-(int)event.getX()),2)+Math.pow((BigCenterY-(int)event.getY()), 2))<=BigCenterR){smallCenterX = pointX;//让小圆跟随用户点击位置smallCenterY = pointY;}else{setSmallCircleXY(BigCenterX, BigCenterY, BigCenterR, getRad(BigCenterX, BigCenterY, pointX, pointY));}double radian = getRad(BigCenterX, BigCenterY, pointX, pointY);angle = radian/Math.PI*180;Log.v("角度:", "============>"+angle+"   radian:"+radian);stopMove();if(angle<-67.5&&angle>-112.5){ //上isUp = true;}else if(angle<-22.5&&angle>-67.5){ //右上isUp=true;isRight = true;dir = DIR_RIGHT;}else if(angle>-167.5&&angle<-112.5){  //左上dir=DIR_LEFT;isLeft =true;isUp = true;}else if(angle>67.5&&angle<112.5){ //下isDown = true;}else if(angle<167.5&&angle>112.5){ //左下dir=DIR_LEFT;isDown = true;isLeft = true;}else if(angle>-22.5&&angle<22.5){  //右dir = DIR_RIGHT;isRight = true;}else if(angle>22.5&&angle<67.5){//右下dir=DIR_RIGHT;isDown = true;isRight = true;}else if((angle>-212.5&&angle<-167.5)||(angle<212.5&&angle>167.5)){ //下dir = DIR_LEFT;isLeft = true;}}return true;}@Overridepublic void run() {while (flag) {long start = System.currentTimeMillis();drawFrame();logic();long end = System.currentTimeMillis();try {if (end - start < 50) {Thread.sleep(50 - (end - start));}} catch (InterruptedException e) {e.printStackTrace();}}}



0 0