0

这让我很头疼,这可能是一些简单的原因造成的——所以我认为我需要一双新的眼睛来看待它。

所有活动都在清单中定义。我确保所有属性都在 onCreate/constructor 中初始化。

'Circle' 对象只是一个通用对象,具有 x、y、半径和颜色的获取和设置。

非常感谢任何帮助。

10-01 16:06:28.338: E/AndroidRuntime(18306): FATAL EXCEPTION: main
10-01 16:06:28.338: E/AndroidRuntime(18306): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dbk.parallelreaction/com.dbk.parallelreaction.GameActivity}: java.lang.NullPointerException
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2308)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.ActivityThread.access$600(ActivityThread.java:153)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.os.Looper.loop(Looper.java:137)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.ActivityThread.main(ActivityThread.java:5227)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at java.lang.reflect.Method.invokeNative(Native Method)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at java.lang.reflect.Method.invoke(Method.java:511)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at dalvik.system.NativeStart.main(Native Method)
10-01 16:06:28.338: E/AndroidRuntime(18306): Caused by: java.lang.NullPointerException
10-01 16:06:28.338: E/AndroidRuntime(18306):    at com.dbk.parallelreaction.util.GameView.<init>(GameView.java:51)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at com.dbk.parallelreaction.GameActivity.onCreate(GameActivity.java:64)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.Activity.performCreate(Activity.java:5104)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
10-01 16:06:28.338: E/AndroidRuntime(18306):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)

有问题的两个文件:

游戏活动.java

package com.dbk.parallelreaction;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.dbk.parallelreaction.util.GameView;

public class GameActivity extends Activity {

    // GameView object to hold current level
    private GameView game;

    // level/score persistance
    private int currentLevel;
    private int currentScore;

    // game countdown timer
    private CountDownTimer timer;
    private int timerTime; // in milliseconds
    private int timerPeriod; // in ms also
    private int timerIndex;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        // initialise
        timerTime = 10000;
        timerPeriod = 50;
        timerIndex = (int) timerTime / timerPeriod;

        // aesthetic stuff
        TextView ins = (TextView) findViewById(R.id.GameInstructions);
        Typeface tf = Typeface.createFromAsset(getAssets(), "Economica-Regular.ttf");
        ins.setTypeface(tf);
        ins.setTextColor(Color.WHITE);
        ins.setTextSize(18);

        // get extras
        Bundle extras = getIntent().getExtras();
        currentLevel = extras.getInt("LEVEL");
        currentScore = extras.getInt("SCORE");

        // check if starting new game, or going to next level
        switch(currentLevel) {
            case 1:
                // new level
                break;
            case 2:
                // etc
                break;
        }

        // add the game view to the layout
        FrameLayout frame = (FrameLayout) findViewById(R.id.GameContainer);
        game = new GameView(this, 2);
        frame.addView(game);

        // timer bar
        final ProgressBar pb = (ProgressBar) findViewById(R.id.GameTimerBar);
        pb.setMax(timerIndex);
        pb.setProgress(timerIndex);
        timer = new CountDownTimer(timerTime, timerPeriod) {
            @Override
            public void onFinish() {
                pb.setProgress(timerIndex);

                Bundle extras = new Bundle();
                extras.putInt("SCORE", 16); // placeholder score

                Intent i = new Intent(getApplicationContext(), GameOverActivity.class);
                i.putExtras(extras);

                // GAME OVER if timer bar empties
                finish();
                startActivity(i);
            }

            @Override
            public void onTick(long msLeft) {
                timerIndex--;
                pb.setProgress(timerIndex);
            }
        }.start();

    }

    // cancel timer if user exits game
    public void onBackPressed() {
        super.onBackPressed();
        timer.cancel();
    }

}

GameView.java更新

package com.dbk.parallelreaction.util;

import java.util.ArrayList;
import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.dbk.parallelreaction.R;

public class GameView extends SurfaceView {

    // Temp ArrayList containing Circle objects
    private ArrayList<Circle> circles;

    // Paint object for colour info
    private Paint paint;

    // number of circles to draw depending on level
    private int numCircles;

    // Current score in the current level
    private int levelScore;


    public GameView(Context context, int numberCircles) {
        super(context);

        LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // replace custom_layout with the name of the .xml file that contains the `FrameLayout` with id R.id.GameContainer
        View v = inflater.inflate(R.layout.activity_game, (ViewGroup) GameView.this.getParent(), true);
        FrameLayout frame = (FrameLayout) v.findViewById(R.id.GameContainer);

        // initialise
        circles = new ArrayList<Circle>();
        paint = new Paint();
        levelScore = 0;

        numCircles = numberCircles;

        // Get the game container FrameView
        int frameW = frame.getWidth();
        int frameH = frame.getHeight();
        int frameL = frame.getLeft();
        int frameT = frame.getTop();

        // fill arraylist with random circles
        Random random = new Random();
        for(int i=0; i<numCircles; i++) {
            // generate coords within the frame
            int x = random.nextInt((frameL+frameW)-frameL) + frameL;
            int y = random.nextInt((frameT+frameH)-frameT) + frameT;

            // random radius between 50 and 10
            int r = random.nextInt(50-10) + 10;

            // add them to the ArrayList
            circles.add(new Circle(x, y, r, Color.WHITE));
        }
    }

    @Override 
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for(int i=0; i<numCircles; i++) {
            Circle c = circles.get(i);

            // set colour
            paint.setColor(c.getColor());

            // draw circle to canvas
            canvas.drawCircle(c.getX(), c.getY(), c.getRadius(), paint);
        }
    }
}
4

2 回答 2

3

如果您的自定义SurfaceView将有一个布局,您需要对其进行充气。在你的构造函数上,你有

FrameLayout frame = (FrameLayout) findViewById(R.id.GameContainer);

您正在尝试引用FrameLayout尚未膨胀的 a。要膨胀相应的 .xml,您需要使用LayoutInflator. 您可以LayoutInflated通过Context传入您的SurfaceView. 例如像这样:

public GameView(Context context, AttributeSet attrs, int numberCircles){

super(context,attrs);
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

 //replace custom_layout with the name of the .xml file that contains the `FrameLayout` with id R.id.GameContainer
View v = inflater.inflate(R.layout.custom_layout, (ViewGroup) GameView.this.getParent(), true);
    FrameLayout frame = (FrameLayout)v.findViewById(R.id.GameContainer);
 //The rest of your code...
}

此外,如果您要将您的文件添加GameView到 .xml 文件中,则需要使用SurfaceView(Context context, AttributeSet attrs)构造函数。

于 2013-10-01T15:40:10.700 回答
0

请检查您的 XML 是否为 GameView.java 中的帧布局提供了正确的 ID

于 2013-10-01T15:39:46.670 回答