程式設計師表白程式,開放原始碼,不斷更新
這是我為自己寫的一款表白的程式,幾經努力把它完成為一個完整的程式,這是我準備完成的程式之愛系列第一輯,希望能多做幾輯吧。
原始碼地址: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 < 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();
}
}
}
}
}
至於字的顯現,應該沒什麼好說,值得注意的是,還有一些閃爍的愛心和下綴的那一段,要注意這些座標,不能覆蓋字,要處理所有出現的心的座標,和字的座標。
另外,還有播放聲音的功能,可以自己設定合適的音樂或者自己錄好自己想說的話然後播放出來。
原始碼還在不斷修改更新中,隨意拿去自用。
這裡不能附件下載,於是原始碼上傳到資源那裡了。
資原始檔下載: