Android仿开心消消乐大树星星无限循环效果

啥都不说先上效果图,这个是我项目里的效果:

下面的是我抽取出来的 demo 适配啥的我基本上都做好了没做其他的

ok 下面 说一下思路把

首先 说一下原理 我是使用bitmap 创建两张图 一开始的时候 一张在下面记为1号 一张在上面 记为2号
当手指向下滑动时 判断 1号 的起点位置 是否完全超出屏幕 如果超出屏幕的话 那么将2号变为下面 1号变为上面 (移动1号的Y坐标) 大体思路 是这样. 里面还有许多判断
比如 是否能向下滑动 起点位置, 星星的判定 哎呀 好烦 说的东西太多啦 来张我的草稿纸 哈哈 话说我草稿都写了好几页

先上代码:

/**
 * Created by liuml on 2016/6/11.
 */

public class MyScrollView extends View {
 // 其资源引用的是同一张图片
 private Bitmap bmpBackGround1;
 private Bitmap bmpBackGround2;
 int speed;
 int pointX;
 int tempy1;
 private Context mcontext;

 private int isfirst = 1;
 // 按钮的坐标
 private int btnX, btnY;
 // 按钮是否按下标识位
 private Boolean isPress;
 // 界面背景坐标
 private int bg1x, bg1y, bg2x, bg2y;
 private int cloudx, cloudy;

 List<Map<String, Object>> mapList;

 // 星星坐标
 private int stars0X, stars0Y, stars1X, stars1Y, stars2X, stars2Y, stars3X,
  stars3Y, stars4X, stars4Y, stars5X, stars5Y, stars6X, stars6Y,
  stars7X, stars7Y, stars8X, stars8Y, stars9X, stars9Y, stars10X,
  stars10Y;
 // //定义第二页的星星坐标
 private int MaxStars = 80;// 最大的星星数量 80个
 private int textContnt[] = new int[MaxStars];// 数字

 private int pointsY[];
 private int pointsX[];

 private int pointY, moveY = 0;

 private int activityNumber = 2;
 private Bitmap treeBackGround;// 界面背景
 private Bitmap cloud_bg;// 界面背景
 private Bitmap starsBg;// 星星
 private Bitmap starsBg_n;// 星星未做的
 // 声明一个Resources实例便于加载图片
 private Resources res = this.getResources();
 // 声明一个画笔
 private Paint paint;
 private DisplayMetrics dm; // 获取屏幕分辨率的类
 // private Scroller mScroller;
 private boolean isFirst = true;
 // 点击事件星星相关
 int mDownX = 0;
 int mDownY = 0;
 int mTempX = 0;
 int mTempY = 0;
 private static final int MAX_DISTANCE_FOR_CLICK = 100;

 private ScrollViewListener listener;

 private int screenHeight;
 private int screenWidth;

 public MyScrollView(Context context, AttributeSet attrs) {
 super(context, attrs);
 mcontext = context;
 // 背景加载资源
 treeBackGround = BitmapFactory.decodeResource(res, R.drawable.tree);
 cloud_bg = BitmapFactory.decodeResource(res, R.drawable.cloud_bg);
 starsBg = BitmapFactory.decodeResource(res, R.drawable.stars_big);
 starsBg_n = BitmapFactory.decodeResource(res, R.drawable.startbg_n);
 this.bmpBackGround1 = treeBackGround;
 this.bmpBackGround2 = treeBackGround;
 bg1x = 0;
 bg2x = 0;
 cloudx = 0;
 pointsY = new int[22];// Y轴
 pointsX = new int[22];// X轴
 screenHeight = DisplayUtils.getScreenHeight(context);
 screenWidth = DisplayUtils.getScreenWidth(context);
 initStartsXY();
 initTextContent();
 // mScroller = new Scroller(context);
 // LogUtils.d("屏幕 分别率 高 = " + DisplayUtils.getScreenHeight(context) +
 // " 屏幕 分别率 宽度 = " + DisplayUtils.getScreenWidth(context));
 // LogUtils.d("屏幕 分别率 getDisplayDensity = " +
 // DisplayUtils.getDisplayDensity(context));

 }

 public void setMapList(List list) {
 mapList = list;
 }

 // //调用此方法滚动到目标位置
 // public void smoothScrollTo(int fx, int fy) {
 // int dx = fx - mScroller.getFinalX();
 // int dy = fy - mScroller.getFinalY();
 // smoothScrollBy(dx, dy);
 // }
 //
 // //调用此方法设置滚动的相对偏移
 // public void smoothScrollBy(int dx, int dy) {
 //
 // //设置mScroller的滚动偏移量
 // mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx,
 // dy);
 // invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
 // }
 //
 // @Override
 // public void computeScroll() {
 // //先判断mScroller滚动是否完成
 // if (mScroller.computeScrollOffset()) {
 //
 // //这里调用View的scrollTo()完成实际的滚动
 // scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
 //
 // //必须调用该方法,否则不一定能看到滚动效果
 // postInvalidate();
 // }
 // super.computeScroll();
 // }

