我正在尝试制作这个游戏应用。
每当在Surfaceview ChickenView中调用UpdateCourt()时,我基本上都会使该BitMap bMapEgg下移。我面临的问题是它看起来确实很矮。位图的运动看起来不流畅。
ballPosition.y += 18;是使其移动的代码。

任何想法如何使它看起来平滑?

public class MainActivity extends Activity implements View.OnTouchListener{

    static Canvas canvas;
    static ChickenView chickenView;

    //Used for getting display details like the number of pixels
    static Display display;
    static Point size;
    static int screenWidth;
    static int screenHeight;

    static Point ballPosition;
    static int ballWidth;

    static boolean ballIsMovingDown;

    //stats
    static long lastFrameTime;
    static int fps;
    static int score;
    static int lives;

    static float bitmapPositionX ;
    static float bitmapPositionY ;
    static float bitmapWidth ;
    static float bitmapHeight;
    static Bitmap bMapEgg;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        chickenView = (ChickenView) findViewById(R.id.chickenView);

        //Get the screen size in pixels
        display = getWindowManager().getDefaultDisplay();
        size = new Point();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            display.getSize(size);
        }
        screenWidth = size.x;
        screenHeight = size.y;

        ballWidth = screenWidth / 35;
        ballPosition = new Point();
        ballPosition.x = screenWidth / 2;
        ballPosition.y = 1 + ballWidth;

        final ImageView imageEggs = (ImageView)findViewById(R.id.imageEggs);
        final ImageView imageUpgrade = (ImageView)findViewById(R.id.imageUpgrade);
        TextView test = (TextView)findViewById(R.id.textEggs);
        imageUpgrade.setOnTouchListener(this);
        chickenView.setOnTouchListener(this);
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (v.getId()) {
            case R.id.imageUpgrade:
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    final int x = (int) event.getX();
                    final int y = (int) event.getY();

                    //now map the coords we got to the
                    //bitmap (because of scaling)
                    ImageView imageView = ((ImageView)v);
                    Bitmap bitmap =((BitmapDrawable)imageView.getDrawable()).getBitmap();
                    int pixel = bitmap.getPixel(x,y);

                    //now check alpha for transparency
                    int alpha = Color.alpha(pixel);
                    if (alpha != 0) {
                        //do whatever you would have done for your click event here
                        Intent i;
                        i = new Intent(this, StructureActivity.class);
                        startActivity(i);
                    }
                }
                break;

            case R.id.chickenView:
                float x = event.getX();
                float y = event.getY();
                // Replace these with the correct values (bitmap x, y, width & height)
                float x1 = bitmapPositionX;
                float x2 = x1 + bitmapWidth;
                float y1 = bitmapPositionY;
                float y2 = y1 + bitmapHeight;
                // Test to see if touch is inside the bitmap
                if (x > x1 && x < x2 && y > y1 && y < y2) {
                    // Bitmap was touched
                    Log.v("test", "test");
                } else {
                    Log.v("werkt ghil ni", "test");
                }
                break;
        }
        return true;
    }


    static class ChickenView extends SurfaceView implements Runnable {
        Thread ourThread = null;
        SurfaceHolder ourHolder;
        volatile boolean playingSquash;
        Paint paint;

        public ChickenView(Context context) {
            super(context);
            init(context);
        }

        public ChickenView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }

        public ChickenView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(context);
        }

        private void init(Context context) {
            ourHolder = getHolder();
            paint = new Paint();
            ballIsMovingDown = true;
        }



        @Override
        public void run() {
            while (playingSquash) {
                updateCourt();
                drawCourt();
                controlFPS();
            }

        }


        public void updateCourt() {


            //depending upon the two directions we should be
            //moving in adjust our x any positions
            if (ballIsMovingDown) {
                ballPosition.y += 18;
            }

            //if hits bottom
            if (ballPosition.y > screenHeight - 7*ballWidth) {
                ballIsMovingDown = false;


            }

        }

        public void drawCourt()  {

            if (ourHolder.getSurface().isValid()) {
                canvas = ourHolder.lockCanvas();
                //Paint paint = new Paint();
                canvas.drawColor(Color.BLACK);//the background
                paint.setColor(Color.argb(255, 255, 255, 255));
                paint.setTextSize(45);
                canvas.drawText("Score:" + score + " Lives:" + lives + " fps:" + fps, 20, 40, paint);

                Bitmap bMapEgg = BitmapFactory.decodeResource(getResources(), R.drawable.egg);
                bMapEgg = scaleDown(bMapEgg,180, true);

                Bitmap bMapBackground = BitmapFactory.decodeResource(getResources(), R.drawable.backgrounddd);
                canvas.drawBitmap(bMapBackground, 0, 0, paint);
                canvas.drawBitmap(bMapEgg, ballPosition.x, ballPosition.y, paint);

                bitmapPositionX = ballPosition.x;
                bitmapPositionY = ballPosition.y;

                bitmapWidth = bMapEgg.getWidth();
                bitmapHeight = bMapEgg.getHeight();

                ourHolder.unlockCanvasAndPost(canvas);
            }

        }

        public void controlFPS() {
            long timeThisFrame = (System.currentTimeMillis() - lastFrameTime);
            long timeToSleep = 15 - timeThisFrame;
            if (timeThisFrame > 0) {
                fps = (int) (1000 / timeThisFrame);
            }
            if (timeToSleep > 0) {

                try {
                    ourThread.sleep(timeToSleep);
                } catch (InterruptedException e) {
                }

            }

            lastFrameTime = System.currentTimeMillis();
        }


        public void pause() {
            playingSquash = false;
            try {
                ourThread.join();
            } catch (InterruptedException e) {
            }

        }

        public void resume() {
            playingSquash = true;
            ourThread = new Thread(this);
            ourThread.start();
        }

    }

    @Override
    protected void onStop() {
        super.onStop();

        while (true) {
            chickenView.pause();
            break;
        }

        finish();
    }


    @Override
    protected void onResume() {
        super.onResume();
        chickenView.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        chickenView.pause();
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            chickenView.pause();
            finish();
            return true;
        }
        return false;
    }

    public static Bitmap scaleDown(Bitmap realImage, float maxImageSize,
                                   boolean filter) {
        float ratio = Math.min(
                (float) maxImageSize / realImage.getWidth(),
                (float) maxImageSize / realImage.getHeight());
        int width = Math.round((float) ratio * realImage.getWidth());
        int height = Math.round((float) ratio * realImage.getHeight());

        Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width,
                height, filter);
        return newBitmap;
    }

}

最佳答案

问题在于,在每个帧中,您都需要重新解码和缩放所有位图。

将解码和缩放的位图移出draw方法,将其放在初始化方法中,然后将解码和缩放的位图存储在成员变量(甚至是静态变量)中,以便可以在每个帧中重复使用它们进行绘制。

关于java - 使运动更流畅,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35852450/

10-09 03:39