160 likes | 310 Views
Java. The Art and Science of. An Introduction. to Computer Science. ERIC S. ROBERTS. C H A P T E R 1 1. Arrays and ArrayLists. Little boxes, on a hillside, little boxes made of ticky-tacky Little boxes, little boxes, little boxes, all the same
E N D
Java The Art and Science of An Introduction to Computer Science ERIC S. ROBERTS C H A P T E R 1 1 Arrays and ArrayLists Little boxes, on a hillside, little boxes made of ticky-tacky Little boxes, little boxes, little boxes, all the same There’s a green one and a pink one and a blue one and a yellow one And they're all made out of ticky-tacky and they all look just the same —Malvina Reynolds, “Little Boxes,” 1962 Chapter 11—Arrays and ArrayLists Lecture Slides, Part III CS101 @ Özyeğin University Slides are adapted from the originals available at http://www-cs-faculty.stanford.edu/~eroberts/books/ArtAndScienceOfJava/
Example: SimpleSnake • In this problem we will implement a simple version of the snake game in which a snake bounces from the walls of the screen.
SimpleSnake • Each part of the snake body will have a size of BODY_PART_WIDTH. • There are SNAKE_LENGTH many body parts. • Each body part is a GOval object. All the body parts are kept in a GOval array. • Corresponding to each body part, we keep the velocity in the x direction and in the y direction. • Food for thought: Why don’t we keep a single velocity value? privateGOval[] snakeBody = newGOval[SNAKE_LENGTH]; privatedouble[] xVelocities = newdouble[SNAKE_LENGTH]; privatedouble[] yVelocities = newdouble[SNAKE_LENGTH];
SimpleSnake publicvoid run() { initializeSnakeBody(); initializeVelocities(); while(true) { moveSnake(); checkBounds(); pause(20); } }
SimpleSnake(initializing body parts) BODY_PART_WIDTH BODY_PART_WIDTH BODY_PART_WIDTH / sqrt(2)
publicvoid initializeSnakeBody() { int xCenter = getWidth() / 2; int yCenter = getHeight() / 2; for(int i = 0; i < snakeBody.length; i++) { snakeBody[i] = createSnakeBodyPartCenteredAt(xCenter, yCenter); xCenter -= (BODY_PART_WIDTH/Math.sqrt(2)); yCenter -= (BODY_PART_WIDTH/Math.sqrt(2)); add(snakeBody[i]); } } public GOval createSnakeBodyPartCenteredAt(int xCenter, int yCenter) { GOval circle = new GOval(xCenter - BODY_PART_WIDTH/2, yCenter - BODY_PART_WIDTH/2, BODY_PART_WIDTH, BODY_PART_WIDTH); circle.setFilled(true); circle.setFillColor(Color.BLUE); return circle; } SimpleSnake
publicvoid initializeVelocities() { for(int i = 0; i < xVelocities.length; i++) { xVelocities[i] = 3; } for(int i = 0; i < yVelocities.length; i++) { yVelocities[i] = 3; } } publicvoid moveSnake() { for(int i = 0; i < snakeBody.length; i++) { snakeBody[i].move(xVelocities[i], yVelocities[i]); } } publicvoid checkBounds() { for(int i = 0; i < snakeBody.length; i++) { double x = snakeBody[i].getX(); double y = snakeBody[i].getY(); if(x < 0 || x > getWidth() - BODY_PART_WIDTH) { xVelocities[i] *= -1; } if(y < 0 || y > getHeight() - BODY_PART_WIDTH) { yVelocities[i] *= -1; } } } SimpleSnake
SimpleSnake v.2 • In this problem we will implement yet another simple version of the snake game. • P.S. You may need to click on the window to request focus so that key events will be captured.
SimpleSnake v.2 • In this version, there is a single, constant SPEED value. The head of the snake has a direction, which can be one of NORTH, EAST, SOUTH, WEST. • After each move, a body part replaces the part in the front. snake direction
SimpleSnake v.2 • In this version, there is a single, constant SPEED value. The head of the snake has a direction, which can be one of NORTH, EAST, SOUTH, WEST. • After each move, a body part replaces the part in the front. snake direction
SimpleSnake v.2 • Moving the snake parts: • Each part element gets the location of the element in front of it. • Head element is moved according to its direction. 0 1 2 3 4 5 6 7
publicclass SimpleSnakeV2 extends GraphicsProgram { privatefinalintBODY_PART_WIDTH = 20; privatefinalintSNAKE_LENGTH = 12; privatefinalintSPEED = BODY_PART_WIDTH; private GOval[] snakeBody = new GOval[SNAKE_LENGTH]; privatefinalintNORTH = 1; privatefinalintEAST = 2; privatefinalintSOUTH = 3; privatefinalintWEST = 4; // Direction of the head is one of {N, W, S, E} privateintdirection = EAST; // Cont’d on the next slide // . . . SimpleSnake
publicvoid run() { addGrid(); initializeSnakeBody(); while(true) { moveSnake(); pause(200); } } publicvoid addGrid() { for(int i = 0; i < getWidth(); i += BODY_PART_WIDTH) { add(new GLine(i, 0, i, getHeight())); } for(int i = 0; i < getHeight(); i += BODY_PART_WIDTH) { add(new GLine(0, i, getWidth(), i)); } }
publicvoidinitializeSnakeBody() { int x = SNAKE_LENGTH * BODY_PART_WIDTH; int y = getHeight() / 2; for(inti = 0; i < snakeBody.length; i++) { snakeBody[i] = createSnakeBodyAt(x, y); x -= BODY_PART_WIDTH; add(snakeBody[i]); } } publicGOvalcreateSnakeBodyAt(int x, int y) { GOvalcircle = newGOval(x, y, BODY_PART_WIDTH, BODY_PART_WIDTH); circle.setFilled(true); circle.setFillColor(Color.BLUE); returncircle; }
publicvoid moveSnake() { // Each body part replaces the one in front of it for(int i = snakeBody.length - 1; i >= 1; i--) { GOval prevPart = snakeBody[i-1]; snakeBody[i].setLocation(prevPart.getX(), prevPart.getY()); } // Move the head if(direction == EAST) { snakeBody[0].move(SPEED, 0); } elseif(direction == WEST) { snakeBody[0].move(-SPEED, 0); } elseif(direction == NORTH) { snakeBody[0].move(0, -SPEED); } elseif(direction == SOUTH) { snakeBody[0].move(0, SPEED); } }
// The method below is invoked whenever the user presses a key // You do not need to spend too much time understanding this part publicvoid keyPressed(KeyEvent keyEvent) { // VK_UP: key code for up arrow key // VK_RIGHT: key code for right arrow key // VK_DOWN: key code for down arrow key // VK_LEFT: key code for left arrow key if(keyEvent.getKeyCode() == KeyEvent.VK_UP) { direction = NORTH; } elseif(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) { direction = EAST; } elseif(keyEvent.getKeyCode() == KeyEvent.VK_DOWN) { direction = SOUTH; } elseif(keyEvent.getKeyCode() == KeyEvent.VK_LEFT) { direction = WEST; } } publicvoid init() { setSize(600, 400); addKeyListeners(); // required for key interaction } }