⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lunarview.java

📁 android 例子中的LunarLander。很有代表意义
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                            || keyCode == KeyEvent.KEYCODE_SPACE) {                        setFiring(false);                        handled = true;                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT                            || keyCode == KeyEvent.KEYCODE_Q                            || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT                            || keyCode == KeyEvent.KEYCODE_W) {                        mRotating = 0;                        handled = true;                    }                }            }            return handled;        }        /**         * Draws the ship, fuel/speed bars, and background to the provided         * Canvas.         */        private void doDraw(Canvas canvas) {            // Draw the background image. Operations on the Canvas accumulate            // so this is like clearing the screen.            canvas.drawBitmap(mBackgroundImage, 0, 0, null);            int yTop = mCanvasHeight - ((int) mY + mLanderHeight / 2);            int xLeft = (int) mX - mLanderWidth / 2;            // Draw the fuel gauge            int fuelWidth = (int) (UI_BAR * mFuel / PHYS_FUEL_MAX);            mScratchRect.set(4, 4, 4 + fuelWidth, 4 + UI_BAR_HEIGHT);            canvas.drawRect(mScratchRect, mLinePaint);            // Draw the speed gauge, with a two-tone effect            double speed = Math.sqrt(mDX * mDX + mDY * mDY);            int speedWidth = (int) (UI_BAR * speed / PHYS_SPEED_MAX);            if (speed <= mGoalSpeed) {                mScratchRect.set(4 + UI_BAR + 4, 4,                        4 + UI_BAR + 4 + speedWidth, 4 + UI_BAR_HEIGHT);                canvas.drawRect(mScratchRect, mLinePaint);            } else {                // Draw the bad color in back, with the good color in front of                // it                mScratchRect.set(4 + UI_BAR + 4, 4,                        4 + UI_BAR + 4 + speedWidth, 4 + UI_BAR_HEIGHT);                canvas.drawRect(mScratchRect, mLinePaintBad);                int goalWidth = (UI_BAR * mGoalSpeed / PHYS_SPEED_MAX);                mScratchRect.set(4 + UI_BAR + 4, 4, 4 + UI_BAR + 4 + goalWidth,                        4 + UI_BAR_HEIGHT);                canvas.drawRect(mScratchRect, mLinePaint);            }            // Draw the landing pad            canvas.drawLine(mGoalX, 1 + mCanvasHeight - TARGET_PAD_HEIGHT,                    mGoalX + mGoalWidth, 1 + mCanvasHeight - TARGET_PAD_HEIGHT,                    mLinePaint);            // Draw the ship with its current rotation            canvas.save();            canvas.rotate((float) mHeading, (float) mX, mCanvasHeight                    - (float) mY);            if (mMode == STATE_LOSE) {                mCrashedImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop                        + mLanderHeight);                mCrashedImage.draw(canvas);            } else if (mEngineFiring) {                mFiringImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop                        + mLanderHeight);                mFiringImage.draw(canvas);            } else {                mLanderImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop                        + mLanderHeight);                mLanderImage.draw(canvas);            }            canvas.restore();        }        /**         * Figures the lander state (x, y, fuel, ...) based on the passage of         * realtime. Does not invalidate(). Called at the start of draw().         * Detects the end-of-game and sets the UI to the next state.         */        private void updatePhysics() {            long now = System.currentTimeMillis();            // Do nothing if mLastTime is in the future.            // This allows the game-start to delay the start of the physics            // by 100ms or whatever.            if (mLastTime > now) return;            double elapsed = (now - mLastTime) / 1000.0;            // mRotating -- update heading            if (mRotating != 0) {                mHeading += mRotating * (PHYS_SLEW_SEC * elapsed);                // Bring things back into the range 0..360                if (mHeading < 0)                    mHeading += 360;                else if (mHeading >= 360) mHeading -= 360;            }            // Base accelerations -- 0 for x, gravity for y            double ddx = 0.0;            double ddy = -PHYS_DOWN_ACCEL_SEC * elapsed;            if (mEngineFiring) {                // taking 0 as up, 90 as to the right                // cos(deg) is ddy component, sin(deg) is ddx component                double elapsedFiring = elapsed;                double fuelUsed = elapsedFiring * PHYS_FUEL_SEC;                // tricky case where we run out of fuel partway through the                // elapsed                if (fuelUsed > mFuel) {                    elapsedFiring = mFuel / fuelUsed * elapsed;                    fuelUsed = mFuel;                    // Oddball case where we adjust the "control" from here                    mEngineFiring = false;                }                mFuel -= fuelUsed;                // have this much acceleration from the engine                double accel = PHYS_FIRE_ACCEL_SEC * elapsedFiring;                double radians = 2 * Math.PI * mHeading / 360;                ddx = Math.sin(radians) * accel;                ddy += Math.cos(radians) * accel;            }            double dxOld = mDX;            double dyOld = mDY;            // figure speeds for the end of the period            mDX += ddx;            mDY += ddy;            // figure position based on average speed during the period            mX += elapsed * (mDX + dxOld) / 2;            mY += elapsed * (mDY + dyOld) / 2;            mLastTime = now;            // Evaluate if we have landed ... stop the game            double yLowerBound = TARGET_PAD_HEIGHT + mLanderHeight / 2                    - TARGET_BOTTOM_PADDING;            if (mY <= yLowerBound) {                mY = yLowerBound;                int result = STATE_LOSE;                CharSequence message = "";                Resources res = mContext.getResources();                double speed = Math.sqrt(mDX * mDX + mDY * mDY);                boolean onGoal = (mGoalX <= mX - mLanderWidth / 2 && mX                        + mLanderWidth / 2 <= mGoalX + mGoalWidth);                // "Hyperspace" win -- upside down, going fast,                // puts you back at the top.                if (onGoal && Math.abs(mHeading - 180) < mGoalAngle                        && speed > PHYS_SPEED_HYPERSPACE) {                    result = STATE_WIN;                    mWinsInARow++;                    doStart();                    return;                    // Oddball case: this case does a return, all other cases                    // fall through to setMode() below.                } else if (!onGoal) {                    message = res.getText(R.string.message_off_pad);                } else if (!(mHeading <= mGoalAngle || mHeading >= 360 - mGoalAngle)) {                    message = res.getText(R.string.message_bad_angle);                } else if (speed > mGoalSpeed) {                    message = res.getText(R.string.message_too_fast);                } else {                    result = STATE_WIN;                    mWinsInARow++;                }                setState(result, message);            }        }    }    /** Handle to the application context, used to e.g. fetch Drawables. */    private Context mContext;    /** Pointer to the text view to display "Paused.." etc. */    private TextView mStatusText;    /** The thread that actually draws the animation */    private LunarThread thread;    public LunarView(Context context, AttributeSet attrs) {        super(context, attrs);        // register our interest in hearing about changes to our surface        SurfaceHolder holder = getHolder();        holder.addCallback(this);        // create thread only; it's started in surfaceCreated()        thread = new LunarThread(holder, context, new Handler() {            @Override            public void handleMessage(Message m) {                mStatusText.setVisibility(m.getData().getInt("viz"));                mStatusText.setText(m.getData().getString("text"));            }        });        setFocusable(true); // make sure we get key events    }    /**     * Fetches the animation thread corresponding to this LunarView.     *      * @return the animation thread     */    public LunarThread getThread() {        return thread;    }    /**     * Standard override to get key-press events.     */    @Override    public boolean onKeyDown(int keyCode, KeyEvent msg) {        return thread.doKeyDown(keyCode, msg);    }    /**     * Standard override for key-up. We actually care about these, so we can     * turn off the engine or stop rotating.     */    @Override    public boolean onKeyUp(int keyCode, KeyEvent msg) {        return thread.doKeyUp(keyCode, msg);    }    /**     * Standard window-focus override. Notice focus lost so we can pause on     * focus lost. e.g. user switches to take a call.     */    @Override    public void onWindowFocusChanged(boolean hasWindowFocus) {        if (!hasWindowFocus) thread.pause();    }    /**     * Installs a pointer to the text view used for messages.     */    public void setTextView(TextView textView) {        mStatusText = textView;    }    /* Callback invoked when the surface dimensions change. */    public void surfaceChanged(SurfaceHolder holder, int format, int width,            int height) {        thread.setSurfaceSize(width, height);    }    /*     * Callback invoked when the Surface has been created and is ready to be     * used.     */    public void surfaceCreated(SurfaceHolder holder) {        // start the thread here so that we don't busy-wait in run()        // waiting for the surface to be created        thread.setRunning(true);        thread.start();    }    /*     * Callback invoked when the Surface has been destroyed and must no longer     * be touched. WARNING: after this method returns, the Surface/Canvas must     * never be touched again!     */    public void surfaceDestroyed(SurfaceHolder holder) {        // we have to tell thread to shut down & wait for it to finish, or else        // it might touch the Surface after we return and explode        boolean retry = true;        thread.setRunning(false);        while (retry) {            try {                thread.join();                retry = false;            } catch (InterruptedException e) {            }        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -