<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Cyh的博客

    Email:kissyan4916@163.com
    posts - 26, comments - 19, trackbacks - 0, articles - 220

    有關SurfaceView 我們將通過三個系統(tǒng) 自帶的例子 來深入掌握Android繪圖必會的SurfaceView,今天我們以SDK中的Sample 游戲 lunarlander中的LunarView具體實現(xiàn),Android123建議大家導入該游戲工程到你的Eclipse 然后自己編譯 先玩一下這個游戲,然后再看代碼 比較好理解。

    view plaincopy to clipboardprint?
    class LunarView extends SurfaceView implements SurfaceHolder.Callback {  
        class LunarThread extends Thread {  
            /* 
            * Difficulty setting constants 
            */ 
            public static final int DIFFICULTY_EASY = 0;  
            public static final int DIFFICULTY_HARD = 1;  
            public static final int DIFFICULTY_MEDIUM = 2;  
            /* 
            * Physics constants 
            */ 
            public static final int PHYS_DOWN_ACCEL_SEC = 35;  
            public static final int PHYS_FIRE_ACCEL_SEC = 80;  
            public static final int PHYS_FUEL_INIT = 60;  
            public static final int PHYS_FUEL_MAX = 100;  
            public static final int PHYS_FUEL_SEC = 10;  
            public static final int PHYS_SLEW_SEC = 120; // degrees/second rotate  
            public static final int PHYS_SPEED_HYPERSPACE = 180;  
            public static final int PHYS_SPEED_INIT = 30;  
            public static final int PHYS_SPEED_MAX = 120;  
            /* 
            * State-tracking constants 
            */ 
            public static final int STATE_LOSE = 1;  
            public static final int STATE_PAUSE = 2;  
            public static final int STATE_READY = 3;  
            public static final int STATE_RUNNING = 4;  
            public static final int STATE_WIN = 5;  
            /* 
            * Goal condition constants 
            */ 
            public static final int TARGET_ANGLE = 18; // > this angle means crash  
            public static final int TARGET_BOTTOM_PADDING = 17; // px below gear  
            public static final int TARGET_PAD_HEIGHT = 8; // how high above ground  
            public static final int TARGET_SPEED = 28; // > this speed means crash  
            public static final double TARGET_WIDTH = 1.6; // width of target  
            /* 
            * UI constants (i.e. the speed & fuel bars) 
            */ 
            public static final int UI_BAR = 100; // width of the bar(s)  
            public static final int UI_BAR_HEIGHT = 10; // height of the bar(s)  
            private static final String KEY_DIFFICULTY = "mDifficulty";  
            private static final String KEY_DX = "mDX";  
            private static final String KEY_DY = "mDY";  
            private static final String KEY_FUEL = "mFuel";  
            private static final String KEY_GOAL_ANGLE = "mGoalAngle";  
            private static final String KEY_GOAL_SPEED = "mGoalSpeed";  
            private static final String KEY_GOAL_WIDTH = "mGoalWidth";  
            private static final String KEY_GOAL_X = "mGoalX";  
            private static final String KEY_HEADING = "mHeading";  
            private static final String KEY_LANDER_HEIGHT = "mLanderHeight";  
            private static final String KEY_LANDER_WIDTH = "mLanderWidth";  
            private static final String KEY_WINS = "mWinsInARow";  
            private static final String KEY_X = "mX";  
            private static final String KEY_Y = "mY";  
            /* 
            * Member (state) fields 
            */ 
            /** The drawable to use as the background of the animation canvas */ 
            private Bitmap mBackgroundImage;  
            /** 
            * Current height of the surface/canvas. 
            * 
            * @see #setSurfaceSize 
            */ 
            private int mCanvasHeight = 1;  
            /** 
            * Current width of the surface/canvas. 
            * 
            * @see #setSurfaceSize 
            */ 
            private int mCanvasWidth = 1;  
            /** What to draw for the Lander when it has crashed */ 
            private Drawable mCrashedImage;  
            /** 
            * Current difficulty -- amount of fuel, allowed angle, etc. Default is 
            * MEDIUM. 
            */ 
            private int mDifficulty;  
            /** Velocity dx. */ 
            private double mDX;  
            /** Velocity dy. */ 
            private double mDY;  
            /** Is the engine burning? */ 
            private boolean mEngineFiring;  
            /** What to draw for the Lander when the engine is firing */ 
            private Drawable mFiringImage;  
            /** Fuel remaining */ 
            private double mFuel;  
            /** Allowed angle. */ 
            private int mGoalAngle;  
            /** Allowed speed. */ 
            private int mGoalSpeed;  
            /** Width of the landing pad. */ 
            private int mGoalWidth;  
            /** X of the landing pad. */ 
            private int mGoalX;  
            /** Message handler used by thread to interact with TextView */ 
            private Handler mHandler;  
            /** 
            * Lander heading in degrees, with 0 up, 90 right. Kept in the range 
            * 0..360. 
            */ 
            private double mHeading;  
            /** Pixel height of lander image. */ 
            private int mLanderHeight;  
            /** What to draw for the Lander in its normal state */ 
            private Drawable mLanderImage;  
            /** Pixel width of lander image. */ 
            private int mLanderWidth;  
            /** Used to figure out elapsed time between frames */ 
            private long mLastTime;  
            /** Paint to draw the lines on screen. */ 
            private Paint mLinePaint;  
            /** "Bad" speed-too-high variant of the line color. */ 
            private Paint mLinePaintBad;  
            /** The state of the game. One of READY, RUNNING, PAUSE, LOSE, or WIN */ 
            private int mMode;  
            /** Currently rotating, -1 left, 0 none, 1 right. */ 
            private int mRotating;  
            /** Indicate whether the surface has been created & is ready to draw */ 
            private boolean mRun = false;  
            /** Scratch rect object. */ 
            private RectF mScratchRect;  
            /** Handle to the surface manager object we interact with */ 
            private SurfaceHolder mSurfaceHolder;  
            /** Number of wins in a row. */ 
            private int mWinsInARow;  
            /** X of lander center. */ 
            private double mX;  
            /** Y of lander center. */ 
            private double mY;  
            public LunarThread(SurfaceHolder surfaceHolder, Context context,  
                    Handler handler) {  
                // get handles to some important objects  
                mSurfaceHolder = surfaceHolder;  
                mHandler = handler;  
                mContext = context;  
                Resources res = context.getResources();  
                // cache handles to our key sprites & other drawables  
                mLanderImage = context.getResources().getDrawable(  
                        R.drawable.lander_plain);  
                mFiringImage = context.getResources().getDrawable(  
                        R.drawable.lander_firing);  
                mCrashedImage = context.getResources().getDrawable(  
                        R.drawable.lander_crashed);  
                // load background image as a Bitmap instead of a Drawable b/c  
                // we don't need to transform it and it's faster to draw this way  
                mBackgroundImage = BitmapFactory.decodeResource(res,  
                        R.drawable.earthrise);  
                // Use the regular lander image as the model size for all sprites  
                mLanderWidth = mLanderImage.getIntrinsicWidth();  
                mLanderHeight = mLanderImage.getIntrinsicHeight();  
                // Initialize paints for speedometer  
                mLinePaint = new Paint();  
                mLinePaint.setAntiAlias(true);  
                mLinePaint.setARGB(255, 0, 255, 0);  
                mLinePaintBad = new Paint();  
                mLinePaintBad.setAntiAlias(true);  
                mLinePaintBad.setARGB(255, 120, 180, 0);  
                mScratchRect = new RectF(0, 0, 0, 0);  
                mWinsInARow = 0;  
                mDifficulty = DIFFICULTY_MEDIUM;  
                // initial show-up of lander (not yet playing)  
                mX = mLanderWidth;  
                mY = mLanderHeight * 2;  
                mFuel = PHYS_FUEL_INIT;  
                mDX = 0;  
                mDY = 0;  
                mHeading = 0;  
                mEngineFiring = true;  
            }  
            /** 
            * Starts the game, setting parameters for the current difficulty. 
            */ 
            public void doStart() {  
                synchronized (mSurfaceHolder) {  
                    // First set the game for Medium difficulty  
                    mFuel = PHYS_FUEL_INIT;  
                    mEngineFiring = false;  
                    mGoalWidth = (int) (mLanderWidth * TARGET_WIDTH);  
                    mGoalSpeed = TARGET_SPEED;  
                    mGoalAngle = TARGET_ANGLE;  
                    int speedInit = PHYS_SPEED_INIT;  
                    // Adjust difficulty params for EASY/HARD  
                    if (mDifficulty == DIFFICULTY_EASY) {  
                        mFuel = mFuel * 3 / 2;  
                        mGoalWidth = mGoalWidth * 4 / 3;  
                        mGoalSpeed = mGoalSpeed * 3 / 2;  
                        mGoalAngle = mGoalAngle * 4 / 3;  
                        speedInit = speedInit * 3 / 4;  
                    } else if (mDifficulty == DIFFICULTY_HARD) {  
                        mFuel = mFuel * 7 / 8;  
                        mGoalWidth = mGoalWidth * 3 / 4;  
                        mGoalSpeed = mGoalSpeed * 7 / 8;  
                        speedInit = speedInit * 4 / 3;  
                    }  
                    // pick a convenient initial location for the lander sprite  
                    mX = mCanvasWidth / 2;  
                    mY = mCanvasHeight - mLanderHeight / 2;  
                    // start with a little random motion  
                    mDY = Math.random() * -speedInit;  
                    mDX = Math.random() * 2 * speedInit - speedInit;  
                    mHeading = 0;  
                    // Figure initial spot for landing, not too near center  
                    while (true) {  
                        mGoalX = (int) (Math.random() * (mCanvasWidth - mGoalWidth));  
                        if (Math.abs(mGoalX - (mX - mLanderWidth / 2)) > mCanvasHeight / 6)  
                            break;  
                    }  
                    mLastTime = System.currentTimeMillis() + 100;  
                    setState(STATE_RUNNING);  
                }  
            }  
            /** 
            * Pauses the physics update & animation. 
            */ 
            public void pause() {  
                synchronized (mSurfaceHolder) {  
                    if (mMode == STATE_RUNNING) setState(STATE_PAUSE);  
                }  
            }  
            /** 
            * Restores game state from the indicated Bundle. Typically called when 
            * the Activity is being restored after having been previously 
            * destroyed. 
            * 
            * @param savedState Bundle containing the game state 
            */ 
            public synchronized void restoreState(Bundle savedState) {  
                synchronized (mSurfaceHolder) {  
                    setState(STATE_PAUSE);  
                    mRotating = 0;  
                    mEngineFiring = false;  
                    mDifficulty = savedState.getInt(KEY_DIFFICULTY);  
                    mX = savedState.getDouble(KEY_X);  
                    mY = savedState.getDouble(KEY_Y);  
                    mDX = savedState.getDouble(KEY_DX);  
                    mDY = savedState.getDouble(KEY_DY);  
                    mHeading = savedState.getDouble(KEY_HEADING);  
                    mLanderWidth = savedState.getInt(KEY_LANDER_WIDTH);  
                    mLanderHeight = savedState.getInt(KEY_LANDER_HEIGHT);  
                    mGoalX = savedState.getInt(KEY_GOAL_X);  
                    mGoalSpeed = savedState.getInt(KEY_GOAL_SPEED);  
                    mGoalAngle = savedState.getInt(KEY_GOAL_ANGLE);  
                    mGoalWidth = savedState.getInt(KEY_GOAL_WIDTH);  
                    mWinsInARow = savedState.getInt(KEY_WINS);  
                    mFuel = savedState.getDouble(KEY_FUEL);  
                }  
            }  
            @Override 
            public void run() {  
                while (mRun) {  
                    Canvas c = null;  
                    try {  
                        c = mSurfaceHolder.lockCanvas(null);  
                        synchronized (mSurfaceHolder) {  
                            if (mMode == STATE_RUNNING) updatePhysics();  
                            doDraw(c);  
                        }  
                    } finally {  
                        // do this in a finally so that if an exception is thrown  
                        // during the above, we don't leave the Surface in an  
                        // inconsistent state  
                        if (c != null) {  
                            mSurfaceHolder.unlockCanvasAndPost(c);  
                        }  
                    }  
                }  
            }  
            /** 
            * Dump game state to the provided Bundle. Typically called when the 
            * Activity is being suspended. 
            * 
            * @return Bundle with this view's state 
            */ 
            public Bundle saveState(Bundle map) {  
                synchronized (mSurfaceHolder) {  
                    if (map != null) {  
                        map.putInt(KEY_DIFFICULTY, Integer.valueOf(mDifficulty));  
                        map.putDouble(KEY_X, Double.valueOf(mX));  
                        map.putDouble(KEY_Y, Double.valueOf(mY));  
                        map.putDouble(KEY_DX, Double.valueOf(mDX));  
                        map.putDouble(KEY_DY, Double.valueOf(mDY));  
                        map.putDouble(KEY_HEADING, Double.valueOf(mHeading));  
                        map.putInt(KEY_LANDER_WIDTH, Integer.valueOf(mLanderWidth));  
                        map.putInt(KEY_LANDER_HEIGHT, Integer  
                                .valueOf(mLanderHeight));  
                        map.putInt(KEY_GOAL_X, Integer.valueOf(mGoalX));  
                        map.putInt(KEY_GOAL_SPEED, Integer.valueOf(mGoalSpeed));  
                        map.putInt(KEY_GOAL_ANGLE, Integer.valueOf(mGoalAngle));  
                        map.putInt(KEY_GOAL_WIDTH, Integer.valueOf(mGoalWidth));  
                        map.putInt(KEY_WINS, Integer.valueOf(mWinsInARow));  
                        map.putDouble(KEY_FUEL, Double.valueOf(mFuel));  
                    }  
                }  
                return map;  
            }  
            /** 
            * Sets the current difficulty. 
            * 
            * @param difficulty 
            */ 
            public void setDifficulty(int difficulty) {  
                synchronized (mSurfaceHolder) {  
                    mDifficulty = difficulty;  
                }  
            }  
            /** 
            * Sets if the engine is currently firing. 
            */ 
            public void setFiring(boolean firing) {  
                synchronized (mSurfaceHolder) {  
                    mEngineFiring = firing;  
                }  
            }  
            /** 
            * Used to signal the thread whether it should be running or not. 
            * Passing true allows the thread to run; passing false will shut it 
            * down if it's already running. Calling start() after this was most 
            * recently called with false will result in an immediate shutdown. 
            * 
            * @param b true to run, false to shut down 
            */ 
            public void setRunning(boolean b) {  
                mRun = b;  
            }  
            /** 
            * Sets the game mode. That is, whether we are running, paused, in the 
            * failure state, in the victory state, etc. 
            * 
            * @see #setState(int, CharSequence) 
            * @param mode one of the STATE_* constants 
            */ 
            public void setState(int mode) {  
                synchronized (mSurfaceHolder) {  
                    setState(mode, null);  
                }  
            }  
            /** 
            * Sets the game mode. That is, whether we are running, paused, in the 
            * failure state, in the victory state, etc. 
            * 
            * @param mode one of the STATE_* constants 
            * @param message string to add to screen or null 
            */ 
            public void setState(int mode, CharSequence message) {  
                /* 
                * This method optionally can cause a text message to be displayed 
                * to the user when the mode changes. Since the View that actually 
                * renders that text is part of the main View hierarchy and not 
                * owned by this thread, we can't touch the state of that View. 
                * Instead we use a Message + Handler to relay commands to the main 
                * thread, which updates the user-text View. 
                */ 
                synchronized (mSurfaceHolder) {  
                    mMode = mode;  
                    if (mMode == STATE_RUNNING) {  
                        Message msg = mHandler.obtainMessage();  
                        Bundle b = new Bundle();  
                        b.putString("text", "");  
                        b.putInt("viz", View.INVISIBLE);  
                        msg.setData(b);  
                        mHandler.sendMessage(msg);  
                    } else {  
                        mRotating = 0;  
                        mEngineFiring = false;  
                        Resources res = mContext.getResources();  
                        CharSequence str = "";  
                        if (mMode == STATE_READY)  
                            str = res.getText(R.string.mode_ready);  
                        else if (mMode == STATE_PAUSE)  
                            str = res.getText(R.string.mode_pause);  
                        else if (mMode == STATE_LOSE)  
                            str = res.getText(R.string.mode_lose);  
                        else if (mMode == STATE_WIN)  
                            str = res.getString(R.string.mode_win_prefix)  
                                    + mWinsInARow + " " 
                                    + res.getString(R.string.mode_win_suffix);  
                        if (message != null) {  
                            str = message + "\n" + str;  
                        }  
                        if (mMode == STATE_LOSE) mWinsInARow = 0;  
                        Message msg = mHandler.obtainMessage();  
                        Bundle b = new Bundle();  
                        b.putString("text", str.toString());  
                        b.putInt("viz", View.VISIBLE);  
                        msg.setData(b);  
                        mHandler.sendMessage(msg);  
                    }  
                }  
            }  
            /* Callback invoked when the surface dimensions change. */ 
            public void setSurfaceSize(int width, int height) {  
                // synchronized to make sure these all change atomically  
                synchronized (mSurfaceHolder) {  
                    mCanvasWidth = width;  
                    mCanvasHeight = height;  
                    // don't forget to resize the background image  
                    mBackgroundImage = mBackgroundImage.createScaledBitmap(  
                            mBackgroundImage, width, height, true);  
                }  
            } 

     

    本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034565.aspx



                                                                                                           --    學海無涯
            

    主站蜘蛛池模板: 男人都懂www深夜免费网站| 青青免费在线视频| 可以免费观看的国产视频| 伊人久久精品亚洲午夜| 尤物视频在线免费观看| 亚洲男人天堂2020| 中文字幕看片在线a免费| 国产AV无码专区亚洲AVJULIA | 亚洲国产一区国产亚洲| 午夜理伦剧场免费| 亚洲国产精品午夜电影| 国国内清清草原免费视频99| www.亚洲日本| 国产国产人免费人成免费视频 | 又粗又大又黑又长的免费视频| 亚洲精品国产福利片| 国产一精品一AV一免费孕妇| 亚洲欧美日韩国产精品一区| 免费少妇a级毛片| 免费一区二区无码东京热| 一边摸一边爽一边叫床免费视频 | 又粗又大又硬又爽的免费视频| 狼色精品人妻在线视频免费| 久久精品国产亚洲AV不卡| 久久久国产精品福利免费| 亚洲毛片在线免费观看| 破了亲妺妺的处免费视频国产| 免费国产草莓视频在线观看黄| 在线视频观看免费视频18| 添bbb免费观看高清视频| 亚洲区不卡顿区在线观看| 青青草原1769久久免费播放| 亚洲日韩国产精品乱-久| 亚洲人成人无码网www国产| 久久免费国产视频| 亚洲AV无码片一区二区三区| 在线观看人成网站深夜免费| 最新国产成人亚洲精品影院| 亚洲无线一二三四区手机| 久久国产美女免费观看精品| 亚洲色av性色在线观无码|