 private void initTextContent() {
 for (int i = 0; i < MaxStars; i++) {
  textContnt[i] = i + 1;
 }
 }

 public void setOnclick(ScrollViewListener listener) {
 this.listener = listener;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);

 // 首先让第一张背景底部正好填满整个屏幕
 int treeHeight = bmpBackGround1.getHeight() - getHeight();
 // LogUtils.d("bg1y = " + bg1y + " bmpBackGround1.getHeight() = " +
 // bmpBackGround1.getHeight()
 // + " getHeight() = " + getHeight());
 if (treeHeight > 0) {// 图高大于屏幕高度

  // 第二张背景图紧接在第一张背景的上方
  // 虽然两张背景图无缝隙连接但是因为图片资源头尾
  // 直接连接不和谐,为了让视觉看不出是两张图连接而修正的位置
  bg1y = -(bmpBackGround1.getHeight() - getHeight());
  bg2y = bg1y - bmpBackGround1.getHeight();// 这里可以+100
       // 可以控制两张图之间的距离修正位置

 } else {
  bg1y = Math.abs(bmpBackGround1.getHeight() - getHeight());
  bg2y = bg1y - bmpBackGround1.getHeight();// 这里可以+100
       // 可以控制两张图之间的距离修正位置
 }

 // LogUtils.d("cloudy = " + cloudy + " bg1y = " + bg1y + " bg2y = " +
 // bg2y + " screenH = " + getHeight());

