如何在Android SurfaceView上实现并绘制自定义按钮

时间:2019-01-29 09:00:07

标签: android surfaceview scene

我正在学习用Android开发2D游戏。我是一个完整的新秀。我遵循了一些教程,以实现SurfaceViews,MainThread等,并且一切正常。

现在,我想在主菜单中放置一个“开始游戏”按钮,我想知道什么是最好的方法。

我可以声明类似private Bitmap button;的按钮,并在onTouch事件上捕获用户的点击并执行某些功能(如果用户点击的坐标位于按钮内)。

但是我想知道是否可以做一个自定义类来管理动画,功能,过渡以及与该按钮相关的所有事情。

我不需要代码(我正在学习自己),只需说明如何执行即可。我正在考虑使“开始”按钮扩展“场景”,或者扩展“位图”类。

我将在MainManu类中对每个包含UI的GameObject进行对象列表处理,并在每次绘制和每次触摸时检查列表。

你怎么看?

主要活动

public class MainActivity extends Activity {
    private SceneHandler _sceneHandler;
    private DBCore database;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        database = new DBCore(this, getResources().getString(R.string.db_name),
                            null, 1);

        _sceneHandler = new SceneHandler(this);
        setContentView(_sceneHandler.getContentView());
    }
}

MainThread

public class MainThread extends Thread {
    private SurfaceHolder surfaceHolder;
    private GameView gameView;
    private boolean running;
    public static Canvas canvas;
    private int targetFPS = 60;
    private double averageFPS;

    public MainThread(SurfaceHolder surfaceHolder, GameView gameView) {

        super();
        this.surfaceHolder = surfaceHolder;
        this.gameView = gameView;

    }

    @Override
    public void run() {
        long startTime;
        long timeMillis;
        long waitTime;
        long totalTime = 0;
        int frameCount = 0;
        long targetTime = 1000 / targetFPS;

        while (running) {
            startTime = System.nanoTime();
            canvas = null;

            try {
                canvas = this.surfaceHolder.lockCanvas();
                synchronized(surfaceHolder) {
                    this.gameView.update();
                    this.gameView.draw(canvas);
                }
            } catch (Exception e) {       }
            finally {
                if (canvas != null)            {
                    try {
                        surfaceHolder.unlockCanvasAndPost(canvas);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            timeMillis = (System.nanoTime() - startTime) / 1000000;
            waitTime = targetTime - timeMillis;

            try {
                this.sleep(waitTime);
            } catch (Exception e) {}

            totalTime += System.nanoTime() - startTime;
            frameCount++;
            if (frameCount == targetFPS)        {
                averageFPS = 1000 / ((totalTime / frameCount) / 1000000);
                frameCount = 0;
                totalTime = 0;
                System.out.println(averageFPS);
            }
        }

    }

    public void setRunning(boolean isRunning) {
        running = isRunning;
    }
}

GameView(又名SurfaceView)

public class GameView extends SurfaceView implements SurfaceHolder.Callback {
    private MainThread thread;

    public GameView(Context context) {
        super(context);

        getHolder().addCallback(this);
        thread = new MainThread(getHolder(), this);
        setFocusable(true);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        thread.setRunning(true);
        thread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        while (retry) {
            try {
                thread.setRunning(false);
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            retry = false;
        }
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
    }

    public void update() {

    }
}

SceneHandler(在场景之间进行更改并对更改进行一些逻辑处理)

public class SceneHandler {
    private Canvas _canvas;

    private Scene _currentScene;
    private MainMenu _mainMenu;
    private LoadingBattle _loadingBattle;
    private Battlefield _battlefield;

    public SceneHandler(Context context) {
        this._mainMenu = new MainMenu(context);
        this._currentScene = this._mainMenu;
    }

    public void changeToScene(String newScene)
    {
        try {
            switch (newScene)
            {
                case "MainMenu":
                    this._currentScene = this._mainMenu;
                    break;
                case "LoadingBattle":
                    this._currentScene = this._loadingBattle;
                    break;
                case "Battlefield":
                    this._currentScene = this._battlefield;
                    break;
                default:
                    throw new Exception("Unrecongnized Scene");
            }
        } catch (Exception e) {
            //
        }
    }

    public Scene getContentView() {
        return _currentScene;
    }
}

场景(扩展的主类)

public class Scene extends GameView implements View.OnTouchListener {
    private Scene _currentScene;
    private ArrayList<Scene> _gameScenes;

    public Scene(Context context) {
        super(context);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
}

MainMenu(最后是我想放置按钮的场景)

public class MainMenu extends Scene {
    private Bitmap background;
    private Context context;

    public MainMenu(Context context) {
        super(context);
        this.context = context;
        background = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.varaldor_menu_background);
    }

    private Matrix getScaleTransformationMatrix() {
        float originalWidth = background.getWidth();
        float originalHeight = background.getHeight();
        float scale = this.getScreenSize().get("width") / originalWidth;

        float xTranslation = 0.0f;
        float yTranslation = (this.getScreenSize().get("height") - originalHeight * scale) / 2.0f;
        Matrix transformation = new Matrix();
        transformation.postTranslate(xTranslation, yTranslation);
        transformation.preScale(scale, scale);
        return transformation;
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.drawBitmap(background, 0, 0, null);
        Paint paint = new Paint();
        paint.setFilterBitmap(true);

        canvas.drawBitmap(background, getScaleTransformationMatrix(), paint);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                Toast.makeText(context,
                    "Toast por defecto", Toast.LENGTH_SHORT);
                break;
        }
        return true;
    }

    private Map<String, Integer> getScreenSize() {
        Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        Integer width = size.x;
        Integer height = size.y;
        Map<String, Integer> screenSizeArray = new HashMap<String, Integer>();
        screenSizeArray.put("width", width);
        screenSizeArray.put("height", height);
        return screenSizeArray;
    }
}

0 个答案:

没有答案