-3

I'm very new to android coding and I'm trying to make a simple game where there are different squares that move around and overlap each other.

Right now I'm just trying to make a bunch of different views that have squares in certain places that I can later animate and move over top of each other. Im running into a problem where Im getting the following error:

06-08 16:18:31.407: E/AndroidRuntime(16612): FATAL EXCEPTION: main
06-08 16:18:31.407: E/AndroidRuntime(16612): Process: com.example.drawable, PID: 16612
06-08 16:18:31.407: E/AndroidRuntime(16612): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.drawable/com.example.drawable.MainActivity}: java.lang.NullPointerException
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2340)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.ActivityThread.access$800(ActivityThread.java:157)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.os.Handler.dispatchMessage(Handler.java:102)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.os.Looper.loop(Looper.java:157)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.ActivityThread.main(ActivityThread.java:5293)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at java.lang.reflect.Method.invokeNative(Native Method)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at java.lang.reflect.Method.invoke(Method.java:515)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at dalvik.system.NativeStart.main(Native Method)
06-08 16:18:31.407: E/AndroidRuntime(16612): Caused by: java.lang.NullPointerException
06-08 16:18:31.407: E/AndroidRuntime(16612):    at com.example.drawable.Grid.addRandomSquare(Grid.java:54)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at com.example.drawable.Grid.<init>(Grid.java:30)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at com.example.drawable.MyViewGroup.<init>(MyViewGroup.java:26)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at com.example.drawable.MainActivity.onCreate(MainActivity.java:35)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.Activity.performCreate(Activity.java:5389)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
06-08 16:18:31.407: E/AndroidRuntime(16612):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2246)
06-08 16:18:31.407: E/AndroidRuntime(16612):    ... 11 more

MainActivity:

public class MainActivity extends Activity {



public static MyViewGroup vgrp;
public static boolean rfr;
int i;





@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    vgrp = new MyViewGroup(getApplicationContext());
    setContentView(vgrp);




    }
 @Override
 protected void onPause() {
  super.onPause();

 }   

}

ViewGroup:

public class MyViewGroup extends ViewGroup{  


public int direction;
public float touchx;
public float touchy;
public float xprev;
public float yprev;
public  float xnew;
public float ynew;
public  float dx;
public   float dy;
public    int in;
private Grid grid;

public MyViewGroup(Context context) {  
    super(context);     
    grid = new Grid(4);
    System.out.println("hellloooooooo"); //4  
}  

@Override  
protected void onLayout(boolean changed, int l, int t, int r, int b) {  
     // TODO Auto-generated method stub  

}  

public void newRectangleAt(int x, int y){

    Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
    x+=1;
    y+=1;
    x*=GraphicsDriver.scale;
    y*=GraphicsDriver.scale;
    SquareView sq = new SquareView(getContext());
    sq.setPos(x, y);
    GraphicsDriver.graphicsGrid.add(sq);

}

@SuppressLint("NewApi")
public boolean onTouchEvent(MotionEvent ev){




    switch (ev.getAction()) {

        case MotionEvent.ACTION_DOWN: {
            xprev = ev.getX();
            yprev = ev.getY();
            return true;
        }
        case MotionEvent.ACTION_MOVE:
        {

            return false;


        }
        case MotionEvent.ACTION_UP:
        {
            Log.d("com.example.drawable","action completed");
            xnew = ev.getX();
            ynew = ev.getY();
            dx=xnew-xprev;
            dy=ynew-yprev;
            if((dx < 10) && (Math.abs(dx) > Math.abs(dy)))
                   direction = Grid.LEFT;
               else if(( dx > 10) && (Math.abs(dx) > Math.abs(dy)))
                   direction = Grid.RIGHT;
               else if((dy > 10) && (Math.abs(dy) > Math.abs(dx)))
                   direction = Grid.DOWN;

            grid.parseGrid(direction);


            return false;
        }
    }




   invalidate();
   return true;
 }



}

Grid.class:

public class Grid {

private Space[][] grid;
public final static int DOWN = 0;
public final static int RIGHT = 1;
public final static int LEFT = -1;

private GraphicsDriver gd;


//constructs grid of given size 
public Grid(int size){
    int s = size;
    grid = new Space[s][s*2];
    for(int y = 0; y < grid[0].length; y++)
        for(int x = 0; x < grid.length; x++)
            grid[x][y] = new Space();




    gd = new GraphicsDriver(this);
    this.addRandomSquare();
    this.addRandomSquare();


}

public Space[][] getGrid(){
    return this.grid;
}

public GraphicsDriver getGraphicsDriver(){
    return this.gd;
}

public void addRandomSquare(){
    int x = (int)(Math.random()*grid.length-.001);
    boolean b = true;

    for(int y = grid[0].length-1 ; y >= 0 ; y--)
        if(b)
        if( grid[x][y].isFree()==true){
            Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
            grid[x][y].placeSquare(new Square());
            Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
            MainActivity.vgrp.newRectangleAt(x,y);
            Log.d("com.example.drawable","coordinates" + x + ", "+ y + " are free");
            b=false;
        }

}

//returns the space in the given direction -- useful to check space availability
public Space getAdjacentSpace(int x, int y, int direction){
    Space ret;

    ret = null;
    try{
    if(direction == DOWN && grid[x][y+1] != null){
        ret = grid[x][y+1];}
    if(direction == RIGHT && grid[x+1][y] != null){
        ret = grid[x+1][y];}
    if(direction == LEFT && grid[x-1][y] != null){
        ret = grid[x-1][y];}
    }
    catch(ArrayIndexOutOfBoundsException e){
        ret = null;
    }

    return ret;
}

public void parseGrid(int direction){
    if(direction == DOWN)
        for(int y = grid[0].length-1; y >= 0; y--)
            for(int x = 0; x < grid.length; x++)
                attemptMove(x,y,direction);
    if(direction == LEFT)
        for(int x = 1; x < grid.length; x++)
            for(int y = grid[0].length-1; y >= 0; y--)
                attemptMove(x,y,direction);
    if(direction == RIGHT)
        for(int x = grid.length-2; x >= 0 ; x--)
            for(int y = grid[0].length-1; y >= 0; y--)
                attemptMove(x,y,direction);
    addRandomSquare();
    GraphicsDriver.drawGrid();
    Log.d("com.example.drawable","parsed grid");
}

public Space getSpace(int x, int y){
    return grid[x][y];
}

//tries to move the place of the square in the direction swiped
public void attemptMove(int x, int y, int direction){
    try{
        if ((y == (grid[0].length-1)) && (direction==DOWN) && (bottomRowCollapsible())){
            grid[x][y].removeSquare();
        }
        else if(!getSpace(x,y).isFree() && getAdjacentSpace(x,y,direction).isFree()){
            moveSquare(x,y,direction);
        }
        else if (getSpace(x,y).getSquareShade() == getAdjacentSpace(x,y,direction).getSquareShade()){
            grid[x][y].getSquare().setShade();
            moveSquare(x,y,direction);

        }

    }
    catch(NullPointerException e){}
}

//checks if the bottom row is full of the highest shade
private boolean bottomRowCollapsible() {
    boolean b = true;
    for(int x = grid.length-1; x >=0; x-- )
        if(grid[x][grid[0].length-1].getSquareShade()!=6) b = false;
    return b;
}

public void moveSquare(int x, int y, int direction){


        Square sqr = grid[x][y].removeSquare();
        Log.d("com.example.drawable","square removed at " + (x+1)+", " +(y+1));

        if(direction == DOWN &&  y != 0){
            grid[x][y+1].placeSquare(sqr);

            }
        if(direction == RIGHT && (x != grid.length-1)){
            grid[x+1][y].placeSquare(sqr);
            Log.d("com.example.drawable","square placed at " + (x+2) +     ", "+ (y+1));
            }
        if(direction == LEFT && x != 0){
            grid[x-1][y].placeSquare(sqr);


            }

    }
}

SquareView.class:

package com.example.drawable;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SquareView extends View{


    private Paint paint;



    int x;
    int y;

    final int size = 15;


    public SquareView(Context context){
        super(context);

        paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setAlpha(20);
    }
    public void setPos(int x, int y){
        this.x=x;
        this.y=y;
    }


    public void onDraw(Canvas canvas){
        canvas.drawColor(Color.TRANSPARENT);
        canvas.drawRect(x-size, y+size, x+size, y-size, paint);
    }


}

GraphicsDriver.class:

@SuppressWarnings("unused")
public class GraphicsDriver {

    public final int size = 50;
    public final static int scale = 220;

    public static ArrayList<SquareView> graphicsGrid;
    private Paint paint;


    public GraphicsDriver(Grid gr){


        graphicsGrid = new ArrayList<SquareView>();
        paint = new Paint();
        paint.setColor(Color.BLUE);

    }

    public static void drawGrid(){


        for(SquareView square: graphicsGrid){
            MainActivity.vgrp.addView(square);
            }

    }

mainactivity.xml file:

    <?xml version="1.0" encoding="utf-8"?>
<com.example.drawable.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/screen" android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent">

<com.exammple.drawable.SquareView android:id="@+id/SquareView" android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    />

</com.example.drawable.MyViewGroup>

Any help would be very appreciated!!

Ultimo_m
  • 4,724
  • 4
  • 38
  • 60
  • read this http://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors and this http://tinyurl.com/so-hints – ben75 Jun 08 '14 at 20:35
  • Caused by: java.lang.NullPointerException -- com.example.drawable.Grid.addRandomSquare(Grid.java:54) – Marco Acierno Jun 08 '14 at 20:41
  • I understand that it is coming from that line, which is this: "MainActivity.vgrp.newRectangleAt(x,y);" But I still don't understand what is throwing the exception in this. – user3720424 Jun 08 '14 at 21:24

1 Answers1

0

It is coming from that line, which is this: MainActivity.vgrp.newRectangleAt(x,y);

Check the call stack. In onCreate(), you have:

vgrp = new MyViewGroup(getApplicationContext());

However, the constructor of MyViewGroup, calls new Grid(), then addRandomSquare(). This means that when addRandomSquare() executes, the vgrp static field has not been set yet. Hence, the NullPointerException.

Please Take a look at What is a stack trace, and how can I use it to debug my application errors?

As an aside, having static references to Views is a very bad idea, as (1) it will cause memory leaks, and (2) if you create a second instance of this activity, they will both point to the same vgrp (namely, the one that was created last).

Community
  • 1
  • 1
matiash
  • 54,791
  • 16
  • 125
  • 154
  • Alright thank you so much! So I should just remove the static on the vgrp? – user3720424 Jun 09 '14 at 13:17
  • Yes, and passing the MyViewGroup object as parameter of the needed methods (i.e. the Grid constructor, then addRandomSquare). – matiash Jun 09 '14 at 13:56
  • Alright Everything is working but im getting a blank screen still.. The onDraw method is being called and the squares are being drawn on the view, and then added to the viewgroup. Is there some method im missing that would actually cause the child views to appear? Sorry im such a noob – user3720424 Jun 09 '14 at 18:30