 // 实例一个画笔
 paint = new Paint();
 paint.setAntiAlias(true);// 设置没有锯齿
 // 设置画笔颜色为白色
 paint.setColor(Color.WHITE);
 }

 @Override
 protected void onDraw(Canvas canvas) {

 // LogUtils.d("屏幕 分别率 h = " + getHeight());
 // LogUtils.d("屏幕 分别率 w = " + getWidth());
 // 画云背景
 canvas.drawBitmap(resizeBitmap(cloud_bg, getWidth(), getHeight()),
  cloudx, cloudy, paint);
 // drawImage(canvas, cloud_bg, cloudx, cloudy, cloud_bg.getWidth(),
 // cloud_bg.getHeight(), cloudx, cloudy, paint);
 // 绘制两张背景
 if (isFirst) {
  bmpBackGround1 = resizeBitmap(bmpBackGround1, getWidth(),
   getHeight());
  isFirst = false;
  initBgView();

 }
 canvas.drawBitmap(bmpBackGround1, bg1x, bg1y, paint);
 canvas.drawBitmap(bmpBackGround1, bg2x, bg2y, paint);
 // LogUtils.d("bmpBackGround1.getHeight() = " +
 // bmpBackGround1.getHeight() + " screenH = " + getHeight() +
 // " bg1y = " + bg1y);
 // LogUtils.d("bg1x = " + bg1x + " bg1y = " + bg1y + " bg2x = " + bg2x
 // + " bg2y = " + bg2y + " screenH = " + getHeight());

 starsDraw(canvas);// 绘制星星
 TextViewDraw(canvas);// 绘制文本
 super.onDraw(canvas);

 }

 @Override
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {

 boolean isDown;
 // speed = t - oldt;
 //
 // //判断向上移动还是向下移动
 // if (speed > 0) {
 // isDown = true;
 // } else {
 // isDown = false;
 // }
 // logic(isDown);//计算点的距离

 super.onScrollChanged(l, t, oldl, oldt);
 }

 public Bitmap resizeBitmap(Bitmap bitmap, int w, int h) {
 if (bitmap != null) {
  int width = bitmap.getWidth();
  int height = bitmap.getHeight();
  int newWidth = w;
  int newHeight = h;
  float scaleWight = ((float) newWidth) / width;
  float scaleHeight = ((float) newHeight) / height;
  Matrix matrix = new Matrix();
  matrix.postScale(scaleWight, scaleHeight);

  Bitmap res = Bitmap.createBitmap(bitmap, 0, 0, width, height,
   matrix, true);// oom问题 待解决
  return res;
 } else {
  return null;
 }
 }

 // 画文字
 private void TextViewDraw(Canvas canvas) {
 // 判断当前画的是第几个
 int c = activityNumber * 11;
 int k = 0;
 if (activityNumber > 2) {

  k = c - ((activityNumber - 1) * 10);
 }

 // LogUtils.d("比例 x 28 = " + (double) 28 / screenWidth);
 // LogUtils.d("比例 y 65 = " + (double) 65 / screenHeight);
 // LogUtils.d("比例 x 40 = " + (double) 40 / screenWidth);
 for (int i = 0; i < 22; i++) {

  paint.setTextSize((int) (0.037037037037037035 * screenWidth));// 设置字体大小
  // paint.setTypeface(typeface);//设置字体类型
  // Typeface.DEFAULT:默认字体。
  // Typeface.DEFAULT_BOLD:加粗字体。
  // Typeface.MONOSPACE:monospace字体。
  // Typeface.SANS_SERIF:sans字体。
  // Typeface.SERIF:serif字体。
  paint.setColor(Color.BLUE);
  // 每页第几个 我推算出来的公式 (x-1)*11+i 这是普通的推算 具体问题 需要具体改变
  // setTextColorUseReflection(Color.BLUE);
  paint.setStrokeWidth(2); // 描边宽度
  paint.setFakeBoldText(true); // 外层text采用粗体
  if (activityNumber <= 2) {
  if (textContnt[i] > 9) {

   paint.setColor(res.getColor(R.color.text_color));
   canvas.drawText(
    String.valueOf(textContnt[i]),
    pointsX[i]
     + (int) (0.025925925925925925 * screenWidth),
    pointsY[i]
     + (int) (0.033854166666666664 * screenHeight),
    paint);
  } else {

   paint.setColor(res.getColor(R.color.text_color));
   canvas.drawText(
    String.valueOf(textContnt[i]),
    pointsX[i]
     + (int) (0.037037037037037035 * screenWidth),
    pointsY[i]
     + (int) (0.033854166666666664 * screenHeight),
    paint);
  }

  } else {
  // 下面的都是从在这里做操作对text 数值
  // int u = (activityNumber - 2) * 11 + i-11;
  // 必须分前后 前面的 是一队 后面的是一队
  if (activityNumber % 2 != 0) {// 第三个开始 奇数 是第二个页面在下面 第一个页面在上
      // 判断上下的 作用
   int befo;// (n-1)*11+i
   int after;
   if (i < 11) {// 数组前面的
   befo = (activityNumber - 1) * 11 + i;
   if (befo < MaxStars) {
    if (textContnt[befo] > 9) {
    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[befo]),
     pointsX[i]
      + (int) (0.025925925925925925 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    } else {
    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[befo]),
     pointsX[i]
      + (int) (0.037037037037037035 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    }
   }
   } else {// 数组后面的
   after = (activityNumber - 3) * 11 + i;
   if (after < MaxStars) {
    if (textContnt[after] > 9) {
    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[after]),
     pointsX[i]
      + (int) (0.025925925925925925 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    } else {

    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[after]),
     pointsX[i]
      + (int) (0.037037037037037035 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    }
   }
   }
  } else {
   int befo;// (n-1)*11+i
   int after;
   if (i < 11) {// 数组前面的
   befo = (activityNumber - 2) * 11 + i;
   if (befo < MaxStars) {
    if (textContnt[befo] > 9) {
    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[befo]),
     pointsX[i]
      + (int) (0.025925925925925925 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    } else {

    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[befo]),
     pointsX[i]
      + (int) (0.037037037037037035 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    }
   }

   } else {// 数组后面的
   after = (activityNumber - 2) * 11 + i;
   if (after < MaxStars) {
    if (textContnt[after] > 9) {
    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[after]),
     pointsX[i]
      + (int) (0.025925925925925925 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    } else {
    paint.setColor(res.getColor(R.color.text_color));
    canvas.drawText(
     String.valueOf(textContnt[after]),
     pointsX[i]
      + (int) (0.037037037037037035 * screenWidth),
     pointsY[i]
      + (int) (0.033854166666666664 * screenHeight),
     paint);
    }
   }
   }
  }

  }

  // LogUtils.d("pointsY [" + i + "]= " + pointsY[i]);
 }
 paint.setColor(Color.WHITE);
 }

 // 获取当前页数的开始数量
 private int getCurrent(int i) {
 int befo;
 // 判断上下
 if (activityNumber % 2 != 0) {// 奇数 第一页在上 第二页在下
  befo = (activityNumber - 1) * 11 + i;
  // LogUtils.d("befo = " + befo + " activityNumber = " +
  // activityNumber + " i = " + i);
 } else {
  befo = (activityNumber - 2) * 11 + i;
 }

 return befo;
 }

 // 获取点击的位置的数字
 private int getOnclickNo(int i) {
 int befo;// (n-1)*11+i
 int after;
 // 判断上下
 if (activityNumber % 2 != 0) {// 奇数 第一页在上 第二页在下
  if (i < 11) {
  befo = (activityNumber - 1) * 11 + i;
  // LogUtils.d("i 小于11 befo = " + befo + " activityNumber = "
  // + activityNumber + " i = " + i);
  } else {
  befo = (activityNumber - 3) * 11 + i;
  // LogUtils.d("i 大于11 befo = " + befo + " activityNumber = "
  // + activityNumber + " i = " + i);
  }
 } else {
  if (i < 11) {
  befo = (activityNumber - 2) * 11 + i;
  // LogUtils.d(" 偶数的时候 befo = " + befo + " activityNumber = "
  // + activityNumber + " i = " + i);
  } else {
  befo = (activityNumber - 2) * 11 + i;

  }
 }

 return befo;
 }

 private void starsDraw(Canvas canvas) {

 // 判断画一页当中 最多的星星 是多少
 int starsMax = (activityNumber) * 11;
 int page;

 if (starsMax > MaxStars) {// 判断当前的最多的星星是否大于定好的星星数量
  if (mapList == null) {
  for (int i = 0; i < 22; i++) {
   // 判断当前画的是第几个
   page = getCurrent(i);
   // LogUtils.d("当前画的是第几个 = " + page);
   canvas.drawBitmap(starsBg_n, pointsX[i], pointsY[i], paint);
  }
  } else {
  for (int i = 0; i < 22; i++) {
   // 判断当前画的是第几个
   page = getCurrent(i);
   // LogUtils.d("当前的 最前面的是多少 current = " + page);

   if (page < MaxStars) {
   if (page < i) {
    Map<String, Object> stringObjectMap = mapList
     .get(page);
    String type = (String) stringObjectMap.get("type");
    if (type.equals("1")) {
    canvas.drawBitmap(starsBg, pointsX[i],
     pointsY[i], paint);
    } else {
    canvas.drawBitmap(starsBg_n, pointsX[i],
     pointsY[i], paint);
    }
   } else {
    canvas.drawBitmap(starsBg_n, pointsX[i],
     pointsY[i], paint);
   }
   }
   // LogUtils.d("pointsY [" + i + "]= " + pointsY[i]);
  }
  }

 } else {
  if (mapList == null) {
  for (int i = 0; i < 22; i++) {
   // 判断当前画的是第几个
   page = getCurrent(i);
   // LogUtils.d("当前画的是第几个 = " + page);
   canvas.drawBitmap(starsBg_n, pointsX[i], pointsY[i], paint);
  }
  } else {
  int size = mapList.size();
  for (int i = 0; i < 22; i++) {
   // 判断当前画的是第几个
   page = getCurrent(i);
   // LogUtils.d("当前画的是第几个 = " + page);
   if (page < size) {
   Map<String, Object> stringObjectMap = mapList.get(page);
   String type = (String) stringObjectMap.get("type");
   if (type.equals("1")) {
    canvas.drawBitmap(starsBg, pointsX[i], pointsY[i],
     paint);
   } else {
    canvas.drawBitmap(starsBg_n, pointsX[i],
     pointsY[i], paint);
   }
   } else {
   canvas.drawBitmap(starsBg_n, pointsX[i], pointsY[i],
    paint);
   }
  }
  }

 }

 }

 private void canvasStats() {

 }

 private void initStartsXY() {

 stars0X = 340;//
 stars0Y = 1180;//
 stars1X = 280;
 stars1Y = 1065;
 stars2X = 500;
 stars2Y = 967;
 stars3X = 240;
 stars3Y = 842;
 stars4X = 400;
 stars4Y = 761;
 stars5X = 540;
 stars5Y = 685;
 stars6X = 330;
 stars6Y = 526;
 stars7X = 540;
 stars7Y = 431;
 stars8X = 375;
 stars8Y = 245;
 stars9X = 550;
 stars9Y = 113;
 stars10X = 310;
 stars10Y = 57;
 speed = 0;

 pointsX[0] = (int) (screenWidth * 0.39351851851851855);
 pointsX[1] = (int) (screenWidth * 0.25925925925925924);
 pointsX[2] = (int) (screenWidth * 0.46296296296296297);
 pointsX[3] = (int) (screenWidth * 0.2222222222222222);
 pointsX[4] = (int) (screenWidth * 0.37037037037037035);
 pointsX[5] = (int) (screenWidth * 0.5);
 pointsX[6] = (int) (screenWidth * 0.3055555555555556);
 pointsX[7] = (int) (screenWidth * 0.5);
 pointsX[8] = (int) (screenWidth * 0.3472222222222222);
 pointsX[9] = (int) (screenWidth * 0.5092592592592593);
 pointsX[10] = (int) (screenWidth * 0.28703703703703703);

 // pointsX[0] = stars0X;
 // pointsX[1] = stars1X;
 // pointsX[2] = stars2X;
 // pointsX[3] = stars3X;
 // pointsX[4] = stars4X;
 // pointsX[5] = stars5X;
 // pointsX[6] = stars6X;
 // pointsX[7] = stars7X;
 // pointsX[8] = stars8X;
 // pointsX[9] = stars9X;
 // pointsX[10] = stars10X;

 pointsX[11] = pointsX[0];
 pointsX[12] = pointsX[1];
 pointsX[13] = pointsX[2];
 pointsX[14] = pointsX[3];
 pointsX[15] = pointsX[4];
 pointsX[16] = pointsX[5];
 pointsX[17] = pointsX[6];
 pointsX[18] = pointsX[7];
 pointsX[19] = pointsX[8];
 pointsX[20] = pointsX[9];
 pointsX[21] = pointsX[10];

 pointsY[0] = stars0Y;
 pointsY[1] = stars1Y;
 pointsY[2] = stars2Y;
 pointsY[3] = stars3Y;
 pointsY[4] = stars4Y;
 pointsY[5] = stars5Y;
 pointsY[6] = stars6Y;
 pointsY[7] = stars7Y;
 pointsY[8] = stars8Y;
 pointsY[9] = stars9Y;
 pointsY[10] = stars10Y;

 // pointsY[0] = (int) (screenHeight * 0.6145833333333334);
 // pointsY[1] = (int) (screenHeight * 0.5546875);
 // pointsY[2] = (int) (screenHeight * 0.5036458333333333);
 // pointsY[3] = (int) (screenHeight * 0.43854166666666666);
 // pointsY[4] = (int) (screenHeight * 0.3963541666666667);
 // pointsY[5] = (int) (screenHeight * 0.3411458333333333);
 // pointsY[6] = (int) (screenHeight * 0.27395833333333336);
 // pointsY[7] = (int) (screenHeight * 0.22447916666666667);
 // pointsY[8] = (int) (screenHeight * 0.12760416666666666);
 // pointsY[9] = (int) (screenHeight * 0.058854166666666666);
 // pointsY[10] = (int) (screenHeight * 0.0296875);

 pointsY[11] = pointsY[0] - (bmpBackGround1.getHeight());
 pointsY[12] = pointsY[1] - (bmpBackGround1.getHeight());
 pointsY[13] = pointsY[2] - (bmpBackGround1.getHeight());
 pointsY[14] = pointsY[3] - (bmpBackGround1.getHeight());
 pointsY[15] = pointsY[4] - (bmpBackGround1.getHeight());
 pointsY[16] = pointsY[5] - (bmpBackGround1.getHeight());
 pointsY[17] = pointsY[6] - (bmpBackGround1.getHeight());
 pointsY[18] = pointsY[7] - (bmpBackGround1.getHeight());
 pointsY[19] = pointsY[8] - (bmpBackGround1.getHeight());
 pointsY[20] = pointsY[9] - (bmpBackGround1.getHeight());
 pointsY[21] = pointsY[10] - (bmpBackGround1.getHeight());

 for (int i = 0; i < 11; i++) {
  double x = (double) pointsX[i] / screenWidth;
  DecimalFormat df = new DecimalFormat("0.00");// 格式化小数,.后跟几个零代表几位小数
  LogUtils.d("比例 i " + i + " x = " + x);
 }
 for (int i = 0; i < 11; i++) {
  double y = (double) pointsY[i] / screenHeight;
  DecimalFormat df = new DecimalFormat("0.00");// 格式化小数,.后跟几个零代表几位小数
  LogUtils.d("比例 i " + i + " y = " + y);
 }
 // float y = (float) 10 / screenHeight;
 // float x = (float) 10 / screenWidth;

 // LogUtils.d("比例 i 10 x = " + x + "比例 i 10 y = " +
 // y);
 }

 private void speedStarsXY() {
 for (int i = 0; i < 22; i++) {
  pointsY[i] += speed;
 }

 }

 private void setStartsXYDown(int type) {
 // LogUtils.d("pointy 0 之前= " + pointsY[0]);
 // LogUtils.d("pointy 11之前 = " + pointsY[11]);
 if (type == 0) {
  for (int i = 0; i < 11; i++) {

  int p = pointsY[i + 11];
  pointsY[i] = p - (bmpBackGround1.getHeight());
  // LogUtils.d("改变 后的 pointsY[" + i + "] = " + pointsY[i]);
  }

 } else {
  for (int i = 0; i < 11; i++) {
  // LogUtils.d("向下的第二种 pointsY[i+ 11] " + (pointsY[i] -
  // (bmpBackGround1.getHeight())));
  int p = pointsY[i];
  pointsY[i + 11] = p - (bmpBackGround1.getHeight());
  // LogUtils.d("改变 后的 向下的第二种 pointsY[" + i + "] = " +
  // pointsY[i]);
  }
 }
 }

 private void setStartsXYUp(int type) {
 if (type == 0) {
  for (int i = 0; i < 11; i++) {
  pointsY[i] = pointsY[i + 11] + (bmpBackGround1.getHeight());
  }
 } else {
  for (int i = 0; i < 11; i++) {
  pointsY[i + 11] = pointsY[i] + (bmpBackGround1.getHeight());
  }
 }
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
 // 获取当前触控位置
 // LogUtils.d("触摸事件 event.getAction() = " + event.getAction());
 int x = (int) event.getX();
 int y = (int) event.getY();

 boolean isDown;
 switch (event.getAction()) {

 case MotionEvent.ACTION_DOWN:// 当用户是按下
  pointX = x;
  pointY = y;
  mDownX = (int) event.getX();
  mDownY = (int) event.getY();
  LogUtils.d(" 按下的 点 x = " + pointX + " y = " + pointY);
  // LogUtils.d(" 按下的 点的比例 x = " + (double) pointX / screenWidth +
  // " y = " + (double) pointY / screenHeight);
  break;
 case MotionEvent.ACTION_MOVE:// 移动
  // LogUtils.d("init moveY " + moveY);
  tempy1 = moveY;

  moveY = (int) event.getY();

  speed = moveY - tempy1;

  // 判断向上移动还是向下移动
  if (speed > 0) {
  isDown = true;
  } else {
  isDown = false;
  }
  logic(isDown);// 计算点的距离
  // LogUtils.d("pointY = " + pointY + " moveY = " + moveY + " speed "
  // + (speed));
  break;
 case MotionEvent.ACTION_UP:
  moveY = 0;
  mTempX = (int) event.getX();
  mTempY = (int) event.getY();
  if (Math.abs(mTempX - mDownX) > MAX_DISTANCE_FOR_CLICK
   || Math.abs(mTempY - mDownY) > MAX_DISTANCE_FOR_CLICK) {
  // 抬起的距离 和按下的距离太远 不形成点击事件
  // LogUtils.d("起的距离 和按下的距离太远 不形成点击事件");
  } else {
  isOnclick(mTempX, mTempY);

  }

  break;
 }

 invalidate();// 刷新界面
 // 使系统响应事件,返回true
 return true;

 }

 // 添加自定义点击事件
 private boolean isOnclick(int x, int y) {
 LogUtils.d("点击了");
 if (listener != null) {
  // 判断是否点击到星星上面
  return isStarsOnclick(x, y, listener);
 } else {
  return false;
 }
 }

 private boolean isStarsOnclick(int x, int y, ScrollViewListener listener) {

 int x1;
 int y1;
 int x2;
 int y2;
 // LogUtils.d("点击 X = " + x + " 点击 Y = " + y + " 星星 X = " + pointsX[0]
 // + " 星星 y = " + pointsY[0]);
 for (int i = 0; i < 22; i++) {
  x1 = pointsX[i];
  y1 = pointsY[i];
  // LogUtils.d("比例 y 100 = " + (double) 100 / screenHeight);
  // LogUtils.d("比例 x 100 = " + (double) 100 / screenWidth);
  x2 = pointsX[i] + (int) (screenWidth * 0.09259259259259259);
  y2 = pointsY[i] + (int) (screenHeight * 0.052083333333333336);
  if (x > x1 && x < x2 && y > y1 && y < y2) {
  // LogUtils.d("点击到了");
  int current = getOnclickNo(i) + 1;
  listener.myOnclick(current);
  // LogUtils.d("点击的第几位 : " + current);
  return true;

  }
 }
 // LogUtils.d("没有点击到");

 return false;

 }

 // 判断是否到顶部了
 private void isTop() {

 if (activityNumber >= 8 && bg1y > getHeight()) {
  // LogUtils.d("当第1张图片的Y坐标超出屏幕, 图片向上的情况 activityNumber 加上的 =======到顶部= bg1y"
  // + activityNumber);
  bg1y = getHeight();
  bg2y = bg1y - bmpBackGround1.getHeight();
  speed = 0;
  speedStarsXY();
  return;
 } else {
  speedStarsXY();
 }
 }

 // 背景滚动的逻辑函数
 public void logic(boolean isDown) {

 if (isDown) {// 手指向下

  if (tempy1 != 0) {
  bg1y += speed;
  bg2y += speed;
  // LogUtils.d("isTop = " + isTop());
  isTop();
  }
  // //判断是否到顶部了
  // if (activityNumber >= 8 && bg1y > getHeight()) {
  // //LogUtils.d("当第1张图片的Y坐标超出屏幕, 图片向上的情况 activityNumber 加上的 =======到顶部= bg1y"
  // + activityNumber);
  // bg1y = getHeight();
  // bg2y = bg1y - bmpBackGround1.getHeight();
  // return;
  // }

  // LogUtils.d("bg1y = " + bg1y + " bg2y = " + bg2y +
  // " bg1y - bmpBackGround1.getHeight() = " + (bg1y -
  // bmpBackGround1.getHeight()) +
  // " -Math.abs(bmpBackGround1.getHeight() - getHeight()) = " +
  // (-Math.abs(bmpBackGround1.getHeight() - getHeight())));
  // 当第一张图片的Y坐标超出屏幕, 手指向下的情况
  // 立即将其坐标设置到第二张图的上方
  if (bg1y > getHeight()) {
  bg1y = bg2y - bmpBackGround1.getHeight();
  activityNumber += 1;
  // LogUtils.d("bg1y = " + bg1y + " getHeight = " + getHeight() +
  // " bmpBackGround1.getHeight() = " +
  // bmpBackGround1.getHeight() + " activityNumber 加上的 = " +
  // activityNumber);
  setStartsXYDown(0);
  // LogUtils.d("当第1张图片的Y坐标超出屏幕, 图片向上的情况 activityNumber 加上的 = "
  // + activityNumber);
  }
  // 当第二张图片的Y坐标超出屏幕,向下的情况
  // 立即将其坐标设置到第一张图的上方
  if (bg2y > getHeight()) {
  bg2y = bg1y - bmpBackGround1.getHeight();
  activityNumber += 1;
  // LogUtils.d("当第1张图片的Y坐标超出屏幕, 图片向上的情况 activityNumber 加上的 = "
  // + activityNumber);
  // LogUtils.d("bg1y = " + bg1y + " getHeight = " + getHeight() +
  // " bmpBackGround1.getHeight() = " +
  // bmpBackGround1.getHeight() + " activityNumber 加上的 = " +
  // activityNumber);
  setStartsXYDown(1);
  }

 } else {

  // 当第一张图片的Y坐标超出屏幕, 手指向上的情况
  // 立即将其坐标设置到第二张图的下方
  if (tempy1 != 0) {
  bg1y += speed;
  bg2y += speed;
  // //判断是否到底部
  isBottom();
  }
  // LogUtils.d("bg1y = " + bg2y + " bg2y = " + bg2y +
  // " bg1y - bmpBackGround1.getHeight() = " + (bg1y -
  // bmpBackGround1.getHeight()) +
  // " -Math.abs(bmpBackGround1.getHeight() - getHeight()) = " +
  // (-Math.abs(bmpBackGround1.getHeight() - getHeight())));
  if (bg1y < -Math.abs(bmpBackGround1.getHeight() - getHeight())) {
  if (bg2y < bg1y) {
   activityNumber -= 1;
   setStartsXYUp(1);
   // LogUtils.d("当第1张图片的Y坐标超出屏幕, 图片向下的情况 activityNumber 减去的 = "
   // + activityNumber);
  }
  bg2y = bg1y + bmpBackGround1.getHeight();// 换屏了 首尾相接
  }
  if (bg2y < -Math.abs(bmpBackGround1.getHeight() - getHeight())) {
  if (bg1y < bg2y) {// 当换图的时候 给减一
   activityNumber -= 1;
   setStartsXYUp(0);
   // LogUtils.d("当第二张图片的Y坐标超出屏幕, 图片向下的情况 activityNumber 减去的 = "
   // + activityNumber);
  }
  bg1y = bg2y + bmpBackGround1.getHeight();
  }

 }
 }

 private void isBottom() {
 int treeHeight = bmpBackGround1.getHeight() - getHeight();

 if (treeHeight < 0) {
  if (activityNumber <= 2
   && bg1y < Math
    .abs(bmpBackGround1.getHeight() - getHeight())) {// 如果是一开始的
          // 到底部时
          // 不能滑动
          // 并且重置
          // 坐标点
  activityNumber = 2;
  bg1y = Math.abs(bmpBackGround1.getHeight() - getHeight());
  // 第二张背景图紧接在第一张背景的上方
  // 直接连接不和谐,为了让视觉看不出是两张图连接而修正的位置
  bg2y = bg1y - bmpBackGround1.getHeight();
  initStartsXY();
  return;
  } else {
  speedStarsXY();
  // LogUtils.d("pointy speedStarsXY 11之后 = " + pointsY[11]);
  }
 } else {
  if (activityNumber <= 2
   && bg1y < -Math.abs(bmpBackGround1.getHeight()
    - getHeight())) {// 如果是一开始的 到底部时 不能滑动 并且重置 坐标点
  activityNumber = 2;
  bg1y = -Math.abs(bmpBackGround1.getHeight() - getHeight());

  // 第二张背景图紧接在第一张背景的上方
  // +101的原因:虽然两张背景图无缝隙连接但是因为图片资源头尾
  // 直接连接不和谐,为了让视觉看不出是两张图连接而修正的位置
  bg2y = bg1y - bmpBackGround1.getHeight();
  initStartsXY();
  return;
  } else {
  speedStarsXY();
  // LogUtils.d("pointy speedStarsXY 11之后 = " + pointsY[11]);
  }
 }
 }

 private void initBgView() {
 int treeHeight = bmpBackGround1.getHeight() - getHeight();

 if (treeHeight < 0) {
  activityNumber = 2;
  bg1y = Math.abs(bmpBackGround1.getHeight() - getHeight());
  // 第二张背景图紧接在第一张背景的上方
  // 直接连接不和谐,为了让视觉看不出是两张图连接而修正的位置
  bg2y = bg1y - bmpBackGround1.getHeight();
  initStartsXY();
  return;
 } else {
  activityNumber = 2;
  bg1y = -Math.abs(bmpBackGround1.getHeight() - getHeight());
  // 第二张背景图紧接在第一张背景的上方

  bg2y = bg1y - bmpBackGround1.getHeight();
  initStartsXY();
  return;
 }
 }

}

