kick_ball

package com.hereyouare.KickBall;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import com.google.ads.*;

public class KickBallActivity extends Activity {
    private static final String PREF = "HEREYOUARE_KICKBALL";
    private static final String PREF_FRONTCAMERA = "KICKBALL_FRONTCAMERA";
    private static final String PREF_SOUND = "KICKBALL_SOUND";
    private static final String PREF_TOPSCORE = "KICKBALL_TOPSCORE";
    private static final String PREF_BOTTOMSCORE = "KICKBALL_BOTTOMSCORE";
    private static final String PREF_BESTSCORE1 = "KICKBALL_BESTSCORE1";
    private static final String PREF_BESTSCORE2 = "KICKBALL_BESTSCORE2";
    private static final String PREF_BESTSCORE3 = "KICKBALL_BESTSCORE3";
    private static final String PREF_VIBRATE = "KICKBALL_VIBRATE";
    private static final String PREF_GRAVITY = "KICKBALL_GRAVITY";
    private static final String PREF_MODE = "KICKBALL_MODE";
    private static final float BALL_FORCE_COEF = 4200.0f;
    private static final float GSENSOR_THRESHOLD = 1.0f;
    private static final int INIT_TIME = -5;
    private static final int MENU_RESET = Menu.FIRST;
    private static final int MENU_SOUND = Menu.FIRST+1;
    private static final int MENU_VIBRATE = Menu.FIRST+2;
    private static final int MENU_GRAVITY = Menu.FIRST+3;
    private static final int MENU_BESTSCORE = Menu.FIRST+4;
    private static final int MENU_MODE = Menu.FIRST+5;
    private static final int MENU_CAMERA = Menu.FIRST+6;
    private static final int EDGE_Y_THRESHOLD = 20;
    private static final int EDGE_Y_THRESHOLD2 = 20;
    private static final int EDGE_UV_THRESHOLD = 180;
    private static final int EDGE_RGB_THRESHOLD = 15<<10;
    private static final int EDGE_RGB_THRESHOLD2 = 5<<10;
    private static final int TOP_COLOR = Color.BLUE;
    private static final int BOTTOM_COLOR = Color.RED;
    private static final int TIME_COLOR = Color.LTGRAY;
    private static final int SIZE_COEF = 8;
    private static final float GRAVITY = -0.07f;
    private static final int TICK_INTERVAL = 50;
    private Preview preview;
    private float realAccX, realAccY, realAccZ;
    private MyTimer mt;
    private Menu myMenu;
    private MediaPlayer mpSound = null;
    private Vibrator vibrator;
    private DemoView demoView;
    private AdView adView;
    private LinearLayout layoutDemo = null;
    private byte[] lastYData;
    private int[] lastRData;
    private int[] lastGData;
    private int[] lastBData;
    private boolean[][] edgeData;
    private boolean[][] edgeDataUV;
    private int edgeDataW;
    private int edgeDataH;
    private float scaleX;
    private float scaleY;
    private int topScore = 0;
    private int bottomScore = 0;
    private int score = 0;
    private int time = 0;
    private int timeCounter = 0;
    private float topX;
    private float bottomX;
    private float timeX;
    private float textS;
    private float textY;
    private boolean bEdgeDataInit = false;
    private boolean bRGBInit = false;
    private float ballX;
    private float ballY;
    private float ballVX = 0;
    private float ballVY = 0;
    private float ballRadius;
    private float ballAngle = 0;
    private float goalX;
    private float goalY;
    private float goalW;
    private float goalH;
    private float goalVX = 0;
    private int screenWidth;
    private int screenHeight;
    private Bitmap bitmapSoccer;
    private Bitmap bitmapGoal = null;
    private int[] bestScore = new int[3];
    private boolean bMode; //true:one player  false:two player
    private boolean bVibrate;
    private boolean bSound;
    private boolean bGravity;
    private boolean bHitTop = false;
    private boolean bHitBottom = false;
    private boolean bHitTopCheck = false;
    private boolean bHitBottomCheck = false;
    private boolean bDetect;
    private boolean bDebug = false;
    private boolean bFrontCamera = true;
    private int level = 1;
    public Camera camera = null;

    private void calParameter() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;

        ballX = screenWidth / 2;
        ballY = screenHeight / 2;
        ballRadius = screenWidth / 8;
        
