setText causing app to crash upon starting












-2












$begingroup$


I have built a small maze game in which you have to navigate to the end before the 10 second timer runs out. The timer works fine and restarts the game if you run out of time, however I have tried numerous methods to update the textview with the timer but all of them cause the app to crash upon starting. Any help would be appreciated, thank you.



Text View XML:



<TextView
android:id="@+id/timerTextView"


Java File:



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.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;
import java.util.Stack;

public class GameView extends View {

private enum Direction {
UP, DOWN, LEFT, RIGHT
} // enumeration to hold different direction states

private Cell cells; // 2d array for the maze
private Cell player, exit; // Cell objects for the player and exit squares
private static final int COLS = 7, ROWS = 12; // number of columns and rows respectively
private static final float WALL_THICKNESS = 5; // thickness of maze walls
private float cellSize, hMargin, vMargin; // cell size and horizontal/vertical margins
private Paint wallPaint, playerPaint, exitPaint; // paint objects for the walls, player and exit squares
private Random random; // random number for maze generation algorithm
private float timer;
private TextView timerText;


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

wallPaint = new Paint();
wallPaint.setColor(Color.BLACK); // set wall colour
wallPaint.setStrokeWidth(WALL_THICKNESS); // set wall thickness

playerPaint = new Paint();
playerPaint.setColor(Color.RED);
exitPaint = new Paint();
exitPaint.setColor(Color.BLUE);

random = new Random(); // initialise new random number

createMaze();
}

private Cell getNeighbour(Cell cell) {

ArrayList<Cell> neighbours = new ArrayList<>();

// left neighbour cell
if (cell.col > 0) // avoid values below 0 causing errors
if (!cells[cell.col - 1][cell.row].visited)
neighbours.add(cells[cell.col - 1][cell.row]);

// right neighbour cell
if (cell.col < COLS - 1) // only check up to the size of the maze
if (!cells[cell.col + 1][cell.row].visited)
neighbours.add(cells[cell.col + 1][cell.row]);

// top neighbour cell
if (cell.row > 0) // avoid values below 0 causing errors
if (!cells[cell.col][cell.row - 1].visited)
neighbours.add(cells[cell.col][cell.row - 1]);

// bottom neighbour cell
if (cell.row < ROWS - 1)
if (!cells[cell.col][cell.row + 1].visited)
neighbours.add(cells[cell.col][cell.row + 1]);

if (neighbours.size() > 0) { // check to make sure the
int index = random.nextInt(neighbours.size()); // random int based on the size of the array (i.e. only between 1 and 2)
return neighbours.get(index);
}
return null;
}

private void removeWall(Cell current, Cell next) {

// check if below
if (current.col == next.col && current.row == next.row + 1) {
current.topWall = false;
next.bottomWall = false;
}

// check if above
if (current.col == next.col && current.row == next.row - 1) {
current.bottomWall = false;
next.topWall = false;
}

// check if right
if (current.col == next.col + 1 && current.row == next.row) {
current.leftWall = false;
next.rightWall = false;
}

// check if left
if (current.col == next.col - 1 && current.row == next.row) {
current.rightWall = false;
next.leftWall = false;
}


}

private void createMaze() { // initialise maze

Stack<Cell> stack = new Stack<>(); // create stack for cell objects
Cell current, next; // current and next position of maze algorithm
timerText = findViewById(R.id.timerTextView);
timer = 10;

cells = new Cell[COLS][ROWS];

for (int x=0; x<COLS; x++) { // nested for loop to create 2d array of objects for the maze
for (int y=0; y<ROWS; y++) {
cells[x][y] = new Cell(x, y);
}
}

player = cells[0][0]; // set start square to top left
exit = cells[COLS-1][ROWS-1]; // set exit square to bottom right

current = cells[0][0]; // start with current cell at the first cell in the top left
current.visited = true;

do {
next = getNeighbour(current); // find random available neighbour cell

if (next != null) { // check to make sure it found a cell
removeWall(current, next); // remove the wall between the first and second cell
stack.push(current); // push the current cell to the stack
current = next; // set new cell to current
current.visited = true;
} else // if a cell wasnt found
current = stack.pop(); // go back a stage, pop a value off the stack
} while (!stack.empty()); // end loop once the stack is empty


mCountDownTimer.start();
}

@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.CYAN); // background colour

int canvasWidth = getWidth(); // get width of canvas
int canvasHeight = getHeight(); // get height of canvas

