Android Studio Surface View with buttons

1

I have a sprite that moves when the Boolean is true and stops when it is false. This I want to activate with a button that I have in the Main activity. The problem is that when I press it the application stops.

What am I doing wrong? What would be the best way to do this?

Thank you.

Main Activity:

    public class MainActivity extends Activity {

    Button b1;
    private Sprite sprite;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        b1= (Button)findViewById(R.id.b1);
    }

    public void play(View view){
        sprite.playing = true;
    }
}

Game:

    public class Juego extends SurfaceView {

    private Bitmap personaje;
    private Sprite sprite;

    public Juego(Context context, AttributeSet attrs) {
        super(context, attrs);

        personaje = BitmapFactory.decodeResource(getResources(), R.drawable.bad1);
        sprite = new Sprite(this, personaje);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        sprite.onDraw(canvas);
        invalidate();
    }
}

Sprite:

    private static final int Horizontal = 4;
    private static final int Vertical = 3;
    private int x = 0;
    private int y = 0;
    private Juego juego;
    private Bitmap personaje;
    private int currentFrame = 0;
    private int ancho;
    private int alto;

    long fps;
    private long timeThisFrame;
    private long lastFrameChangeTime = 0;
    private int frameLengthInMilliseconds = 100;
    int cantFrames = 3;
    boolean playing = false;

    public Sprite(Juego juego, Bitmap personaje){
        this.juego = juego;
        this.personaje = personaje;
        this.ancho = personaje.getWidth() / Vertical;
        this.alto = personaje.getHeight() / Horizontal;
    }

    private void update() {

        if (playing) {

            long startFrame = System.currentTimeMillis();

            if (startFrame > lastFrameChangeTime + frameLengthInMilliseconds) {
                lastFrameChangeTime = startFrame;
                currentFrame++;
                if (currentFrame >= cantFrames) {

                    currentFrame = 0;
                }
            }

            long startFrameTime = System.currentTimeMillis();

            timeThisFrame = System.currentTimeMillis() - startFrameTime;
            if (timeThisFrame >= 1) {
                fps = 1000 / timeThisFrame;
            }
        }
    }

    public void onDraw(Canvas canvas) {
        update();
        int srcX = currentFrame * ancho;
        int srcY = alto;
        Rect src = new Rect(srcX, srcY, srcX + ancho, srcY + alto);
        Rect dst = new Rect(x, y, x + ancho, y + alto);
        canvas.drawBitmap(personaje, src, dst, null);
    }
}

xlm:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_light">


<com.example.agusv.movertipito.Juego
    android:layout_width="368dp"
    android:layout_height="400dp"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp"
    android:background="@android:color/holo_blue_bright"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.0"
android:id="@+id/customView"
android:layout_alignParentStart="true" />

<Button
    android:id="@+id/b1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/customView"
    android:layout_centerHorizontal="true"
    android:onClick="play"
    android:text="Button" />

</RelativeLayout>

LogCat:

07-19 21:20:00.089 18824-18824/com.example.agusv.movertipito E/AndroidRuntime: FATAL EXCEPTION: main
                                                                               Process: com.example.agusv.movertipito, PID: 18824
                                                                               java.lang.IllegalStateException: Could not execute method for android:onClick
                                                                                   at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                                                                                   at android.view.View.performClick(View.java:5610)
                                                                                   at android.view.View$PerformClick.run(View.java:22265)
                                                                                   at android.os.Handler.handleCallback(Handler.java:751)
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                   at android.os.Looper.loop(Looper.java:154)
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
                                                                                Caused by: java.lang.reflect.InvocationTargetException
                                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                                   at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                                                                                   at android.view.View.performClick(View.java:5610) 
                                                                                   at android.view.View$PerformClick.run(View.java:22265) 
                                                                                   at android.os.Handler.handleCallback(Handler.java:751) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                   at android.os.Looper.loop(Looper.java:154) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:6077) 
                                                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
                                                                                Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.agusv.movertipito.Sprite.mover()' on a null object reference
                                                                                   at com.example.agusv.movertipito.MainActivity.play(MainActivity.java:27)
                                                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                                                   at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                                                                                   at android.view.View.performClick(View.java:5610) 
                                                                                   at android.view.View$PerformClick.run(View.java:22265) 
                                                                                   at android.os.Handler.handleCallback(Handler.java:751) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                   at android.os.Looper.loop(Looper.java:154) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:6077) 
                                                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
    
asked by Zekirak 19.07.2017 в 03:40
source

1 answer

1

Reviewing the code of your MainActivity :

  public class MainActivity extends Activity {

    Button b1;
    private Sprite sprite;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        b1= (Button)findViewById(R.id.b1);
    }

    public void play(View view){
        sprite.playing = true;
    }
}

I can determine 2 situations:

The b1 button does not have a listener assigned, therefore when you click and you are performing an action, you are doing it by calling the method by the android:OnClick property that you must have in your layout activity_main.xml , the The method you are calling is:

public void play(View view){
            sprite.playing = true;
        }

and the problem is that sprite is a variable that is not initialized and has a null value, you must initialize the variable to solve your problem.

Update:

Thanks for adding your message in the LogCat, it's actually the problem that I was commenting on:

  

Caused by: java.lang.NullPointerException: Attempt to invoke virtual   method 'void com.example.agusv.movertipito.Sprite.mover ()' on a null   object reference

How can you initialize the variable sprite? You can see this in the Game class:

private Bitmap personaje;
 private Sprite sprite;

 public void play(View view){

        personaje = BitmapFactory.decodeResource(getResources(), R.drawable.bad1);
        sprite = new Sprite(this, personaje);

        sprite.playing = true;

    }
    
answered by 19.07.2017 / 21:42
source