我正在学习用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;
}
}