1. lib폴더에 lombok.jar 파일 넣기
2. vscode 확장프로그램 설치
3. 클래스위에 @Getter @Setter 작성
package test.ex08;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class BackgroundPlayerServiece implements Runnable {
// 의존하는 것들-->상태가 필요한 것은 전역변수로 뺌.
private BufferedImage image;
private Player player;
public BackgroundPlayerServiece(Player player) {
this.player = player;
File file = new File("image/backgroundMaPService.png");
try {
image = ImageIO.read(file);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}
}
public void run() {
while (true) {
// 색상 확인
Color leftColor = new Color(image.getRGB(player.getX() - 10, player.getY() + 25));
Color rightColor = new Color(image.getRGB(player.getX() + 50 + 15, player.getY() + 25));
// System.out.println("leftColor : "+leftColor);
// System.out.println("rightColor : "+rightColor);
int bottomColor = image.getRGB(player.getX() + 10, player.getY() + 50 + 5) // -1
+ image.getRGB(player.getX() + 50 - 10, player.getY() + 50 + 5); // -1
// 바닥 충돌 확인
if (bottomColor != -2) {
// System.out.println("바텀 칼러 : "+bottomColor);
System.out.println("바닥에 충돌함");
player.setDown(false);
} else {
if (!player.isUp() && !player.isDown())
player.down();
}
// 벽 충돌확인
if (leftColor.getRed() == 255 && leftColor.getGreen() == 0 && leftColor.getBlue() == 0) {
System.out.println("왼쪽 벽에 충돌함");
player.setLeftWallCrash(true);
player.setLeft(false);
} else if (rightColor.getRed() == 255 && rightColor.getGreen() == 0 && rightColor.getBlue() == 0) {
System.out.println("오른쪽 벽에 충돌함");
player.setRightWallCrash(true);
player.setRight(false);
} else {
player.setLeftWallCrash(false);
player.setRightWallCrash(false);
}
try {
System.out.println("나 이제 쉴꼐");
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 실의 길이
}
package test.ex08;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
// main 스레드를 GUI 프로그램에서는 ui 스레드라고 부른다.
public class BubbleFrame extends JFrame {
private JLabel backgroundMap;
private Player player;
public BubbleFrame() {
initObject();
initSetting();
initListener();
setVisible(true); // while
}
private void initObject() {
backgroundMap = new JLabel(new ImageIcon("image/backgroundMap.png"));
setContentPane(backgroundMap);
player = new Player();
add(player);
}
private void initSetting() {
setSize(1000, 640);
setLayout(null); // absoulte 레이아웃 (자유롭게 그림을 그릴 수 있다)
setLocationRelativeTo(null); // JFrame 가운데 배치하기
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // x버튼으로 창을 끌 때 JVM 같이 종료하기
}
private void initListener() {
addKeyListener(new KeyAdapter() {
// 키보드 클릭 이벤트 핸들러
@Override
public void keyPressed(KeyEvent e) {
// System.out.println(e.getKeyCode());
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// 너 지금 왼쪽 방향 보고 있으면 안되고
// 너 지금 왼쪽에 벽에 부딪히면 안되고
// 위에 것이 둘다 아니면 가게해줄게
if (!player.isLeft() && !player.isLeftWallCrash()) {
player.left();
}
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (!player.isRight() && !player.isRightWallCrash()) {
player.right();
}
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
if (!player.isUp() && !player.isDown()) {
player.up();
}
}
// else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// if (!player.isDown() && !player.isUp()) {
// player.down();
// }
// }
}
// 키보드 해제 이벤트 핸들러
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
player.setLeft(false);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.setRight(false);
}
}
});
}
public static void main(String[] args) {
new BubbleFrame();
}
}
package test.ex08;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Player extends JLabel {
// 위치 상태
private int x;
private int y;
// 플레이어의 방향 상태
private boolean left;
private boolean right;
private boolean up;
private boolean down;
// 플레이어 속도 상태
private final int SPEED = 10; // x축
private final int JUMPSPEED = 4; // y축
// 벽에 충돌한 상태
private boolean leftWallCrash;
private boolean rightWallCrash;
private boolean downWallCrash;
private ImageIcon playerR, playerL;
public Player() {
initObject();
initSetting();
new Thread(new BackgroundPlayerServiece(this)).start();
}
public void initObject() {
playerR = new ImageIcon("image/playerR.png");
playerL = new ImageIcon("image/playerL.png");
}
private void initSetting() {
x = 70;
y = 535;
setIcon(playerR);
setSize(50, 50);
setLocation(x, y);
left = false;
right = false;
up = false;
left = false;
}
public void right() {
System.out.println("right메서드 실행됨");
right = true;
new Thread(() -> {
while (right) {
setIcon(playerR);
x = x + SPEED;
setLocation(x, y);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public void left() {
System.out.println("left메서드 실행됨");
left = true;
new Thread(() -> {
while (left) {
setIcon(playerL);
x = x - SPEED;
setLocation(x, y);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public void up() {
System.out.println("up 메서드 실행됨");
up = true;
new Thread(() -> {
for (int i = 0; i < 35; i++) {
y = y - JUMPSPEED;
setLocation(x, y);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
up = false;
down();
}).start();
}
public void down() {
System.out.println("down 메서드 실행됨");
down = true;
new Thread(() -> {
while (down) {
y = y + JUMPSPEED;
setLocation(x, y);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
down = false;
}).start();
}
}
A-> throws b-> throws -> c throws
run()-> b.run 호출 -> c.run호출 run()
자신을 호출한 메서드에게 예외처리를 맡김
main 에서 몰아서 처리하는 게 효율적인 경우 있음.
일반적으로는 메서드에서 try catch문으로 오류처리.
(Exception 은 모든 예외의 부모격인 존재로 Exeption e 와 같이 처리하면 편하다)