if (canvasWidth / canvasHeight < COLS/ROWS) // using canvas pixel size, calculate the size of the cells
cellSize = (canvasWidth / (COLS+1)) - 10;
else
cellSize = (canvasHeight / (ROWS+1)) - 10;

hMargin = (canvasWidth - COLS*cellSize)/2; // (width of the canvas - width of the maze)
vMargin = (canvasHeight - ROWS*cellSize)/1.5f; // (height of the canvas - height of the maze)

canvas.translate(hMargin, vMargin); // shift the origin (where to start drawing the maze) by the margin size x, y

for (int x=0; x<COLS; x++) { // nested 'for' loop to create the maze
for (int y=0; y<ROWS; y++) {
if (cells[x][y].topWall) // if there is a top wall, draw it
canvas.drawLine(x*cellSize, y*cellSize, (x+1)*cellSize, y*cellSize, wallPaint);
if (cells[x][y].leftWall)
canvas.drawLine(x*cellSize, y*cellSize, x*cellSize, (y+1)*cellSize, wallPaint);
if (cells[x][y].bottomWall)
canvas.drawLine(x*cellSize, (y+1)*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
if (cells[x][y].rightWall)
canvas.drawLine((x+1)*cellSize, y*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
}
}

float margin = cellSize/15; // create a small margin to avoid player and exit overlapping squares

canvas.drawRect( // draw the player

player.col*cellSize+margin,
player.row*cellSize+margin,
(player.col+1)*cellSize-margin,
(player.row+1)*cellSize-margin,
playerPaint);


canvas.drawRect( // draw the exit
exit.col*cellSize+margin,
exit.row*cellSize+margin,
(exit.col+1)*cellSize-margin,
(exit.row+1)*cellSize-margin,
exitPaint);

timer--;
}

private void movePlayer (Direction direction) {
switch (direction) {
case UP:
if (!player.topWall)
player = cells[player.col][player.row - 1];
break;
case DOWN:
if (!player.bottomWall)
player = cells[player.col][player.row + 1];
break;
case LEFT:
if (!player.leftWall)
player = cells[player.col - 1][player.row];
break;
case RIGHT:
if (!player.rightWall)
player = cells[player.col + 1][player.row];
break;
}

checkExit();
invalidate();
}

private void checkExit() {

if (player == exit) // check if player square is on the exit square
createMaze();

}

@Override
public boolean onTouchEvent(MotionEvent event) {

if(event.getAction() == MotionEvent.ACTION_DOWN)
return true;

if(event.getAction() == MotionEvent.ACTION_MOVE){

float x = event.getX();
float y = event.getY();

float playerCenterX = hMargin + (player.col + 0.5f)*cellSize;
float playerCenterY = vMargin + (player.row + 0.5f)*cellSize;

float dx = x - playerCenterX;
float dy = y - playerCenterY;

float absDx = Math.abs(dx);
float absDy = Math.abs(dy);

if (absDx > cellSize || absDy > cellSize) {

if (absDx > absDy) {
//move in x direction
if (dx > 0)
movePlayer(Direction.RIGHT);
else
movePlayer(Direction.LEFT);
}
else {
//move in y direction
if (dy > 0)
movePlayer(Direction.DOWN);
else
movePlayer(Direction.UP);
}

}
return true;
}

return super.onTouchEvent(event);
}

private class Cell { // manage the cells in the array/maze
boolean // booleans for the state of surrounding cells, set to true default
topWall = true,
leftWall = true,
bottomWall = true,
rightWall = true,
visited = false;

int col, row;

public Cell(int col, int row) { // constructor to set position
this.col = col;
this.row = row;
}
}

private CountDownTimer mCountDownTimer = new CountDownTimer(10000, 1000) {

public void onTick(long millisUntilFinished) {
timerText.setText(Float.toString(timer));
timer--;
//timerText.setText(Integer.toString(timer));
}

public void onFinish() {
createMaze();
}
};
}








share







