I have a class GameActivity
as follows (I just post the relevant part):
public class GameActivity extends AppCompatActivity {
// initiate variables
private GameView mGameView;
private Display mDisplay;
private Point mSize;
public static int window_width = 0;
public static int window_height = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mDisplay = getWindowManager().getDefaultDisplay();
mSize = new Point();
mDisplay.getSize(mSize);
window_width = mSize.x;
window_height = mSize.y;
// initialize game view object
mGameView = new GameView(this);
// adding it to the content view
//setContentView(mGameView);
setContentView(R.layout.activity_game);
}
And I have the class GameView
as follows with two constructors because of the custom view (also just the relevant parts to keep it clear):
private Context mContext;
//These objects will be used for drawing
private SurfaceHolder mSurfaceHolder;
private Paint mPaint;
public GameView(Context context){
super(context);
Log.d("TEST","Constructor 1");
init(context, null);
// clear all lists
...
// create object of map in beginning of game
...
// create objects of HQs
...
// create other sprite objects and add them to lists
...
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
Log.d("TEST","Constructor 2");
init(context, attrs);
}
And I call in both of the constructors the init()
method
private void init(Context context, AttributeSet attrs) {
mContext = context;
mSurfaceHolder = getHolder();
mPaint = new Paint();
mPaint.setColor(Color.DKGRAY);
}
My run()
is like this:
@Override
public void run(){
Log.d("TEST","RUN");
long current_time = 0;
long old_time;
while (playing) {
old_time = current_time;
// update the game
update();
//to draw the frame
//onDraw(canvas);
draw();
//to control (lets the game sleep for some milliseconds)
control();
current_time = SystemClock.elapsedRealtime();
frametime = current_time - old_time;
framerate = 1000/ (current_time - old_time);
}
}
And the draw()
(where the mistake happens) is like this:
private void draw() {
// BUG: mSurfaceHolder.getSurface.isValid ist niemals valid
Canvas canvas;
//if(true){
//checking if surface is valid
if (mSurfaceHolder.getSurface().isValid()) {
Log.d("Test","DRAW");
//locking the canvas
canvas = mSurfaceHolder.lockCanvas();
//drawing a background color for canvas
canvas.drawColor(Color.GREEN);
// call draw methods here
// bigger objects should be called before smaller objects for visibility
draw_ground(canvas);
draw_hq(canvas);
draw_soldiers(canvas);
draw_bullets(canvas);
draw_HUD(canvas);
//Unlocking the canvas
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
No the question is:
If I in the first class GameActivity
pass the object mGameView
of the class GameView
to setContentView
everything is fine and the draw() methods works normal which means mSurfaceHolder.getSurface().isValid())
is valid.
But if I put in the first class setContentView(R.layout.activity_game);
then mSurfaceHolder.getSurface().isValid())
is never valid. Everything else works (e.g. I hear the game sound) but he doesn't draw. If I don't check for mSurfaceHolder.getSurface().isValid())
then the game crashes because in the code below in draw()
the canvas
is empty.
My aim is to create a custom view and overlay this with buttons.
Here is the XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GameActivity">
<!--Test-->
<com.example.mirco.battlefront.GameView
android:id="@+id/gameView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/button"
android:layout_width="119dp"
android:layout_height="wrap_content"
android:text="Button" />
<!--Test-->
</FrameLayout>
The XML seems to be correct because Android Studio recognizes it (custom view with overlayed button). But he doesn't draw in it.
Like I said with setContentView(mGameView);
everything is fine except that I only have one view where I can't overlay buttons and so on which is not what I want.
What am I doing wrong? I tried to follow that LINK as good as possible. I am trying for days now to solve this but also can't find the solution anywhere.
Instead of
mGameView = new GameView(this);
// adding it to the content view
//setContentView(mGameView);
setContentView(R.layout.activity_game);
You should do
setContentView(R.layout.activity_game);
mGameView = (GameView)findViewById (R.id.gameView);
Then the mGameview is the one in your layout.