源码下载:Android仿开心消消乐游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android 使用ViewPager自动滚动循环轮播效果

    对Android 利用ViewPager实现图片可以左右循环滑动效果,感兴趣的朋友可以直接点击查看内容详情. 主要介绍如何实现ViewPager自动播放,循环滚动的效果及使用.顺便解决ViewPager嵌套(ViewPager inside ViewPager)影响触摸滑动及ViewPager滑动速度设置问题. 先给大家展示下效果图,喜欢的朋友可以下载源码: 1.实现 没有通过ScheduledExecutorService或Timer定期执行某个任务实现,而是简单的通过handler发送消息去

  • Android ViewPager实现智能无限循环滚动回绕效果

    android系统提供的ViewPager标准方式是左右可以自由滑动,但是滑动到最左边的极限位置是第一个page,滑动到最右边的位置是最后一个page,当滑动到最左或者最右时候,就不能再滑动/滚动了,这是Android系统默认的ViewPager实现方式. 但是有些情况下开发者可能希望ViewPager能够智能的无限循环滚动回绕,比如现在总共有编号1, 2, 3, 4, 5的5个Page. (1)当用户手指从右往左滚动到最右边/最后面的页面5时候,如果此时用户继续拖住ViewPager往左边滑动

  • Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件

    最近用到需要无限轮播自动播放的轮播轮播图,网上感觉都有这样那样的问题,于是自己写了一个通用的控件CarouselFigureView. 特点: 1.可以轮播view可以自己定义,不一定是要是ImageView2.指示器默认显示,但是可以隐藏3.可以设置指示器的颜色.间距.大小 4.有基础的可以自己修改代码改变指示器位置,这个应该不难5.可以自己开启和关闭自动轮播,开启轮播的时候可以设置轮播时间间隔,默认3000毫秒 我们先来看看效果图: 然后来看看使用代码 xml代码 <?xml version

  • Android ViewPager实现无限循环效果

    最近项目里有用到ViewPager来做广告运营位展示,看到现在很多APP的广告运营位都是无限循环的,所以就研究了一下这个功能的实现. 先看看效果 从一个方向上一直滑动,么有滑到尽头的感觉,具体是怎么实现的呢?看下面的思路. 实现思路 此处画了一幅图来表达实现无限循环的思路,即在数据起始位置前插入最后一项数据,在最后一项数据后插入第一项数据,当滑动到此处时,更新页面的索引位置就ok了 . 代码实现 这个方法用于数据处理,其中mediaList是原始数据,newMediaList是处理完的数据,mM

  • Android实战打飞机游戏之无限循环的背景图(2)

    首先分析下游戏界面内的元素: 无限滚动的背景图, 可以操作的主角,主角的子弹, 主角的血量,两种怪物(敌机),一个boss, boss的爆炸效果. 先看效果图 1.首先实现无限滚动的背景图 原理: 定义两个位图对象 当第一个位图到末尾是 第二个位图从第一个位图的末尾跟上. public class GameBg { // 游戏背景的图片资源 // 为了循环播放,这里定义两个位图对象, // 其资源引用的是同一张图片 private Bitmap bmpBackGround1; private B

  • Android 使用viewpager实现无限循环(定时+手动)

    循环轮播的方法有两种,一种是使用定时器另外一种是使用手指拨动,相比较而言,定时器实现循环播放比较容易,只要在定时器的消息里加上简单几段代码即可,下面分别就这两种方法给大家详解,具体详情请看下文吧. int count = adapter.getCount(); if (count > 1) { // 多于1个,才循环 int index = viewPager.getCurrentItem(); index = (index + 1) % count; viewPager.setCurrentI

  • Android viewpager中动态添加view并实现伪无限循环的方法

    本文实例讲述了Android viewpager中动态添加view并实现伪无限循环的方法.分享给大家供大家参考,具体如下: viewpager的使用,大家都熟悉,它可以实现页面之间左右滑动的切换,这里有一个需求,就是viewpager里面加载的页数不是确定的,而是根据数据的多少来确定的.常见的应用就是在一个新闻的详细页面中,显示与此新闻有关的图片. 下面我们来看一下代码: activity_main.xml <RelativeLayout xmlns:android="http://sch

  • Android实现带指示点的自动轮播无限循环效果

    想要实现无限轮播,一直向左滑动,当到最后一个view时,会滑动到第一个,无限- 可以自己写ViewPager然后加handler先实现自动滚动,当然这里我为了项目的进度直接使用了Trinea的Android-auto-scroll-view-pager库,网址:点击进入github 引用库compile('cn.trinea.android.view.autoscrollviewpager:android-auto-scroll-view-pager:1.1.2') { exclude modu

  • Android简单实现无限滚动自动滚动的ViewPager

    经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个ViewPager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底.所以试着封装一个比较好用的ViewPager 效果如下: 简单的说一下实现思路,要实现无限滚动的话就要在PagerAdapter上面做一些手脚,在PagerAdapter的getCount的函数的返回值设置成Integer.MXA_VALUE就可以实现向右无限滚动,但是要实现向左无限滚动呢?就是一开始的时候setCurrentItem的时

  • Android ViewPager无限循环实现底部小圆点动态滑动

    页面拖动到最后一页 再向下滑动回复到 第一页,第一页向前滑动回到 最后一页 同时,底部红色小圆点随着页面的滑动距离比例随时改变位置 布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas

随机推荐