반응형
package site.metacoding.mytest;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
*
* @author 정재원
*
*
*/
// main을 가진 클래스는 해당 프로그램의 컨텍스트(문맥)를 다 알고 있다.
public class BubbleFrame extends JFrame {
private static final String TAG = "BubbleFrame : ";
private BubbleFrame context = this;
private JLabel backgroundMap; // JLabel로 사진 붙이기
private Player player;
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
public BubbleFrame() {
initObject();
initSetting();
initListener();
initService();
setVisible(true); // 내부에 paintComponent() 호출 코드가 있다.
}
// 각종 모든 세팅
private void initSetting() {
setSize(1000, 640);
setLayout(null); // JFrame의 기본 JPanel의 레이아웃을 AbsoulteLayout으로 설정
setLocationRelativeTo(null); // JFrame 화면 가운데 배치
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // x버튼 클릭시 JVM 같이 종료
}
// new 하는 곳
private void initObject() {
backgroundMap = new JLabel(new ImageIcon("image/backgroundMap.png"));
setContentPane(backgroundMap); // 백그라운드 화면 설정
player = new Player(context); // 플레이어 생성
add(player); // Frame에 플레이어 붙이기
}
private void initListener() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
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_SPACE) {
player.attack();
}
}
@Override
public void keyReleased(KeyEvent e) {
// System.out.println(TAG + "키보드 릴리즈");
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// isLeft를 false로
player.setLeft(false);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// isRight를 false로
player.setRight(false);
}
}
});
}
// backgroundMapService 독립적인 스레드
private void initService() {
new Thread(new BackgroundMapService(player)).start();
}
public static void main(String[] args) {
new BubbleFrame();
}
}
package site.metacoding.mytest;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
/**
*
* @author 정재원 플레이어는 좌우이동이 가능하다. 점프가 가능하다. 방울을 발사한다.
*
*/
public class Player extends JLabel {
private static final String TAG = "Player : ";
private BubbleFrame context;
private static final int SPEED = 4;
private static final int JUMPSPEED = 2;
// 위치 상태
private int x, y;
private ImageIcon playerR, playerL;
// 움직임 상태
private boolean isLeft, isRight, isUp, isDown;
// 충돌 상태
private boolean leftWallCrash, rightWallCrash;
// 방향 상태
private int direction; // -1 왼쪽 0 상태x 1 오른쪽
// X
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
// Y
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
// isLeft
public boolean isLeft() {
return isLeft;
}
public void setLeft(boolean isLeft) {
this.isLeft = isLeft;
}
// isRight
public boolean isRight() {
return isRight;
}
public void setRight(boolean isRight) {
this.isRight = isRight;
}
// isUp
public boolean isUp() {
return isUp;
}
public void setUp(boolean isUp) {
this.isUp = isUp;
}
// isDown
public boolean isDown() {
return isDown;
}
public void setDown(boolean isDown) {
this.isDown = isDown;
}
// leftWallCrash
public boolean isLeftWallCrash() {
return leftWallCrash;
}
public void setLeftWallCrash(boolean leftWallCrash) {
this.leftWallCrash = leftWallCrash;
}
// rightWallCrash
public boolean isRightWallCrash() {
return rightWallCrash;
}
public void setRightWallCrash(boolean rightWallCrash) {
this.rightWallCrash = rightWallCrash;
}
// direction
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
// 생성자
public Player(BubbleFrame context) {
this.context = context;
initObject();
initSetting();
}
private void initSetting() {
// 플레이어 좌표 설정
x = 90;
y = 535;
// default 사진 설정
setIcon(playerR);
setSize(50, 50);
// 플레이어 그림 그리기 paintComponent 호출
setLocation(x, y);
isLeft = false;
isRight = false;
isUp = false;
isDown = false;
leftWallCrash = false;
rightWallCrash = false;
direction = 1;
}
private void initObject() {
playerR = new ImageIcon("image/playerR.png");
playerL = new ImageIcon("image/playerL.png");
}
public void left() {
System.out.println(TAG + "왼쪽");
isLeft = true;
setRightWallCrash(false);
direction = -1;
setIcon(playerL);
new Thread(() -> {
while (isLeft) {
x = x - SPEED;
setLocation(x, y);
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void right() {
System.out.println(TAG + "오른쪽");
isRight = true;
setLeftWallCrash(false);
direction = 1;
setIcon(playerR);
new Thread(() -> {
while (isRight) {
x = x + SPEED;
setLocation(x, y);
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void up() {
System.out.println(TAG + "위쪽");
isUp = true;
new Thread(() -> {
// up
for (int i = 0; i < 130 / JUMPSPEED; i++) {
y = y - JUMPSPEED;
setLocation(x, y);
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
isUp = false;
down();
}).start();
}
public void down() {
System.out.println(TAG + "아래쪽");
isDown = true;
new Thread(() -> {
// down
while (isDown) {
y = y + JUMPSPEED;
setLocation(x, y);
try {
Thread.sleep(3);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void attack() {
System.out.println(TAG + "공격!");
Bubble bubble = new Bubble(context); // JLabel
context.add(bubble);
new Thread(new BackgroundBubbleService(bubble)).start();
}
}
package site.metacoding.mytest;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
// 백그라운드 서비스 (독립적인 스레드로 돌려야 한다)
public class BackgroundMapService implements Runnable {
private static final String TAG = "BackgroundMapService : ";
// 컴포지션
private Player player;
private BufferedImage image;
// 컴포지션을 위한 기술 -> 의존성 주입 (생성자를 통해서 주입) = DI (Dependency Injection)
public BackgroundMapService(Player player) {
this.player = player;
try {
image = ImageIO.read(new File("image/backgroundMapService.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
// 멈추지 않고 while을 돌며 색상 확인
while (true) {
try {
Color leftColor = new Color(image.getRGB(player.getX() - 10, player.getY() + 25));
Color rightColor = new Color(image.getRGB(player.getX() + 50 + 10, player.getY() + 25));
// System.out.println(TAG + "leftColor : " + leftColor);
// System.out.println(TAG + "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
// System.out.println(TAG + bottomColor);
if (bottomColor != -2) { // 바닥에 장애물이 있다!
// System.out.println(TAG + "바닥에 밟히는게 있네");
player.setDown(false); // 그만 떨어져
} else { // 바닥이 흰색
if (!player.isDown() && !player.isUp()) {
// System.out.println(TAG + "바닥에 아무것도 없어!!");
player.down();
}
}
if (leftColor.getRed() == 255 && leftColor.getGreen() == 0 && leftColor.getBlue() == 0) { // 왼쪽벽이 빨간색이면
System.out.println(TAG + "왼쪽 벽에 부딪혔다!");
player.setLeftWallCrash(true);
player.setLeft(false);
} else if (rightColor.getRed() == 255 && rightColor.getGreen() == 0 && rightColor.getBlue() == 0) {
System.out.println(TAG + "오른쪽 벽에 부딪혔다!");
player.setRightWallCrash(true);
player.setRight(false);
}
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
package site.metacoding.mytest;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class Bubble extends JLabel {
private static final String TAG = "Bubble : ";
private static final int BUBBLESPEED = 1;
private BubbleFrame context;
private Player player;
private int x, y;
private ImageIcon bubble, bomb;
private boolean isLeft, isRight, isUp, topWallCrash, leftWallCrash, rightWallCrash;
// isLeft
public boolean isLeft() {
return isLeft;
}
public void setLeft(boolean isLeft) {
this.isLeft = isLeft;
}
// isRight
public boolean isRight() {
return isRight;
}
public void setRight(boolean isRight) {
this.isRight = isRight;
}
// isUp
public boolean isUp() {
return isUp;
}
public void setUp(boolean isUp) {
this.isUp = isUp;
}
// topWallCrash
public boolean isTopWallCrash() {
return topWallCrash;
}
public void setTopWallCrash(boolean topWallCrash) {
this.topWallCrash = topWallCrash;
}
// leftWallCrash
public boolean isLeftWallCrash() {
return leftWallCrash;
}
public void setLeftWallCrash(boolean leftWallCrash) {
this.leftWallCrash = leftWallCrash;
}
// rightWallCrash
public boolean isRightWallCrash() {
return rightWallCrash;
}
public void setRightWallCrash(boolean rightWallCrash) {
this.rightWallCrash = rightWallCrash;
}
// bubble은 player의 위치에 의존해야한다.
// player에만 의존하면 적군을 만들 때 문제가 발생함
// 따라서 context에 의존!
public Bubble(BubbleFrame context) {
this.context = context;
this.player = context.getPlayer();
isLeft = false;
isRight = false;
isUp = false;
topWallCrash = false;
leftWallCrash = false;
rightWallCrash = false;
initObject();
initSetting();
// 방향체크
if (player.getDirection() == -1) {
left();
} else if (player.getDirection() == 1) {
right();
}
}
private void initObject() {
bubble = new ImageIcon("image/bubble.png");
bomb = new ImageIcon("image/bomb.png");
}
private void initSetting() {
x = player.getX();
y = player.getY();
setIcon(bubble);
setSize(50, 50);
setLocation(x, y);
}
public void left() {
isLeft = true;
new Thread(() -> {
try {
for (int i = 0; i < 400; i++) {
x = x - BUBBLESPEED;
setLocation(x, y);
Thread.sleep(1);
if (leftWallCrash == true) {
up();
break;
} else if (i == 399) {
up();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
public void right() {
new Thread(() -> {
try {
for (int i = 0; i < 400; i++) {
x = x + BUBBLESPEED;
setLocation(x, y);
Thread.sleep(1);
if (rightWallCrash == true) {
up();
break;
} else if (i == 399) {
up();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
public void up() {
isUp = true;
try {
while (isUp) {
y = y - BUBBLESPEED;
setLocation(x, y);
Thread.sleep(1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void pop() {
// 천장에 붙고 4초뒤에 사진변경, repaint
// setTopWallCrash가 트루면
new Thread(() -> {
try {
Thread.sleep(4000);
if (topWallCrash == true) {
setIcon(bomb);
setLocation(x, y);
Thread.sleep(1000);
context.remove(this);
context.repaint();
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
package site.metacoding.mytest;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
// 백그라운드 서비스 (독립적인 스레드로 돌려야 한다)
public class BackgroundBubbleService implements Runnable {
private static final String TAG = "BackgroundBubbleService : ";
private Bubble bubble;
private BufferedImage image;
public BackgroundBubbleService(Bubble bubble) {
this.bubble = bubble;
try {
image = ImageIO.read(new File("image/backgroundMapService.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
// 멈추지 않고 while을 돌며 색상 확인
while (true) {
try {
Color leftColor = new Color(image.getRGB(bubble.getX() - 10, bubble.getY() + 25));
Color rightColor = new Color(image.getRGB(bubble.getX() + 50 + 10, bubble.getY() + 25));
int topColor = image.getRGB(bubble.getX() + 25, bubble.getY() - 5);
// System.out.println(TAG + topColor);
if (topColor == -65536) { // 버블이 천장에 닿았어!
// System.out.println(TAG + "머리 부딪혔어");
bubble.setUp(false); // 그만 올라가
bubble.setTopWallCrash(true);
bubble.pop();
}
if (leftColor.getRed() == 255 && leftColor.getGreen() == 0 && leftColor.getBlue() == 0) { // 왼쪽벽이 빨간색이면
// System.out.println(TAG + "왼쪽 벽에 부딪혔다!");
bubble.setLeftWallCrash(true);
bubble.setLeft(false);
} else if (rightColor.getRed() == 255 && rightColor.getGreen() == 0 && rightColor.getBlue() == 0) {
// System.out.println(TAG + "오른쪽 벽에 부딪혔다!");
bubble.setRightWallCrash(true);
bubble.setRight(false);
}
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
반응형