/*
import acm.graphics.;
import acm.program.;
import acm.util.*;
import java.applet.;
import java.awt.;
import java.awt.event.*;
import java.util.*;
import java.util.ArrayList;
public class Breakout extends GraphicsProgram {
// game setting
/* Width and height of application window in pixels /
public static final int APPLICATION_WIDTH = 400;
public static final int APPLICATION_HEIGHT = 600;
/* Dimensions of game board (usually the same) /
private static final int WIDTH = APPLICATION_WIDTH;
private static final int HEIGHT = APPLICATION_HEIGHT;
// paddle information
/* Dimensions of the paddle /
private static final int PADDLE_WIDTH = 60;
private static final int PADDLE_HEIGHT = 10;
/* Offset of the paddle up from the bottom /
private static final int PADDLE_Y_OFFSET = 30;
// bricks information
/* Number of bricks per row /
private static final int NBRICKS_PER_ROW = 10; // 하나의 행에서 brick 갯수
/* Number of rows of bricks /
private static final int NBRICK_ROWS = 10; // 열 갯수
/* Separation between bricks /
private static final int BRICK_SEP = 4;
/* Width of a brick /
private static final int BRICK_WIDTH =
(WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW;
/* Height of a brick /
private static final int BRICK_HEIGHT = 8;
// ball information
/* Radius of the ball in pixels /
private static final int BALL_RADIUS = 10;
/* Offset of the top brick row from the top /
private static final int BRICK_Y_OFFSET = 70;
/* Number of turns /
private static final int NTURNS = 3;
/*Ball velocity/
private double vx, vy;
/*Random number generator for vx/
private RandomGenerator rgen = new RandomGenerator();
/* Animation delay or pause time between ball moves /
private static final double DELAY = 10;
/* 벽돌이랑 충돌 횟수 /
private int BRICKCOUNT = NBRICKS_PER_ROWNBRICK_ROWS ; // 벽돌의 갯수(열행)
/* 게임 점수 /
private int game_Score = 0;
/ Method: run() /
/* Runs the Breakout program. /
public void run() {
for (int tries=0 ; tries < NTURNS; tries++) {
setUpGame();
playGame();
if ( BRICKCOUNT == 0 ) {
ball.setVisible(false);
messageWinner();
break;
}
}
if( BRICKCOUNT > 0) {
messageGameOver();
}
}
private void setUpGame() {
setUpBricks();
createPaddle();
createBall();
drawScoreBox();
}
private void setUpBricks() {
ArrayList<Color> colors = new ArrayList<>(Arrays.asList(Color.RED,Color.ORANGE,Color.YELLOW,Color.GREEN,Color.CYAN));
for (int i=0; i < NBRICK_ROWS;i++) {
double rowStartX = 0;
double rowStartY = BRICK_Y_OFFSET + BRICK_SEP*i + BRICK_HEIGHT*i;
// 몫을 통해 colorNumber를 설정
int colorNumber = i / 2;
// 행표시
for (int j=0; j < NBRICKS_PER_ROW;j++) {
// rowStartX를 벽돌의 개수의 개수만큼 옆으로 이동
double x = rowStartX + BRICK_WIDTH*j + BRICK_SEP*j;
GRect rect = new GRect(x,rowStartY,BRICK_WIDTH,BRICK_HEIGHT);
rect.setFilled(true);
rect.setColor(colors.get(colorNumber));
add(rect);
}
}
}
private GRect paddle;
private void createPaddle() {
double x = getWidth()/2 - PADDLE_WIDTH/2; // paddle이 화면 중앙에 위치하도록 한다.
double y = getHeight() - PADDLE_Y_OFFSET - PADDLE_HEIGHT; //
paddle = new GRect (x, y, PADDLE_WIDTH, PADDLE_HEIGHT);
paddle.setFilled(true);
add (paddle);
addMouseListeners();
}
public void mouseMoved(MouseEvent e) {
if ((e.getX() < getWidth() - PADDLE_WIDTH/2) && (e.getX() > PADDLE_WIDTH/2)) { // 마우스의 위치가 화면 내에 있는 경우
paddle.setLocation(e.getX() - PADDLE_WIDTH/2, getHeight() - PADDLE_Y_OFFSET - PADDLE_HEIGHT ); // paddle은 마우스의 x좌표를 따라가고, y좌표는 유지된다.
}
}
/** 공만들기 */
private GOval ball;
private void createBall() {
double x = getWidth()/2 - BALL_RADIUS;
double y = getHeight()/2 - BALL_RADIUS;
ball = new GOval(x, y, BALL_RADIUS, BALL_RADIUS);
ball.setFilled(true);
add(ball);
}
private void playGame(){
waitForClick();
getBallVelocity();
while (true){
moveBall();
if (ball.getY() >= getHeight() - BALL_RADIUS*2) {
messageDead();
waitForClick();
removeAll();
game_Score = 0;
break;
}
if (BRICKCOUNT == 0) {
break;
}
}
}
private void getBallVelocity(){
vx = rgen.nextDouble(1.0, 3.0);
if(rgen. nextBoolean(0.5)) {
vx = -vx;
}
vy = 3.0; // 임의의 위치에서 공이 떨어지도록 하였다.
}
AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");
private void moveBall() {
ball.move(vx, vy);
if (ball.getX() <= 0 || ball.getX() >= (getWidth() - BALL_RADIUS*2)) { // 공이 왼쪽 벽에 닿거나 오른쪽 벽에 닿으면 속도가 반대가 된다.
vx = -vx;
}
if (ball.getY() <= 0 || ball.getY() >= (getHeight() - BALL_RADIUS*2)) { //공이 천장에 닿으면 y의 속도가 반대가 된다.
vy = -vy;
}
GObject collider = getCollidingObject();
if (collider == paddle) { // paddle 이랑 충돌하면
if(ball.getY() >= getHeight() - PADDLE_Y_OFFSET - PADDLE_HEIGHT - BALL_RADIUS*2 && ball.getY() < getHeight() - PADDLE_Y_OFFSET - PADDLE_HEIGHT - BALL_RADIUS*2 + 3) { //paddle 에 공이 닿으면 y의 속도가 반대가 된다.
vy = -1.2*vy; // 속도가 조금씩 빨라지도록 설정한다.
vx = 1.2*vx;
}
} else if (collider != null) { // 충돌하면
remove(collider); // 충돌한 brick를 제거한다.
bounceClip.play(); // 충돌하면 소리가 난다.
BRICKCOUNT--;
game_Score++;
removeScore();
vy = - vy; // 그리고 나서 y의 속도를 바꾼다.
}
pause(DELAY);
}
private GObject getCollidingObject() {
if((getElementAt(ball.getX(), ball.getY())) != null) { // 왼쪽상단에 충돌이 일어나면
return getElementAt(ball.getX(), ball.getY()); // 왼쪽상단 좌표 값을 반환한다.
}
else if (getElementAt( (ball.getX() + BALL_RADIUS*2), ball.getY() ) != null ){ // 왼쪽하단에 충돌이 일어나면
return getElementAt(ball.getX() + BALL_RADIUS*2, ball.getY()); // 왼쪽하단 좌표 값을 반환한다.
}
else if(getElementAt(ball.getX(), (ball.getY() + BALL_RADIUS*2)) != null ){ // 오른쪽상단에 충돌이 일어나면
return getElementAt(ball.getX(), ball.getY() + BALL_RADIUS*2); // 오른쪽상단 좌표 값을 반환한다.
}
else if(getElementAt((ball.getX() + BALL_RADIUS*2), (ball.getY() + BALL_RADIUS*2)) != null ){ // 오른쪽하단에 충돌이 일어나면
return getElementAt(ball.getX() + BALL_RADIUS*2, ball.getY() + BALL_RADIUS*2); // 오른쪽하단 좌표 값을 반환한다.
}
else{
return null; // 충돌이 없으면 null을 반환한다.
}
}
private void messageGameOver() {
GLabel gameOver = new GLabel("Game Over", getWidth()/2, getHeight()/2);
gameOver.move(-gameOver.getWidth()/2, -gameOver.getHeight());
gameOver.setColor(Color.RED);
add (gameOver);
}
private void messageWinner() {
GLabel Winner = new GLabel (" Winner!! ^_____^ ", getWidth()/2, getHeight()/2);
Winner.move(-Winner.getWidth()/2, -Winner.getHeight());
Winner.setColor(Color.RED);
add (Winner);
}
private void messageDead() {
GLabel Dead = new GLabel ("Dead!! ㅡ_ㅡ;; Try Again", getWidth()/2, getHeight()/2);
Dead.move(-Dead.getWidth()/2, -Dead.getHeight());
Dead.setColor(Color.RED);
add (Dead);
}
// 점수 상자의 크기 지정하기
private static final int Width = 80;
private static final int Height = 20;
private void drawScoreBox() { // 점수 상자 그리기
int x = getWidth() - 100; // 상자의 x위치는 정중앙에서 상자의 너비의 반만큼 왼쪽으로 간 곳에서 시작한다.
int y = getHeight() - PADDLE_Y_OFFSET - PADDLE_HEIGHT +13 ; // 상자의 y위치는 정중앙에서 상자의 높이의 반만큼 위로 간 곳에서 시작한다.
GLabel score = new GLabel("SCORE : " + game_Score, x, y);
add(score);
double boxCenterX = Width/2;
double boxCenterY = Height/2;
double halfScoreBoxWidth = score.getWidth()/2;
double halfScoreBoxHeight = score.getAscent()/2; //finds the center of the height for "program"
score.move( (boxCenterX - halfScoreBoxWidth) , (boxCenterY + halfScoreBoxHeight) );
}
}