New contributor




Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    -2












    $begingroup$


    I have built a small maze game in which you have to navigate to the end before the 10 second timer runs out. The timer works fine and restarts the game if you run out of time, however I have tried numerous methods to update the textview with the timer but all of them cause the app to crash upon starting. Any help would be appreciated, thank you.



    Text View XML:



    <TextView
    android:id="@+id/timerTextView"


    Java File:



    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.view.MotionEvent;
    import android.view.View;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.Random;
    import java.util.Stack;

    public class GameView extends View {

    private enum Direction {
    UP, DOWN, LEFT, RIGHT
    } // enumeration to hold different direction states

    private Cell cells; // 2d array for the maze
    private Cell player, exit; // Cell objects for the player and exit squares
    private static final int COLS = 7, ROWS = 12; // number of columns and rows respectively
    private static final float WALL_THICKNESS = 5; // thickness of maze walls
    private float cellSize, hMargin, vMargin; // cell size and horizontal/vertical margins
    private Paint wallPaint, playerPaint, exitPaint; // paint objects for the walls, player and exit squares
    private Random random; // random number for maze generation algorithm
    private float timer;
    private TextView timerText;


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

    wallPaint = new Paint();
    wallPaint.setColor(Color.BLACK); // set wall colour
    wallPaint.setStrokeWidth(WALL_THICKNESS); // set wall thickness

    playerPaint = new Paint();
    playerPaint.setColor(Color.RED);
    exitPaint = new Paint();
    exitPaint.setColor(Color.BLUE);

    random = new Random(); // initialise new random number

    createMaze();
    }

    private Cell getNeighbour(Cell cell) {

    ArrayList<Cell> neighbours = new ArrayList<>();

    // left neighbour cell
    if (cell.col > 0) // avoid values below 0 causing errors
    if (!cells[cell.col - 1][cell.row].visited)
    neighbours.add(cells[cell.col - 1][cell.row]);

    // right neighbour cell
    if (cell.col < COLS - 1) // only check up to the size of the maze
    if (!cells[cell.col + 1][cell.row].visited)
    neighbours.add(cells[cell.col + 1][cell.row]);

    // top neighbour cell
    if (cell.row > 0) // avoid values below 0 causing errors
    if (!cells[cell.col][cell.row - 1].visited)
    neighbours.add(cells[cell.col][cell.row - 1]);

    // bottom neighbour cell
    if (cell.row < ROWS - 1)
    if (!cells[cell.col][cell.row + 1].visited)
    neighbours.add(cells[cell.col][cell.row + 1]);

    if (neighbours.size() > 0) { // check to make sure the
    int index = random.nextInt(neighbours.size()); // random int based on the size of the array (i.e. only between 1 and 2)
    return neighbours.get(index);
    }
    return null;
    }

    private void removeWall(Cell current, Cell next) {

    // check if below
    if (current.col == next.col && current.row == next.row + 1) {
    current.topWall = false;
    next.bottomWall = false;
    }

    // check if above
    if (current.col == next.col && current.row == next.row - 1) {
    current.bottomWall = false;
    next.topWall = false;
    }

    // check if right
    if (current.col == next.col + 1 && current.row == next.row) {
    current.leftWall = false;
    next.rightWall = false;
    }

    // check if left
    if (current.col == next.col - 1 && current.row == next.row) {
    current.rightWall = false;
    next.leftWall = false;
    }


    }

    private void createMaze() { // initialise maze

    Stack<Cell> stack = new Stack<>(); // create stack for cell objects
    Cell current, next; // current and next position of maze algorithm
    timerText = findViewById(R.id.timerTextView);
    timer = 10;

    cells = new Cell[COLS][ROWS];

    for (int x=0; x<COLS; x++) { // nested for loop to create 2d array of objects for the maze
    for (int y=0; y<ROWS; y++) {
    cells[x][y] = new Cell(x, y);
    }
    }

    player = cells[0][0]; // set start square to top left
    exit = cells[COLS-1][ROWS-1]; // set exit square to bottom right

    current = cells[0][0]; // start with current cell at the first cell in the top left
    current.visited = true;

    do {
    next = getNeighbour(current); // find random available neighbour cell

    if (next != null) { // check to make sure it found a cell
    removeWall(current, next); // remove the wall between the first and second cell
    stack.push(current); // push the current cell to the stack
    current = next; // set new cell to current
    current.visited = true;
    } else // if a cell wasnt found
    current = stack.pop(); // go back a stage, pop a value off the stack
    } while (!stack.empty()); // end loop once the stack is empty


    mCountDownTimer.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.CYAN); // background colour

    int canvasWidth = getWidth(); // get width of canvas
    int canvasHeight = getHeight(); // get height of canvas

    if (canvasWidth / canvasHeight < COLS/ROWS) // using canvas pixel size, calculate the size of the cells
    cellSize = (canvasWidth / (COLS+1)) - 10;
    else
    cellSize = (canvasHeight / (ROWS+1)) - 10;

    hMargin = (canvasWidth - COLS*cellSize)/2; // (width of the canvas - width of the maze)
    vMargin = (canvasHeight - ROWS*cellSize)/1.5f; // (height of the canvas - height of the maze)

    canvas.translate(hMargin, vMargin); // shift the origin (where to start drawing the maze) by the margin size x, y

    for (int x=0; x<COLS; x++) { // nested 'for' loop to create the maze
    for (int y=0; y<ROWS; y++) {
    if (cells[x][y].topWall) // if there is a top wall, draw it
    canvas.drawLine(x*cellSize, y*cellSize, (x+1)*cellSize, y*cellSize, wallPaint);
    if (cells[x][y].leftWall)
    canvas.drawLine(x*cellSize, y*cellSize, x*cellSize, (y+1)*cellSize, wallPaint);
    if (cells[x][y].bottomWall)
    canvas.drawLine(x*cellSize, (y+1)*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
    if (cells[x][y].rightWall)
    canvas.drawLine((x+1)*cellSize, y*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
    }
    }

    float margin = cellSize/15; // create a small margin to avoid player and exit overlapping squares

    canvas.drawRect( // draw the player

    player.col*cellSize+margin,
    player.row*cellSize+margin,
    (player.col+1)*cellSize-margin,
    (player.row+1)*cellSize-margin,
    playerPaint);


    canvas.drawRect( // draw the exit
    exit.col*cellSize+margin,
    exit.row*cellSize+margin,
    (exit.col+1)*cellSize-margin,
    (exit.row+1)*cellSize-margin,
    exitPaint);

    timer--;
    }

    private void movePlayer (Direction direction) {
    switch (direction) {
    case UP:
    if (!player.topWall)
    player = cells[player.col][player.row - 1];
    break;
    case DOWN:
    if (!player.bottomWall)
    player = cells[player.col][player.row + 1];
    break;
    case LEFT:
    if (!player.leftWall)
    player = cells[player.col - 1][player.row];
    break;
    case RIGHT:
    if (!player.rightWall)
    player = cells[player.col + 1][player.row];
    break;
    }

    checkExit();
    invalidate();
    }

    private void checkExit() {

    if (player == exit) // check if player square is on the exit square
    createMaze();

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

    if(event.getAction() == MotionEvent.ACTION_DOWN)
    return true;

    if(event.getAction() == MotionEvent.ACTION_MOVE){

    float x = event.getX();
    float y = event.getY();

    float playerCenterX = hMargin + (player.col + 0.5f)*cellSize;
    float playerCenterY = vMargin + (player.row + 0.5f)*cellSize;

    float dx = x - playerCenterX;
    float dy = y - playerCenterY;

    float absDx = Math.abs(dx);
    float absDy = Math.abs(dy);

    if (absDx > cellSize || absDy > cellSize) {

    if (absDx > absDy) {
    //move in x direction
    if (dx > 0)
    movePlayer(Direction.RIGHT);
    else
    movePlayer(Direction.LEFT);
    }
    else {
    //move in y direction
    if (dy > 0)
    movePlayer(Direction.DOWN);
    else
    movePlayer(Direction.UP);
    }

    }
    return true;
    }

    return super.onTouchEvent(event);
    }

    private class Cell { // manage the cells in the array/maze
    boolean // booleans for the state of surrounding cells, set to true default
    topWall = true,
    leftWall = true,
    bottomWall = true,
    rightWall = true,
    visited = false;

    int col, row;

    public Cell(int col, int row) { // constructor to set position
    this.col = col;
    this.row = row;
    }
    }

    private CountDownTimer mCountDownTimer = new CountDownTimer(10000, 1000) {

    public void onTick(long millisUntilFinished) {
    timerText.setText(Float.toString(timer));
    timer--;
    //timerText.setText(Integer.toString(timer));
    }

    public void onFinish() {
    createMaze();
    }
    };
    }








    share







    New contributor




    Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      -2












      -2








      -2





      $begingroup$


      I have built a small maze game in which you have to navigate to the end before the 10 second timer runs out. The timer works fine and restarts the game if you run out of time, however I have tried numerous methods to update the textview with the timer but all of them cause the app to crash upon starting. Any help would be appreciated, thank you.



      Text View XML:



      <TextView
      android:id="@+id/timerTextView"


      Java File:



      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.view.MotionEvent;
      import android.view.View;
      import android.widget.TextView;
      import java.util.ArrayList;
      import java.util.Random;
      import java.util.Stack;

      public class GameView extends View {

      private enum Direction {
      UP, DOWN, LEFT, RIGHT
      } // enumeration to hold different direction states

      private Cell cells; // 2d array for the maze
      private Cell player, exit; // Cell objects for the player and exit squares
      private static final int COLS = 7, ROWS = 12; // number of columns and rows respectively
      private static final float WALL_THICKNESS = 5; // thickness of maze walls
      private float cellSize, hMargin, vMargin; // cell size and horizontal/vertical margins
      private Paint wallPaint, playerPaint, exitPaint; // paint objects for the walls, player and exit squares
      private Random random; // random number for maze generation algorithm
      private float timer;
      private TextView timerText;


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

      wallPaint = new Paint();
      wallPaint.setColor(Color.BLACK); // set wall colour
      wallPaint.setStrokeWidth(WALL_THICKNESS); // set wall thickness

      playerPaint = new Paint();
      playerPaint.setColor(Color.RED);
      exitPaint = new Paint();
      exitPaint.setColor(Color.BLUE);

      random = new Random(); // initialise new random number

      createMaze();
      }

      private Cell getNeighbour(Cell cell) {

      ArrayList<Cell> neighbours = new ArrayList<>();

      // left neighbour cell
      if (cell.col > 0) // avoid values below 0 causing errors
      if (!cells[cell.col - 1][cell.row].visited)
      neighbours.add(cells[cell.col - 1][cell.row]);

      // right neighbour cell
      if (cell.col < COLS - 1) // only check up to the size of the maze
      if (!cells[cell.col + 1][cell.row].visited)
      neighbours.add(cells[cell.col + 1][cell.row]);

      // top neighbour cell
      if (cell.row > 0) // avoid values below 0 causing errors
      if (!cells[cell.col][cell.row - 1].visited)
      neighbours.add(cells[cell.col][cell.row - 1]);

      // bottom neighbour cell
      if (cell.row < ROWS - 1)
      if (!cells[cell.col][cell.row + 1].visited)
      neighbours.add(cells[cell.col][cell.row + 1]);

      if (neighbours.size() > 0) { // check to make sure the
      int index = random.nextInt(neighbours.size()); // random int based on the size of the array (i.e. only between 1 and 2)
      return neighbours.get(index);
      }
      return null;
      }

      private void removeWall(Cell current, Cell next) {

      // check if below
      if (current.col == next.col && current.row == next.row + 1) {
      current.topWall = false;
      next.bottomWall = false;
      }

      // check if above
      if (current.col == next.col && current.row == next.row - 1) {
      current.bottomWall = false;
      next.topWall = false;
      }

      // check if right
      if (current.col == next.col + 1 && current.row == next.row) {
      current.leftWall = false;
      next.rightWall = false;
      }

      // check if left
      if (current.col == next.col - 1 && current.row == next.row) {
      current.rightWall = false;
      next.leftWall = false;
      }


      }

      private void createMaze() { // initialise maze

      Stack<Cell> stack = new Stack<>(); // create stack for cell objects
      Cell current, next; // current and next position of maze algorithm
      timerText = findViewById(R.id.timerTextView);
      timer = 10;

      cells = new Cell[COLS][ROWS];

      for (int x=0; x<COLS; x++) { // nested for loop to create 2d array of objects for the maze
      for (int y=0; y<ROWS; y++) {
      cells[x][y] = new Cell(x, y);
      }
      }

      player = cells[0][0]; // set start square to top left
      exit = cells[COLS-1][ROWS-1]; // set exit square to bottom right

      current = cells[0][0]; // start with current cell at the first cell in the top left
      current.visited = true;

      do {
      next = getNeighbour(current); // find random available neighbour cell

      if (next != null) { // check to make sure it found a cell
      removeWall(current, next); // remove the wall between the first and second cell
      stack.push(current); // push the current cell to the stack
      current = next; // set new cell to current
      current.visited = true;
      } else // if a cell wasnt found
      current = stack.pop(); // go back a stage, pop a value off the stack
      } while (!stack.empty()); // end loop once the stack is empty


      mCountDownTimer.start();
      }

      @Override
      protected void onDraw(Canvas canvas) {
      canvas.drawColor(Color.CYAN); // background colour

      int canvasWidth = getWidth(); // get width of canvas
      int canvasHeight = getHeight(); // get height of canvas

      if (canvasWidth / canvasHeight < COLS/ROWS) // using canvas pixel size, calculate the size of the cells
      cellSize = (canvasWidth / (COLS+1)) - 10;
      else
      cellSize = (canvasHeight / (ROWS+1)) - 10;

      hMargin = (canvasWidth - COLS*cellSize)/2; // (width of the canvas - width of the maze)
      vMargin = (canvasHeight - ROWS*cellSize)/1.5f; // (height of the canvas - height of the maze)

      canvas.translate(hMargin, vMargin); // shift the origin (where to start drawing the maze) by the margin size x, y

      for (int x=0; x<COLS; x++) { // nested 'for' loop to create the maze
      for (int y=0; y<ROWS; y++) {
      if (cells[x][y].topWall) // if there is a top wall, draw it
      canvas.drawLine(x*cellSize, y*cellSize, (x+1)*cellSize, y*cellSize, wallPaint);
      if (cells[x][y].leftWall)
      canvas.drawLine(x*cellSize, y*cellSize, x*cellSize, (y+1)*cellSize, wallPaint);
      if (cells[x][y].bottomWall)
      canvas.drawLine(x*cellSize, (y+1)*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
      if (cells[x][y].rightWall)
      canvas.drawLine((x+1)*cellSize, y*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
      }
      }

      float margin = cellSize/15; // create a small margin to avoid player and exit overlapping squares

      canvas.drawRect( // draw the player

      player.col*cellSize+margin,
      player.row*cellSize+margin,
      (player.col+1)*cellSize-margin,
      (player.row+1)*cellSize-margin,
      playerPaint);


      canvas.drawRect( // draw the exit
      exit.col*cellSize+margin,
      exit.row*cellSize+margin,
      (exit.col+1)*cellSize-margin,
      (exit.row+1)*cellSize-margin,
      exitPaint);

      timer--;
      }

      private void movePlayer (Direction direction) {
      switch (direction) {
      case UP:
      if (!player.topWall)
      player = cells[player.col][player.row - 1];
      break;
      case DOWN:
      if (!player.bottomWall)
      player = cells[player.col][player.row + 1];
      break;
      case LEFT:
      if (!player.leftWall)
      player = cells[player.col - 1][player.row];
      break;
      case RIGHT:
      if (!player.rightWall)
      player = cells[player.col + 1][player.row];
      break;
      }

      checkExit();
      invalidate();
      }

      private void checkExit() {

      if (player == exit) // check if player square is on the exit square
      createMaze();

      }

      @Override
      public boolean onTouchEvent(MotionEvent event) {

      if(event.getAction() == MotionEvent.ACTION_DOWN)
      return true;

      if(event.getAction() == MotionEvent.ACTION_MOVE){

      float x = event.getX();
      float y = event.getY();

      float playerCenterX = hMargin + (player.col + 0.5f)*cellSize;
      float playerCenterY = vMargin + (player.row + 0.5f)*cellSize;

      float dx = x - playerCenterX;
      float dy = y - playerCenterY;

      float absDx = Math.abs(dx);
      float absDy = Math.abs(dy);

      if (absDx > cellSize || absDy > cellSize) {

      if (absDx > absDy) {
      //move in x direction
      if (dx > 0)
      movePlayer(Direction.RIGHT);
      else
      movePlayer(Direction.LEFT);
      }
      else {
      //move in y direction
      if (dy > 0)
      movePlayer(Direction.DOWN);
      else
      movePlayer(Direction.UP);
      }

      }
      return true;
      }

      return super.onTouchEvent(event);
      }

      private class Cell { // manage the cells in the array/maze
      boolean // booleans for the state of surrounding cells, set to true default
      topWall = true,
      leftWall = true,
      bottomWall = true,
      rightWall = true,
      visited = false;

      int col, row;

      public Cell(int col, int row) { // constructor to set position
      this.col = col;
      this.row = row;
      }
      }

      private CountDownTimer mCountDownTimer = new CountDownTimer(10000, 1000) {

      public void onTick(long millisUntilFinished) {
      timerText.setText(Float.toString(timer));
      timer--;
      //timerText.setText(Integer.toString(timer));
      }

      public void onFinish() {
      createMaze();
      }
      };
      }








      share







      New contributor




      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      I have built a small maze game in which you have to navigate to the end before the 10 second timer runs out. The timer works fine and restarts the game if you run out of time, however I have tried numerous methods to update the textview with the timer but all of them cause the app to crash upon starting. Any help would be appreciated, thank you.



      Text View XML:



      <TextView
      android:id="@+id/timerTextView"


      Java File:



      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.view.MotionEvent;
      import android.view.View;
      import android.widget.TextView;
      import java.util.ArrayList;
      import java.util.Random;
      import java.util.Stack;

      public class GameView extends View {

      private enum Direction {
      UP, DOWN, LEFT, RIGHT
      } // enumeration to hold different direction states

      private Cell cells; // 2d array for the maze
      private Cell player, exit; // Cell objects for the player and exit squares
      private static final int COLS = 7, ROWS = 12; // number of columns and rows respectively
      private static final float WALL_THICKNESS = 5; // thickness of maze walls
      private float cellSize, hMargin, vMargin; // cell size and horizontal/vertical margins
      private Paint wallPaint, playerPaint, exitPaint; // paint objects for the walls, player and exit squares
      private Random random; // random number for maze generation algorithm
      private float timer;
      private TextView timerText;


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

      wallPaint = new Paint();
      wallPaint.setColor(Color.BLACK); // set wall colour
      wallPaint.setStrokeWidth(WALL_THICKNESS); // set wall thickness

      playerPaint = new Paint();
      playerPaint.setColor(Color.RED);
      exitPaint = new Paint();
      exitPaint.setColor(Color.BLUE);

      random = new Random(); // initialise new random number

      createMaze();
      }

      private Cell getNeighbour(Cell cell) {

      ArrayList<Cell> neighbours = new ArrayList<>();

      // left neighbour cell
      if (cell.col > 0) // avoid values below 0 causing errors
      if (!cells[cell.col - 1][cell.row].visited)
      neighbours.add(cells[cell.col - 1][cell.row]);

      // right neighbour cell
      if (cell.col < COLS - 1) // only check up to the size of the maze
      if (!cells[cell.col + 1][cell.row].visited)
      neighbours.add(cells[cell.col + 1][cell.row]);

      // top neighbour cell
      if (cell.row > 0) // avoid values below 0 causing errors
      if (!cells[cell.col][cell.row - 1].visited)
      neighbours.add(cells[cell.col][cell.row - 1]);

      // bottom neighbour cell
      if (cell.row < ROWS - 1)
      if (!cells[cell.col][cell.row + 1].visited)
      neighbours.add(cells[cell.col][cell.row + 1]);

      if (neighbours.size() > 0) { // check to make sure the
      int index = random.nextInt(neighbours.size()); // random int based on the size of the array (i.e. only between 1 and 2)
      return neighbours.get(index);
      }
      return null;
      }

      private void removeWall(Cell current, Cell next) {

      // check if below
      if (current.col == next.col && current.row == next.row + 1) {
      current.topWall = false;
      next.bottomWall = false;
      }

      // check if above
      if (current.col == next.col && current.row == next.row - 1) {
      current.bottomWall = false;
      next.topWall = false;
      }

      // check if right
      if (current.col == next.col + 1 && current.row == next.row) {
      current.leftWall = false;
      next.rightWall = false;
      }

      // check if left
      if (current.col == next.col - 1 && current.row == next.row) {
      current.rightWall = false;
      next.leftWall = false;
      }


      }

      private void createMaze() { // initialise maze

      Stack<Cell> stack = new Stack<>(); // create stack for cell objects
      Cell current, next; // current and next position of maze algorithm
      timerText = findViewById(R.id.timerTextView);
      timer = 10;

      cells = new Cell[COLS][ROWS];

      for (int x=0; x<COLS; x++) { // nested for loop to create 2d array of objects for the maze
      for (int y=0; y<ROWS; y++) {
      cells[x][y] = new Cell(x, y);
      }
      }

      player = cells[0][0]; // set start square to top left
      exit = cells[COLS-1][ROWS-1]; // set exit square to bottom right

      current = cells[0][0]; // start with current cell at the first cell in the top left
      current.visited = true;

      do {
      next = getNeighbour(current); // find random available neighbour cell

      if (next != null) { // check to make sure it found a cell
      removeWall(current, next); // remove the wall between the first and second cell
      stack.push(current); // push the current cell to the stack
      current = next; // set new cell to current
      current.visited = true;
      } else // if a cell wasnt found
      current = stack.pop(); // go back a stage, pop a value off the stack
      } while (!stack.empty()); // end loop once the stack is empty


      mCountDownTimer.start();
      }

      @Override
      protected void onDraw(Canvas canvas) {
      canvas.drawColor(Color.CYAN); // background colour

      int canvasWidth = getWidth(); // get width of canvas
      int canvasHeight = getHeight(); // get height of canvas

      if (canvasWidth / canvasHeight < COLS/ROWS) // using canvas pixel size, calculate the size of the cells
      cellSize = (canvasWidth / (COLS+1)) - 10;
      else
      cellSize = (canvasHeight / (ROWS+1)) - 10;

      hMargin = (canvasWidth - COLS*cellSize)/2; // (width of the canvas - width of the maze)
      vMargin = (canvasHeight - ROWS*cellSize)/1.5f; // (height of the canvas - height of the maze)

      canvas.translate(hMargin, vMargin); // shift the origin (where to start drawing the maze) by the margin size x, y

      for (int x=0; x<COLS; x++) { // nested 'for' loop to create the maze
      for (int y=0; y<ROWS; y++) {
      if (cells[x][y].topWall) // if there is a top wall, draw it
      canvas.drawLine(x*cellSize, y*cellSize, (x+1)*cellSize, y*cellSize, wallPaint);
      if (cells[x][y].leftWall)
      canvas.drawLine(x*cellSize, y*cellSize, x*cellSize, (y+1)*cellSize, wallPaint);
      if (cells[x][y].bottomWall)
      canvas.drawLine(x*cellSize, (y+1)*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
      if (cells[x][y].rightWall)
      canvas.drawLine((x+1)*cellSize, y*cellSize, (x+1)*cellSize, (y+1)*cellSize, wallPaint);
      }
      }

      float margin = cellSize/15; // create a small margin to avoid player and exit overlapping squares

      canvas.drawRect( // draw the player

      player.col*cellSize+margin,
      player.row*cellSize+margin,
      (player.col+1)*cellSize-margin,
      (player.row+1)*cellSize-margin,
      playerPaint);


      canvas.drawRect( // draw the exit
      exit.col*cellSize+margin,
      exit.row*cellSize+margin,
      (exit.col+1)*cellSize-margin,
      (exit.row+1)*cellSize-margin,
      exitPaint);

      timer--;
      }

      private void movePlayer (Direction direction) {
      switch (direction) {
      case UP:
      if (!player.topWall)
      player = cells[player.col][player.row - 1];
      break;
      case DOWN:
      if (!player.bottomWall)
      player = cells[player.col][player.row + 1];
      break;
      case LEFT:
      if (!player.leftWall)
      player = cells[player.col - 1][player.row];
      break;
      case RIGHT:
      if (!player.rightWall)
      player = cells[player.col + 1][player.row];
      break;
      }

      checkExit();
      invalidate();
      }

      private void checkExit() {

      if (player == exit) // check if player square is on the exit square
      createMaze();

      }

      @Override
      public boolean onTouchEvent(MotionEvent event) {

      if(event.getAction() == MotionEvent.ACTION_DOWN)
      return true;

      if(event.getAction() == MotionEvent.ACTION_MOVE){

      float x = event.getX();
      float y = event.getY();

      float playerCenterX = hMargin + (player.col + 0.5f)*cellSize;
      float playerCenterY = vMargin + (player.row + 0.5f)*cellSize;

      float dx = x - playerCenterX;
      float dy = y - playerCenterY;

      float absDx = Math.abs(dx);
      float absDy = Math.abs(dy);

      if (absDx > cellSize || absDy > cellSize) {

      if (absDx > absDy) {
      //move in x direction
      if (dx > 0)
      movePlayer(Direction.RIGHT);
      else
      movePlayer(Direction.LEFT);
      }
      else {
      //move in y direction
      if (dy > 0)
      movePlayer(Direction.DOWN);
      else
      movePlayer(Direction.UP);
      }

      }
      return true;
      }

      return super.onTouchEvent(event);
      }

      private class Cell { // manage the cells in the array/maze
      boolean // booleans for the state of surrounding cells, set to true default
      topWall = true,
      leftWall = true,
      bottomWall = true,
      rightWall = true,
      visited = false;

      int col, row;

      public Cell(int col, int row) { // constructor to set position
      this.col = col;
      this.row = row;
      }
      }

      private CountDownTimer mCountDownTimer = new CountDownTimer(10000, 1000) {

      public void onTick(long millisUntilFinished) {
      timerText.setText(Float.toString(timer));
      timer--;
      //timerText.setText(Integer.toString(timer));
      }

      public void onFinish() {
      createMaze();
      }
      };
      }






      java android timer





      share







      New contributor




      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share







      New contributor




      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share



      share






      New contributor




      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 9 mins ago









      CykapathCykapath

      1




      1




      New contributor




      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Cykapath is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Cykapath is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212192%2fsettext-causing-app-to-crash-upon-starting%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Cykapath is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Cykapath is a new contributor. Be nice, and check out our Code of Conduct.













          Cykapath is a new contributor. Be nice, and check out our Code of Conduct.












          Cykapath is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212192%2fsettext-causing-app-to-crash-upon-starting%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Costa Masnaga

          Fotorealismo

          Sidney Franklin