setText causing app to crash upon starting
$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();
}
};
}
java android timer
New contributor
$endgroup$
add a comment |
$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();
}
};
}
java android timer
New contributor
$endgroup$
add a comment |
$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();
}
};
}
java android timer
New contributor
$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
java android timer
New contributor
New contributor
New contributor
asked 12 mins ago
CykapathCykapath
1
1
New contributor
New contributor
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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.
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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