onDraw()方法仅在我在onDraw()中创建对象时才起作用

时间:2015-10-23 10:44:23

标签: java android-activity

我遇到了问题。我不知道为什么我不能在我的iniGame()方法中创建对象。当我从GameObject类创建对象并使用render()方法中的方法onDraw()时,该方法不起作用。仅当我在onDraw()方法中创建所有相对对象时才有效。

我的布局XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="de.fhflensburg.manichja.barrier51.GameActivity">

    <de.fhflensburg.manichja.barrier51.GameView
        android:id="@+id/gameView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/gameView"
        />
</RelativeLayout>

我的游戏活动:

package de.fhflensburg.manichja.barrier51;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class GameActivity extends AppCompatActivity {


    private GameView gameView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        gameView = new GameView(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_game, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

我的GameView

    package de.fhflensburg.manichja.barrier51;

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.os.CountDownTimer;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;


    public class GameView extends View {

        private Canvas canvas;
        private Context context;
        private Paint peter;
        private GameObject ball;

        public GameView(Context context) {
            super(context);
            this.context = context;
            initGame();
        }

        public void initGame(){


            //ball.setSprite(R.drawable.menu_background);
        }

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

        public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }

        @Override
        public void onDraw(Canvas canvas){
            ball = new GameObject(this.context);
            this.canvas = canvas;
            peter = new Paint();
            peter.setColor(Color.BLUE);
            canvas.drawRect(100, 100, 200, 200, peter);
            ball.render(canvas,peter);
        }
}

我的GameObject代码

package de.fhflensburg.manichja.barrier51;

    import android.content.Context;
    import android.content.res.ColorStateList;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Point;
    import android.graphics.drawable.Drawable;
    import android.util.Log;
    import android.view.View;
    import android.widget.ImageView;
    import android.util.Size;


public class GameObject {
    private Size size;      // A color as stated as a resource in the XML file (thus, it is an int)
    private Point position; // A color as stated as a resource in the XML file (thus, it is an int)
    private int fillColor;      // A color as stated as a resource in the XML file (thus, it is an int)
    private int strokeColor;// A color as stated as a resource in the XML file (thus, it is an int)
    private int sprite;// A color as stated as a resource in the XML file (thus, it is an int)


 private Bitmap ourSprite;
    private Context conny;

    public GameObject(Context context)
    {
        this.conny = context;
        /*Paint myPaint = new Paint();
        myPaint.setColor(Color.rgb(0, 0, 0));
        myPaint.setStrokeWidth(10);
        c.drawRect(100, 100, 200, 200, myPaint);*/
    }

    /**
     * Sets the position of the GameObject on the screen.
     * @param position A Point instance with x and y
     */
    public void setPosition(Point position)
    {
        this.position = position;
    }

    /**
     * Sets the fill color of the game object. If it has a Sprite image, the assigned color will be ignored.
     * @param color A color resource, defined in the XML file (e.g. R.color.limegreen)
     */
    public void setFillColor(int color)
    {
        this.fillColor = color;
    }

    /**
     * Sets the stroke color of the game object. If it has a Sprite image, the assigned color will be ignored.
     * @param color A color resource, defined in the XML file (e.g. R.color.limegreen)
     */
    public void setStrokeColor(int color)
    {
        this.strokeColor = color;
    }

    /**
     * @return Delivers the current size of the GameObject
     */
    public Size getSize()
    {
        return size;
    }

    /**
     * @return Delivers the current position of the GameObject
     */
    public Point getPosition()
    {
        return position;
    }

    /**
     * @return Delivers the current position of the GameObject as stated in the XML file.
     */
    public int getFillColor()
    {
        return fillColor;
    }

    /**
     * @return Delivers the current stroke color of the GameObject as stated in the XML file.
     */
    public int getStrokeColor()
    {
        return strokeColor;
    }

    /**
     * Checks for a collision of this object with another instance of a GameObject.
     * @param obj The object to be checked for collision
     * @return Returns true if the objects' coordinates overlap at any pixel.
     */
    public boolean overlaps(GameObject obj)
    {
        if (getPosition().x < obj.getPosition().x + obj.getSize().getWidth() &&
                getPosition().x + getSize().getWidth() > obj.getPosition().x &&
                getPosition().y < obj.getPosition().y + obj.getSize().getHeight() &&
                getSize().getHeight() + getPosition().y > obj.getPosition().y)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * Sets the sprite image of the GameObject.
     * @param sprite A bitmap resource as defined in the XML file.
     */
    public void setSprite(int sprite) {

        Log.i("Peter", "Inigame get started"+sprite);
        this.sprite = sprite;
        ourSprite = BitmapFactory.decodeResource(this.conny.getResources(),R.drawable.menu_background);
    }

    /**
     * @return Delivers the sprite resource id as an Integer.
     */
    public Bitmap getSprite() {

        return ourSprite;
    }

    /**
     * Renders the object with the current attributes on the screen.
     */
    public void render(Canvas c,Paint paint)
    {
        c.drawRect(0,0,120,120,paint);
    }

}

1 个答案:

答案 0 :(得分:0)

您收到NullPointerException,因为您的initGame可能未被调用。至少不在调用onDraw的对象上 我的意思是你的GameView有两个实例。第一个实例是您使用以下手动创建的实例:

gameView = new GameView(this);

第二个实例是从XML-File创建的,因为您正在定义:

<de.fhflensburg.manichja.barrier51.GameView
    android:id="@+id/gameView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

所以第二个实例是由App自动创建的。而且你一开始就不知道,三个构造函数中的哪一个被称为。你应该改变两件事:

  1. 在您的活动中,将gameView = new GameView(this);替换为gameView = (GameView) findViewById(R.id.gameView);。这将为您提供GameView的正确实例。有关详细信息,请参阅View-Doc
  2. GameView课程中,在所有三个构造函数中添加对initGame的调用。无论调用什么构造函数,这都可以确保元素被初始化。