热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

程序员表白程序,开放源码,不断更新

这是我为自己写的一款表白的程序,几经努力把它完成为一个完整的程序,这是我准备完成的程序之爱系列第一辑,希望能多做几辑吧。源码地址:https:github.comwuxia2001

这是我为自己写的一款表白的程序,几经努力把它完成为一个完整的程序,这是我准备完成的程序之爱系列第一辑,希望能多做几辑吧。

源码地址:https://github.com/wuxia2001/mylove.git

APK地址:http://zhushou.360.cn/detail/index/soft_id/1380324   

(很久没更新这个软件了,因为很生气,我把这个软件放到了安卓市场里,然后居然被人给冒领了,然后怎么都弄不回来了,也不能再更新了,很生气,所以,请各位看官不要下载安卓市场的那个,下载360市场的吧。一直以来收到了很多的建议,比如太花俏,比如想再加个相册界面啊,最近准备重新再修改一番啦。)

先上图吧

                            



一共三个主界面和一个设置界面,主界面都是用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 {
for (int j = 0; 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 {
for (int i = 0; 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 for(int i=0;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 String[] all_b = all_a[i].split("b");
System.out.println();
for (int j = 0; 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 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){
holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}

} catch (Exception e) {
e.printStackTrace();
}

}

第二种方法就是点阵字符集,我程序中,如果设置的字不是内定的那寥寥几个,就会用点阵字符,点阵字符分16*1624*2432*3248*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 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 lCount = 0;
for(int k = 0;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;
}

}

这段代码可以得到字体的坐标,1632的就是

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 for (int j = 0; 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 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 for (j = 0; 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
// //sleep,屏幕
try {
Thread.sleep(10);
// clearAll();
} catch (InterruptedException e) {
// // TODO 自动生成的 catch 块
e.printStackTrace();
}
Canvas c = null;
int numm = 10;

for (j = 0; j
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 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 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 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 xinall = new ArrayList();
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();
}
}
}
}
下落的代码如下
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 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();
}
}
}
}
}

至于字的显现,应该没什么好说,值得注意的是,还有一些闪烁的爱心和下缀的那一段,要注意这些坐标,不能覆盖字,要处理所有出现的心的坐标,和字的坐标。

另外,还有播放声音的功能,可以自己设置合适的音乐或者自己录好自己想说的话然后播放出来。

源码还在不断修改更新中,随意拿去自用。



这里不能附件下载,于是源码上传到资源那里了。



资源文件下载:

http://download.csdn.net/detail/wuxia2001/6856257

http://download.csdn.net/detail/wuxia2001/7251015




推荐阅读
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 利用Python与Android进行高效移动应用开发
    通过结合Python和Android,可以实现高效的移动应用开发。首先,需要安装Scripting Layer for Android (SL4A),这是一个开源项目,旨在为Android系统提供脚本语言支持。SL4A不仅简化了开发流程,还允许开发者使用Python等高级语言编写脚本,从而提高开发效率和代码可维护性。此外,SL4A还支持多种其他脚本语言,进一步扩展了其应用范围。通过这种方式,开发者可以快速构建功能丰富的移动应用,同时保持较高的灵活性和可扩展性。 ... [详细]
  • 深入解析 Android 选择器与形状绘制技术
    本文深入探讨了 Android 中选择器(Selector)与形状绘制(Shape Drawing)技术的应用与实现。重点分析了 `Selector` 的 `item` 元素,其中包括 `android:drawable` 属性的使用方法及其在不同状态下的表现。此外,还详细介绍了如何通过 XML 定义复杂的形状和渐变效果,以提升 UI 设计的灵活性和美观性。 ... [详细]
  • 本文探讨了在Android应用中实现动态滚动文本显示控件的优化方法。通过详细分析焦点管理机制,特别是通过设置返回值为`true`来确保焦点不会被其他控件抢占,从而提升滚动文本的流畅性和用户体验。具体实现中,对`MarqueeText.java`进行了代码层面的优化,增强了控件的稳定性和兼容性。 ... [详细]
  • 为了优化直播应用底部聊天框的弹出机制,确保在不同设备上的布局稳定性和兼容性,特别是在配备虚拟按键的设备上,我们对用户交互流程进行了调整。首次打开应用时,需先点击首个输入框以准确获取键盘高度,避免直接点击第二个输入框导致的整体布局挤压问题。此优化通过调整 `activity_main.xml` 布局文件实现,确保了更好的用户体验和界面适配。 ... [详细]
  • 本文深入解析了如何通过自定义 ViewGroup 实现类似支付宝风格的酷炫雷达脉冲动画效果。文章详细介绍了自定义 ViewGroup 的原理和实现步骤,并结合实际案例展示了如何在 Android UI 设计中应用这一技术,为开发者提供了宝贵的参考和实践指导。 ... [详细]
  • Node.js 配置文件管理方法详解与最佳实践
    本文详细介绍了 Node.js 中配置文件管理的方法与最佳实践,涵盖常见的配置文件格式及其优缺点,并提供了多种实用技巧和示例代码,帮助开发者高效地管理和维护项目配置,具有较高的参考价值。 ... [详细]
  • 本文深入探讨了CGLIB BeanCopier在Bean对象复制中的应用及其优化技巧。相较于Spring的BeanUtils和Apache的BeanUtils,CGLIB BeanCopier在性能上具有显著优势。通过详细分析其内部机制和使用场景,本文提供了多种优化方法,帮助开发者在实际项目中更高效地利用这一工具。此外,文章还讨论了CGLIB BeanCopier在复杂对象结构和大规模数据处理中的表现,为读者提供了实用的参考和建议。 ... [详细]
  • 【Linux进阶指南】第一阶段第三课:体验与部署Ubuntu系统
    在正式踏上Linux学习之旅之前,本课程将引导你深入体验和部署Ubuntu系统。通过详细的操作步骤和实践演练,你将掌握Ubuntu的基本安装、配置及常用命令,为后续的进阶学习打下坚实的基础。此外,课程还将介绍如何解决常见问题和优化系统性能,帮助你更加高效地使用Ubuntu。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 在MPAndroidChart中,当滑动至最后一个数据点时自动加载更多数据
    在MPAndroidChart中,当用户滑动图表至最后一个数据点时,系统将自动触发加载更多数据的功能,以提供连续的数据展示体验。这一机制特别适用于需要动态更新数据的场景,如实时监控和数据分析应用。 ... [详细]
  • 深入解析 Android Drawable:第六阶段进阶指南 ... [详细]
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 如何在Android应用中设计和实现专业的启动欢迎界面(Splash Screen)
    在Android应用开发中,设计与实现一个专业的启动欢迎界面(Splash Screen)至关重要。尽管Android设计指南对使用Splash Screen的态度存在争议,但一个精心设计的启动界面不仅能提升用户体验,还能增强品牌识别度。本文将探讨如何在遵循最佳实践的同时,通过技术手段实现既美观又高效的启动欢迎界面,包括加载动画、过渡效果以及性能优化等方面。 ... [详细]
  • APKAnalyzer(1):命令行操作体验与功能解析
    在对apkChecker进行深入研究后,自然而然地关注到了Android Studio中的APK分析功能。将APK文件导入IDE中,系统会自动解析并展示其中各类文件的详细信息。官方文档提供了详细的命令行工具使用指南,帮助开发者快速上手。本文以一个RecyclerView的Adapter代理开源库为例,探讨了如何利用这些工具进行高效的APK分析。 ... [详细]
author-avatar
炽热冰菊66
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有