        bottomX = screenWidth / 6;
        topX = screenWidth * 5 / 6;
        timeX = screenWidth * 3 / 6;
        textS = screenWidth / 10;
        textY = textS * 1.2f;
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Config.ARGB_8888;
        bitmapSoccer = BitmapFactory.decodeResource(this.getResources(), R.drawable.soccer2, opt);
        bitmapSoccer = bitmapSoccer.createScaledBitmap(bitmapSoccer, (int)(ballRadius*2), (int)(ballRadius*2), true);
    }
    private void getPref() {
        String tempStr;
        SharedPreferences settings = getSharedPreferences(PREF, 0);
        tempStr = settings.getString(PREF_SOUND, "true");
        if (tempStr.equals("true")) bSound = true; else bSound = false;
        tempStr = settings.getString(PREF_VIBRATE, "true");
        if (tempStr.equals("true")) bVibrate = true; else bVibrate = false;
        tempStr = settings.getString(PREF_GRAVITY, "true");
        if (tempStr.equals("true")) bGravity = true; else bGravity = false;
        tempStr = settings.getString(PREF_MODE, "true");
        if (tempStr.equals("true")) bMode = true; else bMode = false;
        tempStr = settings.getString(PREF_BESTSCORE1, "0");
        bestScore[0] = Integer.valueOf(tempStr);
        tempStr = settings.getString(PREF_BESTSCORE2, "0");
        bestScore[1] = Integer.valueOf(tempStr);
        tempStr = settings.getString(PREF_BESTSCORE3, "0");
        bestScore[2] = Integer.valueOf(tempStr);
        tempStr = settings.getString(PREF_TOPSCORE, "0");
        topScore = Integer.valueOf(tempStr);
        tempStr = settings.getString(PREF_BOTTOMSCORE, "0");
        bottomScore = Integer.valueOf(tempStr);
        tempStr = settings.getString(PREF_FRONTCAMERA, "false");
        if (tempStr.equals("true")) bFrontCamera = true; else bFrontCamera = false;
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        vibrator = (Vibrator) getApplication().getSystemService(Service.VIBRATOR_SERVICE);

        setContentView(R.layout.main);

        getPref();
        calParameter();
        reset();

        layoutDemo = (LinearLayout)findViewById(R.id.DrawLayout);
        demoView = new DemoView(this);
        layoutDemo.addView(demoView);

        adView = new AdView(this, AdSize.BANNER, "a14fb23de8cbd06");
        LinearLayout layout = (LinearLayout)findViewById(R.id.AdLayout);
        layout.addView(adView);
        adView.loadAd(new AdRequest());

        preview = new Preview(this);
        ((FrameLayout) findViewById(R.id.preview)).addView(preview);
        
        mt = new MyTimer(86400000, TICK_INTERVAL);
        mt.start();
    }
    @Override 
    public void onResume() {
        demoView.invalidate();
        super.onResume();
        mt.start();
    }
    @Override
    public void onDestroy() {
        mt.cancel();
        adView.destroy();
        super.onDestroy();
    }
    @Override
    protected void onPause() {
        super.onPause();
        if (mpSound != null) {
            mpSound.stop();
            mpSound.release();
            mpSound = null;
        }
        mt.cancel();
    }
    @Override
    protected void onStop() {
        super.onStop();
        mt.cancel();
    }
    private void playSound(int resInd) {
        if (!bSound) return;
        if (mpSound != null) {
            mpSound.stop();
            mpSound.release();
            mpSound = null;
        }
        switch (resInd) {
            default:
            case 0:
                mpSound = MediaPlayer.create(KickBallActivity.this, R.raw.click2);
                break;
            case 1:
                mpSound = MediaPlayer.create(KickBallActivity.this, R.raw.kickcut);
                break;
            case 2:
                mpSound = MediaPlayer.create(KickBallActivity.this, R.raw.hitwallcut);
                break;
        }
           //mpSound.setAudioStreamType(AudioManager.STREAM_MUSIC);
        if (mpSound != null) {
            mpSound.start();
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, MENU_RESET, 0, getString(R.string.menu_reset));
        menu.add(0, MENU_BESTSCORE, 0, getString(R.string.menu_bestscore));
        if (bMode) {
            menu.add(0, MENU_MODE, 0, getString(R.string.menu_mode_on));
        } else {
            menu.add(0, MENU_MODE, 0, getString(R.string.menu_mode_off));            
        }
        if (bGravity) {
            menu.add(0, MENU_GRAVITY, 0, getString(R.string.menu_gravity_on));
        } else {
            menu.add(0, MENU_GRAVITY, 0, getString(R.string.menu_gravity_off));
        }
        if (bSound) {
            menu.add(0, MENU_SOUND, 0, getString(R.string.menu_sound_on));
        } else {
            menu.add(0, MENU_SOUND, 0, getString(R.string.menu_sound_off));
        }
        if (bVibrate) {
            menu.add(0, MENU_VIBRATE, 0, getString(R.string.menu_vibrate_on));
        } else {
            menu.add(0, MENU_VIBRATE, 0, getString(R.string.menu_vibrate_off));
        }
        menu.add(0, MENU_CAMERA, 0, getString(R.string.camera_switch));        
        myMenu = menu;
        return true;
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            AlertDialog.Builder dialog = new AlertDialog.Builder(KickBallActivity.this);      
            dialog.setMessage(getString(R.string.exitMessage));
            dialog.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            });
            dialog.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            });
            dialog.show();
            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }
    private void showBestScore(int tmp) {
        int i, j;
        int place = -1;
        AlertDialog.Builder dialog = new AlertDialog.Builder(KickBallActivity.this);      
        if (tmp >= 0) {
            for (i=0;i<3;i++) {
                if (bestScore[i] <= tmp) {
                    for (j=2;j>i;j--) {
                        bestScore[j] = bestScore[j-1];
                    }
                    bestScore[i] = tmp;
                    place = i;
                    break;
                }
            }
        }
        dialog.setTitle(getString(R.string.menu_bestscore));
        String tmpStr = "";
        for (i=0;i<3;i++) {
            tmpStr = tmpStr + String.valueOf(i+1) + " - " + String.valueOf(bestScore[i]);
            if (place == i) {
                tmpStr = tmpStr + "("+getString(R.string.yourscore)+")";
            }
            tmpStr = tmpStr + "\n";
        }
        SharedPreferences settings = getSharedPreferences(PREF, 0);
        settings.edit().putString(PREF_BESTSCORE1, String.valueOf(bestScore[0])).commit();
        settings.edit().putString(PREF_BESTSCORE2, String.valueOf(bestScore[1])).commit();
        settings.edit().putString(PREF_BESTSCORE3, String.valueOf(bestScore[2])).commit();
        if (tmp >= 0 && place == -1) {
            tmpStr = tmpStr + getString(R.string.yourscore) + " - " + String.valueOf(tmp);
        }
        dialog.setMessage(tmpStr);
        dialog.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            }
        });
        dialog.show();
    }
    private void reset() {
        level = 1;
        time = INIT_TIME;
        score = 0;
        topScore = 0;
        bottomScore = 0;
        ballX = screenWidth / 2;
        ballY = screenHeight / 2;
        setGoal();        
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        AlertDialog.Builder dialog = new AlertDialog.Builder(KickBallActivity.this);      
        switch(item.getItemId()) {
            case MENU_RESET:
                reset();
                break;
            case MENU_BESTSCORE:
                showBestScore(-1);
                break;
            case MENU_MODE:
                dialog.setMessage(getString(R.string.menu_mode_msg));
                dialog.setPositiveButton(getString(R.string.menu_mode_on), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bMode = true;
                        reset();
                        myMenu.findItem(MENU_MODE).setTitle(getString(R.string.menu_mode_on));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_MODE, "true").commit();
                    }
                });
                dialog.setNegativeButton(getString(R.string.menu_mode_off), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bMode = false;
                        reset();
                        myMenu.findItem(MENU_MODE).setTitle(getString(R.string.menu_mode_off));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_MODE, "false").commit();
                    }
                });
                dialog.show();
                break;
            case MENU_GRAVITY:
                dialog.setMessage(getString(R.string.menu_gravity_msg));
                dialog.setPositiveButton(getString(R.string.menu_gravity_on), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bGravity = true;
                        myMenu.findItem(MENU_GRAVITY).setTitle(getString(R.string.menu_gravity_on));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_GRAVITY, "true").commit();
                    }
                });
                dialog.setNegativeButton(getString(R.string.menu_gravity_off), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bGravity = false;
                        myMenu.findItem(MENU_GRAVITY).setTitle(getString(R.string.menu_gravity_off));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_GRAVITY, "false").commit();
                    }
                });
                dialog.show();
                break;
            case MENU_SOUND:
                dialog.setMessage(getString(R.string.menu_sound_msg));
                dialog.setPositiveButton(getString(R.string.menu_sound_on), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bSound = true;
                        myMenu.findItem(MENU_SOUND).setTitle(getString(R.string.menu_sound_on));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_SOUND, "true").commit();
                    }
                });
                dialog.setNegativeButton(getString(R.string.menu_sound_off), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bSound = false;
                        myMenu.findItem(MENU_SOUND).setTitle(getString(R.string.menu_sound_off));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_SOUND, "false").commit();
                    }
                });
                dialog.show();
                break;
            case MENU_VIBRATE:
                dialog.setMessage(getString(R.string.menu_vibrate_msg));
                dialog.setPositiveButton(getString(R.string.menu_vibrate_on), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bVibrate = true;
                        myMenu.findItem(MENU_VIBRATE).setTitle(getString(R.string.menu_vibrate_on));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_VIBRATE, "true").commit();
                    }
                });
                dialog.setNegativeButton(getString(R.string.menu_vibrate_off), new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        bVibrate = false;
                        myMenu.findItem(MENU_VIBRATE).setTitle(getString(R.string.menu_vibrate_off));
                        SharedPreferences settings = getSharedPreferences(PREF, 0);
                        settings.edit().putString(PREF_VIBRATE, "false").commit();
                    }
                });
                dialog.show();
                break;
            case MENU_CAMERA:
                if (Camera.getNumberOfCameras()<=1) {
                    Toast.makeText(getApplicationContext(), getString(R.string.camera_one), Toast.LENGTH_SHORT).show();                                
                } else {
                    dialog.setMessage(getString(R.string.camera_switch));
                    dialog.setPositiveButton(getString(R.string.camera_front), new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            bFrontCamera=true;
                            SharedPreferences settings = getSharedPreferences(PREF, 0);
                            String tempStr = (bFrontCamera) ? "true" : "false";
                            settings.edit().putString(PREF_FRONTCAMERA, tempStr).commit();
                            Toast.makeText(getApplicationContext(), getString(R.string.camera_reopen), Toast.LENGTH_SHORT).show();                                
                        }
                    });
                    dialog.setNegativeButton(getString(R.string.camera_back), new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            bFrontCamera=false;
                            SharedPreferences settings = getSharedPreferences(PREF, 0);
                            String tempStr = (bFrontCamera) ? "true" : "false";
                            settings.edit().putString(PREF_FRONTCAMERA, tempStr).commit();
                            Toast.makeText(getApplicationContext(), getString(R.string.camera_reopen), Toast.LENGTH_SHORT).show();                                
                        }
                    });
                    dialog.show();
                }
            default:
                break;
        }
        return true;
    }
    private class DemoView extends View{
        public DemoView(Context context){
            super(context);
        }
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                {
                    break;
                }
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                {
                    KickBallActivity.this.openOptionsMenu();
                    break;
                }
                default:
                    break;
            }
            return true;
        }
        @Override protected void onDraw(Canvas canvas) {
            int i, j;            
            super.onDraw(canvas);

            Paint paint = new Paint();
            paint.setAntiAlias(true);

            if (bEdgeDataInit && bDebug) {
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(Color.BLUE);
                for (j=1;j<edgeDataW;j++) {
                    for (i=1;i<edgeDataH;i++) {
                        if (edgeData[j][i]) {
                            canvas.drawPoint(j*scaleX, i*scaleY, paint);
                        }
                    }
                }
            }
            if (bMode) {
                //draw goal
                if (bHitTop) {
                    paint.setAlpha(80);
                    if (bHitTopCheck==true) {
                        bHitTop = false;
                    }
                } else {
                    paint.setAlpha(255);
                }
                if (bitmapGoal != null) canvas.drawBitmap(bitmapGoal, goalX, goalY, paint);
            }
            //draw ball
            paint.setStyle(Paint.Style.FILL);
//            paint.setColor(Color.DKGRAY);
//            canvas.drawCircle(ballX, ballY, ballRadius, paint);
//            canvas.save();
            canvas.rotate(ballAngle, ballX, ballY);
            canvas.drawBitmap(bitmapSoccer, ballX-ballRadius, ballY-ballRadius, paint);
            canvas.rotate(-ballAngle, ballX, ballY);
//            canvas.restore();
            
            if (bMode) {
                //draw score & time
                paint.setTextAlign(Align.CENTER);
                paint.setTextSize(textS);
                paint.setColor(TOP_COLOR);
                canvas.drawText(String.valueOf(score), topX, textY, paint);
                paint.setStrokeWidth(2);
                paint.setStyle(Paint.Style.STROKE);
                paint.setColor(TIME_COLOR);
                canvas.drawText(sec2min(time), bottomX, textY, paint);
            } else {
                //draw score & time
                paint.setTextAlign(Align.CENTER);
                paint.setTextSize(textS);
                paint.setColor(TOP_COLOR);
                canvas.drawText(String.valueOf(topScore), topX, textY, paint);
                paint.setColor(BOTTOM_COLOR);
                canvas.drawText(String.valueOf(bottomScore), bottomX, textY, paint);            
                paint.setStrokeWidth(2);
                paint.setStyle(Paint.Style.STROKE);
                paint.setColor(TIME_COLOR);
                canvas.drawText(sec2min(time), timeX, textY, paint);
                
                //draw hit top or bottom
                if (bHitTop) {
                    canvas.drawColor(BOTTOM_COLOR);
                    bHitTop = false;
                } else if (bHitBottom) {
                    canvas.drawColor(TOP_COLOR);
                    bHitBottom = false;
                }
            }
        }
    }    
    private String sec2min(int val) {
        int minute = val/60;
        int second = val%60;
        String retStr;
        if (val<0) {
            retStr = "Lv"+String.valueOf(level)+":";
            if (val == -1) {
                retStr = retStr + "OVER";
            } else if (val == -2) {
                retStr = retStr + "GO!";
            } else {
                retStr = retStr + "(" + String.valueOf(Math.abs(val)-2) +")";
            }
        } else {
            if (minute<10) retStr = "0"; else retStr = "";
            retStr = retStr + String.valueOf(minute);
            retStr = retStr + ":";
            if (second<10) retStr = retStr + "0";
            retStr = retStr+String.valueOf(second);
        }
        return retStr;
    }
    private void findBallForce() {
        int i, j;
        float vx=0, vy=0;
        int tmpX, tmpY, tmpRadius;
        int check = 0;
        tmpX = (int)ballX*edgeDataW/screenWidth;
        tmpY = (int)ballY*edgeDataH/screenHeight;
        tmpRadius = (int)ballRadius*(edgeDataW+edgeDataH)/(screenWidth+screenHeight);
        for (i=-tmpRadius;i<=tmpRadius;i++) {
            for (j=-tmpRadius;j<=tmpRadius;j++) {
                if (tmpX+i>=0 && tmpX+i<edgeDataW
                    && tmpY+j>=0 && tmpY+j<edgeDataH) {
                    if (edgeData[tmpX+i][tmpY+j]) {
                        check = check + 1;
                        vx = vx + i;
                        vy = vy + j;
                    }
                }
            }            
        }
        if (check>3) {
            if (bVibrate) vibrator.vibrate(check*3);
            if (check>10) playSound(1);
        }
        ballVX = ballVX - vx * BALL_FORCE_COEF / (ballRadius*ballRadius);
        ballVY = ballVY - vy * BALL_FORCE_COEF / (ballRadius*ballRadius);
    }
    private void findBitmapEdge(byte[] data) {
/*        int i, j;
        int frameSize = edgeDataH * edgeDataW;
        int uvp = 0, u = 0, v = 0;
        int yp = 0, y = 0, y1192 = 0;
        int r = 0, g = 0, b = 0;
        int[][] rData = new int[edgeDataW][edgeDataH];
        int[][] gData = new int[edgeDataW][edgeDataH];
        int[][] bData = new int[edgeDataW][edgeDataH];
        for (j=0;j<edgeDataH;j++) {
            uvp = frameSize + (j>>1)*edgeDataW;
            u=0;
            v=0;
            for (i=0;i<edgeDataW;i++,yp++) {
                y=(0xff&((int)data[yp])) - 16;
                if(y<0) y=0;
                if((i&1)==0) {
                    v=(0xff&data[uvp++])-128;
                    u=(0xff&data[uvp++])-128;
                }
                y1192=1192*y;
                r=(y1192+1634*v);
                g=(y1192-833*v-400*u);
                b=(y1192+2066*u);
//                if(r<0)r=0; else if (r>262143)r=262143;
//                if(g<0)g=0; else if (g>262143)g=262143;
//                if(b<0)b=0; else if (b>262143)b=262143;
                rData[i][j] = r;//>>10;
                gData[i][j] = g;//>>10;
                bData[i][j] = b;//>>10;
            }
        }
        for (i=1;i<edgeDataW;i++) {
            for (j=1;j<edgeDataH;j++) {
                if (Math.abs(rData[i][j]-rData[i][j-1])>EDGE_RGB_THRESHOLD
                    || Math.abs(gData[i][j]-gData[i][j-1])>EDGE_RGB_THRESHOLD
                    || Math.abs(bData[i][j]-bData[i][j-1])>EDGE_RGB_THRESHOLD) {
                    edgeData[i][j] = true;
                } else {
                    if (Math.abs(rData[i][j]-rData[i-1][j])>EDGE_RGB_THRESHOLD
                        || Math.abs(gData[i][j]-gData[i-1][j])>EDGE_RGB_THRESHOLD
                        || Math.abs(bData[i][j]-bData[i-1][j])>EDGE_RGB_THRESHOLD) {
                            edgeData[i][j] = true;
                    } else {
                        edgeData[i][j] = false;
                    }                    
                }
            }
        }*/
/*        int i, j;
        int tmpY, tmpY2;
        int tmpU, tmpV, tmpU2, tmpV2;
        int YShift = edgeDataH*edgeDataW;
        for (i=1;i<edgeDataH/2;i++) {
            for (j=1;j<edgeDataW/2;j++) {
                tmpU = data[YShift+i*edgeDataW+j*2];
                tmpV = data[YShift+i*edgeDataW+j*2+1];
                tmpU2 = data[YShift+i*edgeDataW+j*2-2];
                tmpV2 = data[YShift+i*edgeDataW+j*2-1];
                if (Math.abs(tmpU-tmpU2)>EDGE_UV_THRESHOLD ||
                    Math.abs(tmpV-tmpV2)>EDGE_UV_THRESHOLD) {
                    edgeDataUV[j][i] = true;
                } else {
                    tmpU2 = data[YShift+(i-1)*edgeDataW+j*2];
                    tmpV2 = data[YShift+(i-1)*edgeDataW+j*2+1];
                    if (Math.abs(tmpU-tmpU2)>EDGE_UV_THRESHOLD ||
                        Math.abs(tmpV-tmpV2)>EDGE_UV_THRESHOLD) {
                        edgeDataUV[j][i] = true;
                    } else {
                        edgeDataUV[j][i] = false;
                    }
                }
            }
        }*/
/*        for (i=1;i<edgeDataH;i++) {
            for (j=1;j<edgeDataW;j++) {
                tmpY = data[j*SIZE_COEF*edgeDataH*SIZE_COEF+i*SIZE_COEF];
                tmpY2 = data[j*SIZE_COEF*edgeDataH*SIZE_COEF+(i-1)*SIZE_COEF];
                if (Math.abs(tmpY-tmpY2)>EDGE_Y_THRESHOLD) {
                    edgeData[edgeDataW-j][i] = true;
                } else {
                    tmpY2 = data[(j-1)*SIZE_COEF*edgeDataH*SIZE_COEF+i*SIZE_COEF];
                    if (Math.abs(tmpY-tmpY2)>EDGE_Y_THRESHOLD) {
                            edgeData[edgeDataW-j][i] = true;
                    } else {
                        edgeData[edgeDataW-j][i] = false;
                    }
                }
//                edgeData[j][i] = edgeData[j][i]&edgeDataUV[j/2][i/2];
            }
        }//*/
        int i, j;
        int y, u, v, y1192;
        int r, g, b;
        int ind, ind2, ind3;
        int offset = edgeDataH*edgeDataW*SIZE_COEF*SIZE_COEF;
        for (i=0;i<edgeDataH;i++) {
            for (j=0;j<edgeDataW;j++) {
                ind = j*SIZE_COEF*edgeDataH*SIZE_COEF+i*SIZE_COEF;
                y = (0xff & ((int)data[ind])) - 16;
                if (y<0) y = 0;
                ind2 = offset + j*SIZE_COEF*edgeDataH*SIZE_COEF/4+i*SIZE_COEF/2;
                v = (0xff & data[ind2]) - 128;
                u = (0xff & data[ind2+1]) - 128;
                y1192 = 1192 * y;
                r = (y1192 + 1634 * v);
                g = (y1192 - 833 * v - 400 * u);
                b = (y1192 + 2066 * u);
                ind3 = j*edgeDataH + i;
                if (bRGBInit) {
                    if (bDetect == false) {
                        edgeData[edgeDataW-j-1][i] = false;
                    } else if (Math.abs(data[ind]-lastYData[ind3])>EDGE_Y_THRESHOLD
                        &&(Math.abs(r - lastRData[ind3])>EDGE_RGB_THRESHOLD
                        ||Math.abs(g - lastGData[ind3])>EDGE_RGB_THRESHOLD
                        ||Math.abs(b - lastBData[ind3])>EDGE_RGB_THRESHOLD)) {                        
//                        edgeData[edgeDataW-j-1][i] = true;
                        if (j==0||i==0) {
                            edgeData[edgeDataW-j-1][i] = false;
                        } else {
                            ind2 = j*edgeDataH + i - 1;
                            if (Math.abs(r - lastRData[ind2])>EDGE_RGB_THRESHOLD2
                                ||Math.abs(g - lastGData[ind2])>EDGE_RGB_THRESHOLD2
                                ||Math.abs(b - lastBData[ind2])>EDGE_RGB_THRESHOLD2) {                        
                                ind2 = (j-1)*edgeDataH + i;
                                if (Math.abs(r - lastRData[ind2])>EDGE_RGB_THRESHOLD2
                                        ||Math.abs(g - lastGData[ind2])>EDGE_RGB_THRESHOLD2
                                        ||Math.abs(b - lastBData[ind2])>EDGE_RGB_THRESHOLD2) {                        
                                    edgeData[edgeDataW-j-1][i] = true;
                                } else {
                                    edgeData[edgeDataW-j-1][i] = false;
                                }
                            } else {
                                edgeData[edgeDataW-j-1][i] = false;
                            }
                        }
                    } else {
                        edgeData[edgeDataW-j-1][i] = false;
                    }
                } else {
                    edgeData[edgeDataW-j-1][i] = false;
                    bRGBInit = true;
                }
                lastYData[ind3] = data[ind];
                lastRData[ind3] = r;
                lastGData[ind3] = g;
                lastBData[ind3] = b;
            }
        }//*/
/*        int i, j;
        int tmpY, tmpY2;
        int ind, ind2;
        int m, n;
        for (i=0;i<edgeDataH;i++) {
            for (j=0;j<edgeDataW;j++) {
                ind = j*SIZE_COEF*edgeDataH*SIZE_COEF+i*SIZE_COEF;
                ind2 = j*edgeDataH+i;
                tmpY = 0;
                tmpY = data[ind];
                tmpY2 = lastYData[ind2];
                lastYData[ind2] = (byte)tmpY;
                if (Math.abs(tmpY-tmpY2)>EDGE_Y_THRESHOLD) {
//                    edgeData[edgeDataW-j-1][i] = true;
                    if (i==0||j==0) {
                        edgeData[edgeDataW-j-1][i] = false;
                    } else {
                        ind2 = (j-1)*SIZE_COEF*edgeDataH*SIZE_COEF+i*SIZE_COEF;
                        tmpY2 = data[ind2];
                        if (Math.abs(tmpY-tmpY2)>EDGE_Y_THRESHOLD2) {
                            ind2 = j*SIZE_COEF*edgeDataH*SIZE_COEF+(i-1)*SIZE_COEF;
                            tmpY2 = data[ind2];
                            if (Math.abs(tmpY-tmpY2)>EDGE_Y_THRESHOLD2) {
                                edgeData[edgeDataW-j-1][i] = true;
                            } else {                        
                                edgeData[edgeDataW-j-1][i] = false;
                            }                        
                        } else {                        
                            edgeData[edgeDataW-j-1][i] = false;
                        }
                    }
                } else {
                    edgeData[edgeDataW-j-1][i] = false;
                }
//                edgeData[j][i] = edgeData[j][i]&edgeDataUV[j/2][i/2];
            }
        }//*/
    }
    private void setGoal() {
        switch (level) {
            case 1:
            case 2:
            case 3:
                goalW = screenWidth / 2;
                goalH = goalW / 2;
                goalX = screenWidth / 2 - goalW / 2;
                goalY = 0;
                break;
            default:
                goalW = screenWidth / 4;
                goalH = goalW / 2;
                goalX = screenWidth / 2 - goalW / 2;
                goalY = 0;
                break;
        }
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Config.ARGB_8888;
        bitmapGoal = BitmapFactory.decodeResource(this.getResources(), R.drawable.goal, opt);
        bitmapGoal = bitmapGoal.createScaledBitmap(bitmapGoal, (int)(goalW), (int)(goalH), true);
        if (level%3 == 0) {
            goalVX = level;
        } else if (level%3 == 1){
            goalVX = 0;
        } else {
            goalVX = level;            
        }
    }
    private class MyTimer extends CountDownTimer implements SensorListener {
        private SensorManager sm;
        float lastX=0, lastY=0, lastZ=0;
        public MyTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
            sm = (SensorManager) getSystemService(SENSOR_SERVICE);
            sm.registerListener(this, sm.SENSOR_ACCELEROMETER, sm.SENSOR_DELAY_GAME);
        }
        public void onAccuracyChanged(int arg0, int arg1) {
        }
        public void onSensorChanged(int sensor, float[] values) {
            if (sensor == sm.SENSOR_ACCELEROMETER) {
                realAccX = values[0];
                realAccY = values[1];
                realAccZ = values[2];
            }
        }
        @Override
        public void onFinish() {
            sm.unregisterListener(this);
        }
        @Override
        public void onTick(long arg0) {
            if (Math.abs(realAccX-lastX)+Math.abs(realAccY-lastY)
                +Math.abs(realAccZ-lastZ) > GSENSOR_THRESHOLD) {
                bDetect = false;
            } else {
                bDetect = true;
            }
            lastX = realAccX;
            lastY = realAccY;
            lastZ = realAccZ;
            if (timeCounter >= 1000 / TICK_INTERVAL) {
                timeCounter = 0;
                if (bMode) {
                    if (time < -2) {
                        time = time + 1;
                    } else if (time == -2) {
                        time = 60;
                    } else if (time == -1) {
                        //game over
                    } else if (time == 0) {
                        if (score >= level * 15) {
                            level = level + 1;
                            time = INIT_TIME;
                            setGoal();
                        } else {
                            showBestScore(score);
                            time = -1;
                        }
                    } else {
                        time = time - 1;
                    }
                } else {
                    if (time < 3600) {
                        time = time + 1;
                        if (time == -1) {
                            time = 0;
                        }
                    }
                }
            } else {
                timeCounter = timeCounter + 1;
            }
            float coef = 10.0f;
            ballX = ballX + ballVX;
            ballY = ballY + ballVY;
            ballVX = ballVX + 0;//realAccX/coef;
            if (bGravity) {
                ballVY = ballVY - GRAVITY;//realAccY/coef;
            }
            ballAngle = ballAngle + ballVX + ballVY;
            goalX = goalX + goalVX;
            if (goalX < 0 || goalX + goalW > screenWidth) {
                goalVX = -goalVX;
            }
            if (ballX-ballRadius<0) {
                ballVX = -ballVX/2;
                ballX = ballRadius;
            } else if (ballX+ballRadius>screenWidth) {
                ballVX = -ballVX/2;
                ballX = screenWidth-ballRadius;
            }
            if (ballY-ballRadius<0) {
                if (bHitTopCheck) {
                    if (bMode) {
                        if (ballX>=goalX && ballX<=goalX+goalW) {
                            playSound(2);
                            bHitTop = true;
                            if (time >= 0) {
                                if (ballX-ballRadius>=goalX && ballX+ballRadius<=goalX+goalW) {
                                    score = score + 2;
                                } else {
                                    score = score + 1;
                                }
                            }
                        } else {
                            playSound(0);
                        }                        
                        bHitTopCheck = false;
                        if (bVibrate) vibrator.vibrate(100);
                    } else {
                        if (bVibrate) vibrator.vibrate(100);
                        playSound(0);
                        bHitTop = true;
                        topScore = topScore + 1;
                        bHitTopCheck = false;
                    }
                }
                ballVY = -ballVY/2;
                ballY = ballRadius;
            } else if (ballY+ballRadius>screenHeight) {
                if (bMode) {
                } else {
                    if (bHitBottomCheck) {
                        if (bVibrate) vibrator.vibrate(100);
                        playSound(0);
                        bHitBottom = true;
                        bottomScore = bottomScore + 1;
                        bHitBottomCheck = false;
                    }
                }
                ballVY = -ballVY/2;
                ballY = screenHeight-ballRadius;
            } else if (ballY - goalH > 0 && ballY + goalH < screenHeight) {
                bHitTopCheck = true;
                bHitBottomCheck = true;
            }
            if (demoView!=null) demoView.invalidate();                        
        }
    }

    private PreviewCallback previewCallback = new PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera arg1) {
/*                    FileOutputStream outStream = null;
            try {
                outStream = new FileOutputStream(String.format(
                        "/sdcard/%d.jpg", System.currentTimeMillis()));
                outStream.write(data);
                outStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }*/
            if (bEdgeDataInit == false) {
                Camera.Parameters parameters = arg1.getParameters();
                edgeDataW = parameters.getPreviewSize().height/SIZE_COEF;
                edgeDataH = parameters.getPreviewSize().width/SIZE_COEF;
                //edgeData = new boolean[edgeDataW][edgeDataH];
                edgeData = new boolean[edgeDataW][edgeDataH];
                lastYData = new byte[edgeDataW*edgeDataH];
                lastRData = new int[edgeDataW*edgeDataH];
                lastGData = new int[edgeDataW*edgeDataH];
                lastBData = new int[edgeDataW*edgeDataH];
                System.arraycopy(data, 0, lastYData, 0, edgeDataW*edgeDataH);
//                            edgeDataUV = new boolean[edgeDataW/2][edgeDataH/2];

                scaleX = (float)screenWidth/edgeDataW;
                scaleY = (float)screenHeight/edgeDataH;
                bEdgeDataInit = true;
            }
            findBitmapEdge(data);
            findBallForce();
            /*int format = parameters.getPreviewFormat();
            // YUV formats require more conversion
            if (format == ImageFormat.NV21 || format == ImageFormat.YUY2 || format == ImageFormat.NV16)
            {
                int w = parameters.getPreviewSize().width;
                int h = parameters.getPreviewSize().height;
                // Get the YuV image
                YuvImage yuv_image = new YuvImage(data, format, w, h, null);
                // Convert YuV to Jpeg
                Rect rect = new Rect(0, 0, w, h);
                ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
                yuv_image.compressToJpeg(rect, 100, output_stream);
                // Convert from Jpeg to Bitmap
                bitmap = BitmapFactory.decodeByteArray(output_stream.toByteArray(), 0, output_stream.size());
            }
            // Jpeg and RGB565 are supported by BitmapFactory.decodeByteArray
            else if (format == ImageFormat.JPEG || format == ImageFormat.RGB_565)
            {
                mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            }*/
        }
    };
    class Preview extends SurfaceView implements SurfaceHolder.Callback {
        SurfaceHolder mHolder;

        @SuppressWarnings("deprecation")
        Preview(Context context) {
            super(context);
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, acquire the camera and tell it where
            // to draw.
            if (camera == null) {
                if (bFrontCamera) {
                    try {
                        camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
                    } catch (Exception e) {
                        camera = null;
                        Toast.makeText(getApplicationContext(), getString(R.string.open_camera_fail), Toast.LENGTH_SHORT).show();    
                        finish();
                    }                    
                } else {
                    try {
                        camera = Camera.open();
                    } catch (Exception e) {
                        camera = null;
                        Toast.makeText(getApplicationContext(), getString(R.string.open_camera_fail), Toast.LENGTH_SHORT).show();    
                        finish();
                    }
                }
                if (camera!=null && holder!=null) {
                    try {
                        camera.setPreviewDisplay(holder);
                        camera.setPreviewCallback(previewCallback);
                    } catch (IOException e) {
                        camera.release();
                        camera = null;
                        Toast.makeText(getApplicationContext(), getString(R.string.error_camera), Toast.LENGTH_SHORT).show();
                        finish();
                    }
                }
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            // Surface will be destroyed when we return, so stop the preview.
            // Because the CameraDevice object is not a shared resource, it's very
            // important to release it when the activity is paused.
            if (camera != null) {
                camera.setPreviewCallback(null);
//                camera.stopPreview();
                camera.release();
                camera = null;
            }
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            final int IDEAL_WIDTH = 320;
            int i, minW, index = 0;
            if (camera!=null) {
                Camera.Parameters parameters = camera.getParameters();
                List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
                minW = Math.abs(previewSizes.get(0).width-IDEAL_WIDTH);
                for (i=1;i<previewSizes.size();i++) {
                    if (Math.abs(previewSizes.get(i).width-IDEAL_WIDTH)<minW) {
                        minW = Math.abs(previewSizes.get(i).width-IDEAL_WIDTH);
                        index = i;
                    }
                }
                Camera.Size previewSize = previewSizes.get(index);
                parameters.setPreviewSize(previewSize.width, previewSize.height);
                camera.setDisplayOrientation(90);
                camera.setParameters(parameters);
                try {
                    camera.startPreview();
                } catch (Exception e) {
                    Toast.makeText(getApplicationContext(), getString(R.string.error_camera), Toast.LENGTH_SHORT).show();
                    finish();
                }
            }
        }
    }
}

 

posted @ 2014-02-12 15:39  zmiao  阅读(188)  评论(0编辑  收藏  举报