程序员表白程序,开放源码,不断更新
2014-12-18 09:07
821 查看
摘要: 程序员表白程序,开放源码,不断更新
这是我为自己写的一款表白的程序,几经努力把它完成为一个完整的程序,这是我准备完成的程序之爱系列第一辑,希望能多做几辑吧。
源码地址:https://github.com/wuxia2001/mylove.git
APK地址:http://zhushou.360.cn/detail/index/soft_id/1380324
先上图吧
一共三个主界面和一个设置界面,主界面都是用surfaceview画出来的。三个界面都是自己设计的,作为一个程序员,非美工,就不要对我的美术素养太苛刻了哈!
每个界面都有底层背景,加背景的方法:
第一个界面,楚楚这两个字是用爱心一点点渐现出来的,在这里,画出字有两种方法,第一种,是我用awt得到的字的坐标,然后保存在文件里,再从文件里读出坐标,从而画出字。
生成坐标的代码如下,这部分代码只能在电脑上运行,不能移植到手机端,所以这种方法只能用来显示事先设计好的字,但这种方法写出来的字效果去很好。代码如下
直接进行调用 zi("楚","array_chu.txt",font,-1,17,20,20);就可以得坐标。
在手机端读出来并写出来的代码如下:
第二种方法就是点阵字符集,我程序中,如果设置的字不是内定的那寥寥几个,就会用点阵字符,点阵字符分16*16,24*24,32*32,48*48,我代码里有前三种,每种字体又分为黑体宋体楷体等几种,在经过每一种尝试后,我最终选择的24HZKS,代码里每一种都有代码,大家也可以对每种进行测试,如果只要适应一款分辨率的话,会有更好的适配字体,我这是为了适应大多数的分辨率选的这种。24*24的代码如下,
这段代码可以得到字体的坐标,16和32的就是
三个参数不一样而己。
用坐标系画字大体差不多,代码如下
画出爱心,最主要得到爱心的坐标就可以了,具体可参照:http://love.hackerzhou.me/
第一界面就差不多了,一些花边就没必要说了。
第二个界面,要说的也不多,那个一点点画出来的大的爱心是从PC端上移植过去的,但我感觉那个爱心不太圆满,也没时间去修正了,但要注意的是画这个爱心的时候容易发生闪烁,我还是把代码贴出来吧,
第三个界面,如果有几张仙女连贯的动态图就好了,可惜我不是美工,尽管这整套都是我自己设计实现的,但不是美工无法设计出仙女散爱心的连续图,于是只能是晃啊晃啊然后爱心下落,下落后可以漂往左边或右边,并程抛物线飞行。
爱心变大,星星闪烁,花朵移动都在一个线程里:
至于字的显现,应该没什么好说,值得注意的是,还有一些闪烁的爱心和下缀的那一段,要注意这些坐标,不能覆盖字,要处理所有出现的心的坐标,和字的坐标。
另外,还有播放声音的功能,可以自己设置合适的音乐或者自己录好自己想说的话然后播放出来。
源码还在不断修改更新中,随意拿去自用。
这是我为自己写的一款表白的程序,几经努力把它完成为一个完整的程序,这是我准备完成的程序之爱系列第一辑,希望能多做几辑吧。
源码地址:https://github.com/wuxia2001/mylove.git
APK地址:http://zhushou.360.cn/detail/index/soft_id/1380324
先上图吧
一共三个主界面和一个设置界面,主界面都是用surfaceview画出来的。三个界面都是自己设计的,作为一个程序员,非美工,就不要对我的美术素养太苛刻了哈!
每个界面都有底层背景,加背景的方法:
//外面加背景 l1.setBackgroundResource(R.drawable.q2); //Surfaceview做设置 //透明 setZOrderOnTop(true); holder.setFormat(PixelFormat.TRANSPARENT);
第一个界面,楚楚这两个字是用爱心一点点渐现出来的,在这里,画出字有两种方法,第一种,是我用awt得到的字的坐标,然后保存在文件里,再从文件里读出坐标,从而画出字。
生成坐标的代码如下,这部分代码只能在电脑上运行,不能移植到手机端,所以这种方法只能用来显示事先设计好的字,但这种方法写出来的字效果去很好。代码如下
/** * 要写的字,我这里只试过单字,要保存的文件名,字体,调整X和Y位置,宽和高 * @param zi * @param filename * @param font * @param outx * @param outy * @param w * @param h */ public static void zi(String zi, String filename, Font font, int outx,int outy,int w,int h){ try { //张 黑体,30号字。w40 h 29 array_zhang //晚 黑体 30 //I 宋体 30号。 w12 h24 array_I //U 宋体 30 号粗 w17 h24 array_U //Font font = new Font("黑体", Font.PLAIN, 30); AffineTransform at = new AffineTransform(); FontRenderContext frc = new FontRenderContext(at, true, true); GlyphVector gv = font.createGlyphVector(frc, zi); // 要显示的文字 Shape shape = gv.getOutline(outx,outy); int weith = w; int height = h; boolean[][] view = new boolean[weith][height]; for (int i = 0; i < weith; i++) { for (int j = 0; j < height; j++) { if (shape.contains(i, j)) { view[i][j] = true; } else { view[i][j] = false; } //if(i == 7 && j>=3 && j<=6) view[i][j] = true; //if(i == 6 && j == 8) view[i][j] = true; } } for (int j = 0; j < height; j++) { for (int i = 0; i < weith; i++) { if (view[i][j]) { System.out.print("@");// 替换成你喜欢的图案 } else { System.out.print(" "); } } System.out.println(); } File file = new File(filename); //存放数组数据的文件 FileWriter out = new FileWriter(file); //文件写入流 //将数组中的数据写入到文件中。每行各数据之间TAB间隔 for(int j=0;j<height;j++){ for(int i=0;i<weith;i++){ if(view[i][j]) out.write(1+"b"); else out.write(0+"b"); } out.write("n"); } out.close(); } catch (Exception e) { e.printStackTrace(); } }
直接进行调用 zi("楚","array_chu.txt",font,-1,17,20,20);就可以得坐标。
在手机端读出来并写出来的代码如下:
// 花 type 1为花,2为爱心 /** * 开始x,开始Y坐标,字的宽,高,文件名字,放大倍数,type为图片种类 * @param stx * @param sty * @param w * @param h * @param filename * @param beishu * @param type */ public void show_I(int stx, int sty, int w, int h, String filename, int beishu, int type) { int startx = stx, starty = sty; try { int weith = w; int height = h; boolean[][] arr = new boolean[weith][height]; // 插入的数组 String file = filename; InputStream ins = Util.init().getAssetsInputStream(mContext, file); BufferedReader in = new BufferedReader(new InputStreamReader(ins)); // String line; // 一行数据 int row = 0; // 逐行读取,并将每个数组放入到数组中 StringBuilder sb = new StringBuilder(); while ((line = in.readLine()) != null) { sb.append(line); } System.out.println(sb.toString()); in.close(); String all = sb.toString(); String[] all_a = all.split("n"); //先得到坐标 for (int i = 0; i < all_a.length; i++) { String[] all_b = all_a[i].split("b"); System.out.println(); for (int j = 0; j < all_b.length; j++) { if (all_b[j].equals("0")) { arr[j][i] = false; } else arr[j][i] = true; } } int bei = beishu; int dis = 25; int old_num = -1; for (int j = 0; j < height && !isallstop; j++) { for (int i = 0; i <= weith && !isallstop; i++) { //一定要sleep,要不然其他线程画不了东西 Thread.sleep(25); Random rm = new Random(); Bitmap bitmap = null; int num = 0; if (type == 1) { num = rm.nextInt(heart_all.length - 1); bitmap = bitmapcache .getBitmap(heart_all[num], mContext); } else if (type == 2) { bitmap = bitmapcache.getBitmap(R.drawable.love, mContext); } int bw = bitmap.getWidth(); int bh = bitmap.getHeight(); if (i >= weith && !isallstop) { synchronized (holder) { Canvas c = null; try { float xx = (float) i; float yy = (float) j; //不要轻易去锁定整个屏幕 c = holder.lockCanvas(new Rect(startx + (int) xx * bei, starty + (int) yy * bei, startx + (int) xx * bei + dis, starty + (int) yy * bei + dis)); // c = holder.lockCanvas(); Paint p = new Paint(); // 创建画笔 p.setColor(Color.RED); //下面这段是保证双缓冲能都画上东西,从而不会闪烁 if (i > 0 && !isallstop) { int xx_b = i - 1; int yy_b = j; if (arr[xx_b][yy_b]) { if (old_num != -1) { if (type == 1) c.drawBitmap(bitmapcache.getBitmap( heart_all[old_num], mContext), startx + xx_b * bei, starty + yy_b * bei, p); else if (type == 2) { c.drawBitmap(bitmapcache.getBitmap( R.drawable.love, mContext), startx + xx_b * bei, starty + yy_b * bei, p); } } } } if (arr[i][j] && !isallstop) { c.drawBitmap(bitmap, startx + xx * bei, starty + yy * bei, p); } old_num = num; } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ <span style="white-space:pre"> </span>holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } } } } catch (Exception e) { e.printStackTrace(); } }
第二种方法就是点阵字符集,我程序中,如果设置的字不是内定的那寥寥几个,就会用点阵字符,点阵字符分16*16,24*24,32*32,48*48,我代码里有前三种,每种字体又分为黑体宋体楷体等几种,在经过每一种尝试后,我最终选择的24HZKS,代码里每一种都有代码,大家也可以对每种进行测试,如果只要适应一款分辨率的话,会有更好的适配字体,我这是为了适应大多数的分辨率选的这种。24*24的代码如下,
public class Font24 { private Context context; public Font24(Context context){ this.context = context; } private final static int[] mask = {128, 64, 32, 16, 8, 4, 2, 1}; private final static String ENCODE = "GB2312"; private final static String ZK16 = "Hzk24s"; private boolean[][] arr; int all_16_32 = 24; int all_2_4 = 3; int all_32_128 = 72; public boolean[][] drawString(String str){ byte[] data = null; int[] code = null; int byteCount;//到点阵数据的第几个字节了 int lCount;//控制列 arr = new boolean[all_16_32][all_16_32]; // 插入的数组 //g.setColor(color); for(int i = 0;i < str.length();i ++){ if(str.charAt(i) < 0x80){//非中文 //g.drawString(str.substring(i,i+1),x+(i<<4),y,0); continue; } code = getByteCode(str.substring(i,i+1)); data = read(code[0],code[1]); byteCount = 0; for(int line = 0;line < all_16_32;line ++){ lCount = 0; for(int k = 0;k < all_2_4;k ++){ for(int j = 0;j < 8;j ++){ // if((data[byteCount]&mask[j])==mask[j]){ if (((data[byteCount] >> (7 - j)) & 0x1) == 1) { arr[line][lCount] = true; System.out.print("@"); }else{ System.out.print(" "); arr[line][lCount] = false; } lCount++; } byteCount ++; } System.out.println(); } } return arr; } /** *读取文字信息 *@param areaCode 区码 *@param posCode 位码 *@return 文字数据 */ protected byte[] read(int areaCode,int posCode){ byte[] data = null; try{ int area = areaCode-0xa0;//获得真实区码 int pos = posCode-0xa0;//获得真实位码 //InputStream in = getClass().getResourceAsStream(ZK32); InputStream in = Util.init().getAssetsInputStream(context, ZK16); long offset = all_32_128*((area-1)*94+pos-1); in.skip(offset); data = new byte[all_32_128]; in.read(data,0,all_32_128); in.close(); }catch(Exception ex){ } return data; } /** *获得文字的区位码 *@param str *@return int[2] */ protected int[] getByteCode(String str){ int[] byteCode = new int[2]; try{ byte[] data = str.getBytes(ENCODE); byteCode[0] = data[0] < 0?256+data[0]:data[0]; byteCode[1] = data[1] < 0?256+data[1]:data[1]; }catch(Exception ex){ ex.printStackTrace(); } return byteCode; } }
这段代码可以得到字体的坐标,16和32的就是
int all_16_32 = 24; int all_2_4 = 3; int all_32_128 = 72;
三个参数不一样而己。
用坐标系画字大体差不多,代码如下
/** * 16/24/32,要写的字符,开始的x,y,倍数,花或爱心 * @param font_kind * @param s * @param stx * @param sty * @param beishu * @param type */ public void show_font16_24_32(int font_kind,String s, int stx, int sty, int beishu, int type) { boolean[][] arr = null; int weith = 16; int height = 16; if(font_kind == 16){ weith = 16; height = 16; arr = new boolean[weith][height]; Font16 font16 = new Font16(mContext); arr = font16.drawString(s); }else if(font_kind == 24){ weith = 24; height = 24; arr = new boolean[weith][height]; Font24 font24 = new Font24(mContext); arr = font24.drawString(s); }else { weith = 32; height = 32; arr = new boolean[weith][height]; Font32 font32 = new Font32(mContext); arr = font32.drawString(s); } int startx = stx, starty = sty; int bei = beishu; int old_num = -1; int lCount;// 控制列 for (int i = 0; i < weith && !isallstop; i++) { for (int j = 0; j < height && !isallstop; j++) { try { Thread.sleep(25); } catch (InterruptedException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } float xx = (float) j; float yy = (float) i; if (arr[i][j] && !isallstop) { Random rm = new Random(); Bitmap bitmap = null; int num = 0; if (type == 1) { num = rm.nextInt(heart_all.length - 1); bitmap = bitmapcache .getBitmap(heart_all[num], mContext); } else if (type == 2) { bitmap = bitmapcache.getBitmap(R.drawable.love, mContext); } int bw = bitmap.getWidth(); int bh = bitmap.getHeight(); synchronized (holder) { Canvas c = null; try { // 不要轻易去锁定整个屏幕 c = holder.lockCanvas(new Rect(startx + (int) xx * bei, starty + (int) yy * bei, startx + (int) xx * bei + bw, starty + (int) yy * bei + bh)); // c = holder.lockCanvas(); Paint p = new Paint(); // 创建画笔 p.setColor(Color.RED); // 下面这段是保证双缓冲能都画上东西,从而不会闪烁 c.drawBitmap(bitmap, startx + xx * bei, starty + yy * bei, p); old_num = num; } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } }
画出爱心,最主要得到爱心的坐标就可以了,具体可参照:http://love.hackerzhou.me/
private void run_hua_heart() { // TODO 自动生成的方法存根 int startx = sw / 2 - 16, starty = sh / 2 - 68; int maxh = 100; int y_dao = starty; double begin = 10; // 起始位置 Random rm = new Random(); int old_num = -1; float old_xx = 0, old_yy = 0; for (int i = 0; i < maxh && !isallstop; i++) { try { Thread.sleep(80); } catch (InterruptedException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } int hua_num = rm.nextInt(18); Bitmap bit = bitmapcache .getBitmap(heart_all[hua_num], mContext); begin = begin + 0.2; //密度 double b = begin / Math.PI; double a = 13.5 * (16 * Math.pow(Math.sin(b), 3)); //这里的13.5可以控制大小 double d = -13.5 * (13 * Math.cos(b) - 5 * Math.cos(2 * b) - 2 * Math.cos(3 * b) - Math.cos(4 * b)); synchronized (holder) { Canvas c = null; try { float xx = (float) a; float yy = (float) d; c = holder.lockCanvas(new Rect( (int) (startx + xx - 40), (int) (starty + yy - 40), (int) (startx + xx + 40), (int) (starty + yy + 40))); Paint p = new Paint(); // 创建画笔 p.setColor(Color.RED); //画上一个,要不然会闪烁 if (old_num != -1) { Bitmap bb = bitmapcache.getBitmap( heart_all[old_num], mContext); c.drawBitmap(bb, startx + old_xx, starty + old_yy, p); } c.drawBitmap(bit, startx + xx, starty + yy, p); old_num = hua_num; old_xx = xx; old_yy = yy; // c.drawPoint(startx+xx,starty+yy, p); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } }
第一界面就差不多了,一些花边就没必要说了。
第二个界面,要说的也不多,那个一点点画出来的大的爱心是从PC端上移植过去的,但我感觉那个爱心不太圆满,也没时间去修正了,但要注意的是画这个爱心的时候容易发生闪烁,我还是把代码贴出来吧,
public void run_heart() { int i, j; double x, y, r; int max = 180; //先计算出所有的位置,再去画图 float[][] x_ff = new float[max][max]; float[][] y_ff = new float[max][max]; for (i = 0; i < max; i++) { for (j = 0; j < max; j++) { double pi = Math.PI; r = (pi / 45 * i * (1 - (Math.sin(pi / 45 * j))) * 18); x = ((r * (Math.cos(pi / 45 * j)) * (Math.sin(pi / 45 * i)) + w / 2) * 1.01); y = ((-r * (Math.sin(pi / 45 * j)) + h / 4) * 1.01); x_ff[i][j] = (float) x; y_ff[i][j] = (float) y; } } i = 0; j = 0; for (i = 0; i < max && !isallstop; i++) { // //sleep,屏幕 try { Thread.sleep(10); // clearAll(); } catch (InterruptedException e) { // // TODO 自动生成的 catch 块 e.printStackTrace(); } Canvas c = null; int numm = 10; for (j = 0; j < max && !isallstop; j=j+numm) { synchronized (holder) { try { Paint p = new Paint(); // 创建画笔 p.setColor(Color.RED); //找出最大最小 float xx_min=x_ff[i][j], xx_max=x_ff[i][j], yy_min=y_ff[i][j], yy_max=y_ff[i][j]; for(int k =0;k<numm;k++){ float xx_n = x_ff[i][j+k]; float yy_n = y_ff[i][j+k]; if(xx_n >= xx_max) xx_max = xx_n; if(xx_n <= xx_min) xx_min = xx_n; if(yy_n >= yy_max) yy_max = yy_n; if(yy_n <= yy_min) yy_min = yy_n; } int xmin,xmax,ymin,ymax; if(xx_min == 0) xmin = 0; else xmin = (int) (xx_min-5>0?xx_min-5:0); if(yy_min == 0) ymin = 0; else ymin = (int) (yy_min-5>0?yy_min-5:0); xmax = (int) (xx_max+5); ymax = (int) (yy_max+5); //c = holder.lockCanvas(new Rect(xi,yi,xa,ya)); c = holder.lockCanvas(new Rect(xmin,ymin,xmax,ymax)); if(j!=0){ int m = j-numm; for(int k =0;k<numm;k++){ float xx_n = x_ff[i][m+k]; float yy_n = y_ff[i][m+k]; c.drawPoint(xx_n, yy_n, p); } } for(int k =0;k<numm;k++){ float xx_n = x_ff[i][j+k]; float yy_n = y_ff[i][j+k]; c.drawPoint(xx_n, yy_n, p); } } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } } } }
第三个界面,如果有几张仙女连贯的动态图就好了,可惜我不是美工,尽管这整套都是我自己设计实现的,但不是美工无法设计出仙女散爱心的连续图,于是只能是晃啊晃啊然后爱心下落,下落后可以漂往左边或右边,并程抛物线飞行。
爱心变大,星星闪烁,花朵移动都在一个线程里:
public void show(){ int ii = 30; boolean run = true; Paint p = new Paint(); //旋转的花 Bitmap hua = bitmapcache.getBitmap(R.drawable.hua, mContext); int huax = dest_x-40+xadd/2; int huay = 30; int huaw = hua.getWidth(); int huah = hua.getHeight(); int huamax = 180; int huamin = 0; int hua_add_plus = 2; int huar=0; int re_num = 0; //星 Bitmap xin1 = bitmapcache.getBitmapByLM(R.drawable.xin1, mContext,2); Bitmap xin2 = bitmapcache.getBitmapByLM(R.drawable.xin2, mContext,2); int xin1w = xin1.getWidth(); int xin1h = xin1.getHeight(); int xin2w = xin2.getWidth(); int xin2h = xin2.getHeight(); //三个星1,三个星2 ArrayList<LoveDot> xinall = new ArrayList<LoveDot>(); xinall.add(new LoveDot(1+xadd,10,1)); xinall.add(new LoveDot(48+xadd,18,1)); xinall.add(new LoveDot(110+xadd,40,1)); xinall.add(new LoveDot(20+xadd,150,2)); xinall.add(new LoveDot(150+xadd,160,2)); xinall.add(new LoveDot(130+xadd,190,2)); boolean xinboolean = true; //为真的时候画星,为假的时候擦除 int oldx = 0; while (true && !isallstop) { try { Thread.sleep(150); } catch (InterruptedException e2) { // TODO 自动生成的 catch 块 e2.printStackTrace(); } //旋转加透明 synchronized (holder) { Canvas c = null; Bitmap b2 = null; try { //c.drawColor(co); Matrix m = new Matrix(); m.setRotate(huar); p.setAlpha(255-Math.abs(huar)); b2 = Bitmap.createBitmap( hua, 0, 0, huaw,huah, m, true); c = holder.lockCanvas(new Rect(huax,huay,huax+b2.getWidth(), huay+b2.getHeight())); c.drawColor(Color.TRANSPARENT,Mode.CLEAR); c.drawBitmap(b2, huax,huay, p); //c.drawBitmap(big, dest_x, dest_y, p); huar = huar+hua_add_plus; if(huar==huamax) hua_add_plus = -2; if(huar == huamin) hua_add_plus = 2; } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } //if(b2 != null) // b2.recycle(); } } //星星闪烁 //为真的时候画星,为假的时候擦除 if(xinboolean){ LoveDot d = xinall.get(oldx); Bitmap xinb = null; int xw,xh; int xx = d.x; int yy = d.y; if(d.num == 2){ xinb = xin2; xw = xin2w; xh = xin2h; } else { xinb = xin1; xw = xin1w; xh = xin1h; } synchronized (holder) { Canvas c = null; try { c = holder.lockCanvas(new Rect(xx,yy,xx+xw,yy+xh)); p.setAlpha(255); //c.drawColor(Color.TRANSPARENT,Mode.CLEAR); c.drawBitmap(xinb, xx,yy, p); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } //oldx = thisone; xinboolean = !xinboolean; }else{ int thisone = getRandom(0, xinall.size()-1); LoveDot d = xinall.get(thisone); int xw,xh; int xx = d.x; int yy = d.y; if(d.num == 2){ //xinb = xin2; xw = xin2w; xh = xin2h; } else { //xinb = xin1; xw = xin1w; xh = xin1h; } synchronized (holder) { Canvas c = null; try { c = holder.lockCanvas(new Rect(xx,yy,xx+xw,yy+xh)); p.setAlpha(255); c.drawColor(Color.TRANSPARENT,Mode.CLEAR); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } oldx = thisone; xinboolean = !xinboolean; } re_num++; if(re_num>3){ re_num = 0; }else continue; Bitmap big15 = bitmapcache.getBitmap(R.drawable.big99, mContext); //Y为dest ,x 为dest - w/2 int bw = big15.getWidth(); int bh = big15.getHeight(); Bitmap mBitmap = Bitmap.createScaledBitmap(big15, bw-ii, bh-ii, true); bw = mBitmap.getWidth(); bh = mBitmap.getHeight(); int x = dest_x-bw/2; int y = dest_y; // dropx = x; dropy = y; //dropw = ,droph synchronized (holder) { Canvas c = null; try { c = holder.lockCanvas(new Rect(x-1,y-1,x+1+bw,y+1+bh)); p.setAlpha(255); c.drawColor(Color.TRANSPARENT,Mode.CLEAR); c.drawBitmap(mBitmap, x,y, p); //c.drawBitmap(big, dest_x, dest_y, p); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } ii--; if(ii <=0) { try { Thread.sleep(500); } catch (InterruptedException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } ii = 30; synchronized (holder) { Canvas c = null; try { c = holder.lockCanvas(new Rect(x-1,y-1,x+1+bw,y+1+bh)); //c.drawColor(co); c.drawColor(Color.TRANSPARENT,Mode.CLEAR); //c.drawBitmap(big15, x,y, p); //c.drawBitmap(big, dest_x, dest_y, p); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } if(!isallstop){ dropnum++; Thread drop = new LoveDrop(dropnum,x,y); drop.start(); dropthread_Add(dropnum, drop); //new LoveDrop(x,y).start(); } try { Thread.sleep(1500); } catch (InterruptedException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } } } } <span style="font-size:14px;">下落的代码如下</span> private void drop(){ //startx = dest_x; //starty = dest_y+10; endy = h-100; //最多下落到这 endx = startx; Bitmap llove = bitmapcache.getBitmap(R.drawable.big_h, mContext); int bw = llove.getWidth(); int bh = llove.getHeight(); Paint p = new Paint(); boolean isr = true; long de = 60; dropw = bw+1; droph = bh+1; while(isr && !isallstop){ synchronized (holder) { Canvas c = null; try { //Xfermode xFermode = new PorterDuffXfermode(Mode.DST_ATOP); //p.setXfermode(xFermode); c = holder.lockCanvas(new Rect(startx,starty-2,startx+bw,starty+bh+1)); c.drawColor(Color.TRANSPARENT,Mode.CLEAR); c.drawBitmap(llove, startx,starty++, p); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } } try { Thread.sleep(de); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } de=(long) (de-0.05); if(de <=40) de=(long) (de-0.01); if(de <=20) de = 20; if(starty >= endy && !isallstop){//准备往左右 isr = false; //结束线程 // 初始化y轴数据 int centerY = endy; //int[] Y_axis = new int[w-startx]; int left_right = getRandom(0, 10); boolean isright = true; //为真为右,为假为左,为右的机会大些 if(left_right<4){ //左 isright = false; } int le,top; int maxhh = endy - maxziy; int rmin = 80,rmax = 100; int lmin = 40,lmax = 50; if(maxhh <100 && maxhh>50 ) { rmin = 50; rmax = 60; } if(maxhh < 50){ rmin = 30; rmax = 40; lmin = 20; lmax = 30; } if(isright){ le = w-startx; top = getRandom(rmin, rmax); } else { le = startx+bw; top = getRandom(lmin,lmax); } for (int i = 1; i < le && !isallstop; i++) {// 计算正弦波 int x; if(isright) x = startx+i; else x = startx-i; //y=Asin(ωx+φ φ(初相位):决定波形与X轴位置关系或横向移动距离(左加右减) //ω:决定周期(最小正周期T=2π/|ω|) // A:决定峰值(即纵向拉伸压缩的倍数) int y = centerY-Math.abs( (int) (top * Math.sin(i * 2 * Math.PI/ 180))); synchronized (holder) { Canvas c = null; try { c = holder.lockCanvas(new Rect(x-2, y-15, x + bw+1, y + bh + 15)); c.drawColor(Color.TRANSPARENT, Mode.CLEAR); c.drawBitmap(llove, x, y, p); } catch (Exception e) { e.printStackTrace(); } finally { try{ if (c != null){ holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } }catch(Exception e){ e.printStackTrace(); } } }// sy int delay = endy - y; try { //顶峰慢,delay 大,越慢,时间长 Thread.sleep(50+delay*2); //System.out.println("y:"+y); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } }
至于字的显现,应该没什么好说,值得注意的是,还有一些闪烁的爱心和下缀的那一段,要注意这些坐标,不能覆盖字,要处理所有出现的心的坐标,和字的坐标。
另外,还有播放声音的功能,可以自己设置合适的音乐或者自己录好自己想说的话然后播放出来。
源码还在不断修改更新中,随意拿去自用。
相关文章推荐
- 程序员表白程序,开放源码,不断更新(第三篇:第二弹)
- 程序员表白程序,开放源码,不断更新(第二篇)
- 程序员表白程序,开放源码,不断更新
- 程序员表白程序,开放源码,不断更新
- 程序员表白程序,开放源码,不断更新(第二篇)
- 程序员表白程序,开放源码,不断更新
- 程序员表白程序,开放源码,不断更新(第三篇:第二弹)
- 程序员表白程序,开放源码,不断更新(第三篇:第二弹)
- 程序员表白程序,开放源码在此!
- 程序员表白程序,开放源码在此!
- 程序员表白程序,开放源码在此!
- 关于程序本身启动更新程序完成更新后再启动自己的源码
- BugNet0.7.881.0汉化免安装版源码(后续版本不断汉化更新中,敬请期待!)
- PostgreSQL存储引擎源码分析一(不断更新)
- PostgreSQL存储引擎源码分析五(原创,不断更新)
- PostgreSQL存储引擎源码分析四(原创,不断更新)
- PostgreSQL存储引擎源码分析二(原创,不断更新)
- Postgresql8.4.2源码在windows下的编译(转载,协作,不断更新)
- C#窗体程序设计小技巧(不断更新中)
- 【连载】高效程序员的45 个习惯(不断更新中。。。)