android星空背景实现,一个Android自定义背景视图,通过触摸绘制类星空背景图

这篇博客介绍了如何创建一个自定义视图BackgroundView,该视图使用手势识别进行交互,模拟canvas中的绘图效果。作者通过在Android平台上实现一个View,利用随机点和线的动态移动,创建出类似canvas-nest.js的效果。同时,博客详细讲解了如何处理触摸事件,包括手势的监听和处理,以及视图的重绘机制。
摘要由CSDN通过智能技术生成

/**

* Created by lz on 2016/7/24.

* github地址:https://github.com/lzuntalented/BackgroundView

* 自定义背景视图

*

* 参考canvas中就是绘图,地址:https://github.com/hustcc/canvas-nest.js

*/

public class BackgroundView extends View implements View.OnTouchListener,GestureDetector.OnGestureListener {

private List mlist = new ArrayList<>();//存储多次点击事件的响应

private int lineCount = 99;//屏幕出现的点数量

private Context mContext;

private List random_lines = new ArrayList<>();//屏幕出现的点集合

private GestureDetector mGestureDetector = null;

private LineConfig currentDown = new LineConfig();//触摸点

private int color_point = Color.argb(100, 255, 255, 255);//点的颜色

private int color_line = Color.argb(100,255,0,0);//线的颜色

public BackgroundView(Context context) {

super(context);

mContext = context;

init();

}

public BackgroundView(Context context, AttributeSet attrs) {

super(context, attrs);

mContext = context;

init();

}

public BackgroundView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mContext = context;

init();

}

/**

* 初始化

*/

private void init(){

currentDown.max = 100000;//触摸点与其他点连线的最大距离

/*添加手势监听*/

mGestureDetector = new GestureDetector(mContext, this);

this.setOnTouchListener(this);

this.setLongClickable(true);

WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

int width = wm.getDefaultDisplay().getWidth();

int height = wm.getDefaultDisplay().getHeight();

/*初始化点集合*/

for(int i=0; i < lineCount ; ++i){

LineConfig l = new LineConfig();

l.x = (float) (Math.random() * width);

l.y = (float) (Math.random() * height);

l.xa = (float) (Math.random() * 2 - 1);

l.ya = (float) (Math.random() * 2 - 1);

l.max = 15000;

random_lines.add(l);

}

/*添加触摸点到集合*/

random_lines.add(currentDown);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

int canvas_width = wm.getDefaultDisplay().getWidth();

int canvas_height = wm.getDefaultDisplay().getHeight();

Paint paint_blue = new Paint();

paint_blue.setStyle(Paint.Style.STROKE);

paint_blue.setStrokeWidth(1);

float d, x_dist, y_dist, dist;

for(int i = 0; i < random_lines.size() ; i ++ ){

LineConfig r = random_lines.get(i);

r.x += r.xa;

r.y += r.ya; //移动

r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1;

r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1; //碰到边界,反向反弹

paint_blue.setColor(color_point);

canvas.drawCircle(r.x, r.y, 1, paint_blue);

for(int j = i + 1; j < random_lines.size() ; j ++ ){

LineConfig e = random_lines.get(j);

x_dist = r.x - e.x; //x轴距离

y_dist = r.y - e.y; //y轴距离

dist = x_dist * x_dist + y_dist * y_dist; //总距离

if(dist < e.max){

if(e.touch && dist >= e.max / 2){

r.x -= 0.03 * x_dist;

r.y -= 0.03 * y_dist; //靠近的时候加速

}

paint_blue.setColor(color_line);

canvas.drawLine(r.x,r.y,e.x,e.y,paint_blue);

}

}

}

new DrawThread().start();//启动定时线程绘制

}

/**

* 重写触摸监听事件,

* 将添加的触摸事件添加到集合中

* 防止外部对此视图再次添加事件导致触摸点无效

*/

@Override

public void setOnTouchListener(OnTouchListener l) {

mlist.add(l);

super.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

for (int i = 0; i < mlist.size(); ++i) {

OnTouchListener ml = mlist.get(i);

if (ml.onTouch(v, event)) {

return true;

}

}

return false;

}

});

}

@Override

public boolean onTouch(View v, MotionEvent event) {

mGestureDetector.onTouchEvent(event);//分发手势通知

return false;

}

@Override

public boolean onDown(MotionEvent e) {

currentDown.touch = true;

return false;

}

@Override

public void onShowPress(MotionEvent e) {

}

@Override

public boolean onSingleTapUp(MotionEvent e) {

currentDown.touch = false;

return false;

}

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

currentDown.x = e2.getX();//记录触摸点坐标

currentDown.y = e2.getY();//记录触摸点坐标

return false;

}

@Override

public void onLongPress(MotionEvent e) {

}

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

return false;

}

/**

* 定时通知绘制线程

* */

private class DrawThread extends Thread{

@Override

public void run() {

super.run();

try {

sleep(1000 / 45);//每秒绘制45次

mHandler.sendEmptyMessage(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

/**绘图通知handler*/

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if(msg.what == 1) draw_canvas();

}

};

/**

* 重绘视图通知

*/

private void draw_canvas() {

this.invalidate();

}

/**

* 屏幕点对象

* */

private class LineConfig{

public float x;//x左标

public float y;//y左标

public float xa;//x增量

public float ya;//y增量

public float max;//两点间最大距离,超过此距离不再绘制线段

public boolean touch = false;//标示是否为触摸点

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个使用和EasyX画星空背景的示例代码: ```c++ #include <graphics.h> #include <time.h> const int WIDTH = 800; // 窗口宽度 const int HEIGHT = 600; // 窗口高度 const int STAR_NUM = 100; // 星星数量 // 星星 class Star { public: Star() { x = rand() % WIDTH; // 随机生成初始位置 y = rand() % HEIGHT; size = rand() % 3 + 1; // 随机生成大小 color = RGB(255, 255, 255); // 白色 } // 绘制星星 void draw() { setfillcolor(color); solidcircle(x, y, size); } // 移动星星 void move() { x -= size; // 每帧向左移动 if (x < 0) { x = WIDTH; } } private: int x, y; // 位置 int size; // 大小 COLORREF color; // 颜色 }; int main() { // 初始化窗口 initgraph(WIDTH, HEIGHT); // 随机生成星星 Star stars[STAR_NUM]; srand(time(NULL)); for (int i = 0; i < STAR_NUM; i++) { stars[i] = Star(); } // 绘制星空背景 while (true) { // 清空画布 cleardevice(); // 绘制星星 for (int i = 0; i < STAR_NUM; i++) { stars[i].draw(); stars[i].move(); } // 刷新画面 Sleep(20); // 暂停一段时间,降低帧率,模拟星空中的恒星 flushbatch(); // 批量刷新,提高性能 } // 关闭窗口 closegraph(); return 0; } ``` 这个程序会随机生成一些星星,并在窗口中绘制它们。每帧,星星会向左移动一定的距离,当移出窗口时会重新出现在窗口右侧。 你可以根据需要调整窗口大小、星星数量和移动速度等参数。运行程序后,你应该能够看到一个闪烁的星空背景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值