티스토리 뷰
옵저버 패턴
https://luckygg.tistory.com/181\
[Design Pattern] 옵저버 패턴(Observer Pattern) 이야기 #1 (예제 포함)
옵저버 패턴(Observer Pattern) 옵저버 패턴은 관찰자 패턴이라고도 합니다. 일대다 관계를 이루고 있으며, 상태가 업데이트되면 모든 옵저버들에게 정보를 갱신할 수 있도록 하는 것을 의미합니다.
luckygg.tistory.com
main package
Main class
package main;
import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class Main {
public static void main(String[] args) {
new Control().init();
}
}
MyCanvas class
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Random;
import model.Ball;
import model.Fire;
public class MyCanvas extends Canvas {
Ball ball;
Ball enemy;
ArrayList<Fire> fireArr = new ArrayList<>();
MyCrash crashTh = null;
MyThread th = null;
public MyCanvas() {
enemy = new Ball(200, 50, 0, 0, 50, Color.yellow);
enemy.life = 50;
ball = new Ball(100, 100, 3, 3, 50, Color.red);
th = new MyThread();
th.start();
crashTh = new MyCrash();
crashTh.start();
}
boolean isUp = false;
boolean isDown = false;
boolean isLeft = false;
boolean isRight = false;
public void goLeft() {
ball.left();
}
public void goUp() {
ball.up();
}
public void goRight() {
ball.right();
}
public void goDown() {
ball.down();
}
public void addFire() {
Fire fire = new Fire(ball.getPosX() + (ball.getSize() / 2), ball.getPosY() - 5, -7, 6, 13);
synchronized (fireArr) {
fireArr.add(fire);
}
}
Image bufferImage;
Graphics buffg;
@Override
public void paint(Graphics g) {
if (buffg == null) {
bufferImage = createImage(getWidth(), getHeight());
if (bufferImage == null)
System.out.println("생성 실패");
else
buffg = bufferImage.getGraphics();
}
}
@Override
public void update(Graphics g) {
// if (buffg == null) {
// bufferImage = createImage(getWidth(), getHeight());
// if (bufferImage == null)
// System.out.println("생성 실패");
// else
// buffg = bufferImage.getGraphics();
// }
buffg.drawImage(bufferImage, 0, 0, this); // 버퍼 세팅
/** 배경을 그려서 이전 화면을 덮음 **/
buffg.setColor(Color.blue);
buffg.fillRect(0, 0, getWidth(), getHeight());
// 내 캐릭터
buffg.setColor(ball.getColor());
buffg.fillOval(ball.getPosX(), ball.getPosY(), ball.getSize(), ball.getSize());
// 총알
buffg.setColor(Color.white);
synchronized (fireArr) {
for (int i = 0; i < fireArr.size(); i++) {
Fire temp = fireArr.get(i);
buffg.fillRect(temp.getPosX(), temp.getPosY(), temp.getWidth(), temp.getHeight());
}
}
// 적군
buffg.setColor(enemy.getColor());
// if(enemy.life < 20) {
// buffg.setColor(Color.white);
// }else if(enemy.life < 30) {
// buffg.setColor(Color.red);
// }else if(enemy.life < 40) {
// buffg.setColor(Color.black);
// }
buffg.fillRect(enemy.getPosX(), enemy.getPosY(), enemy.getSize(), enemy.getSize());
// for (int i = 0; i < ballArr.size(); i++) {
// Ball ball = ballArr.get(i);
// buffg.setColor(ball.getColor());
// buffg.fillOval(ball.getPosX(), ball.getPosY(), ball.getSize(), ball.getSize());
// }
g.drawImage(bufferImage, 0, 0, this); // 버퍼에 있는 것 그려주기
}
class MyCrash extends Thread {
@Override
public void run() {
while (true) {
synchronized (fireArr) {
for (int i = 0; i < fireArr.size(); i++) {
Rectangle enRec = new Rectangle(enemy.getPosX(), enemy.getPosY(), enemy.getSize(),
enemy.getSize());
Fire fire = fireArr.get(i);
Rectangle fireRec = new Rectangle(fire.getPosX(), fire.getPosY(), fire.getWidth(),
fire.getHeight());
if (enRec.intersects(fireRec)) {
// 충돌
fireArr.remove(i);
i--;
enemy.life --;
if(enemy.life <1 ) {
enemy.setPosX(-1000);
}
}
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class MyThread extends Thread {
@Override
public void run() {
while (true) {
if (isDown) {
ball.down();
}
if (isUp && ball.getPosY() > 0) {
ball.up();
}
if (isLeft) {
ball.left();
}
if (isRight) {
ball.right();
}
// 총알 이동
synchronized (fireArr) {
for (int i = 0; i < fireArr.size(); i++) {
Fire temp = fireArr.get(i);
temp.move();
if (temp.getPosY() < -20) {
fireArr.remove(i);
i--;
}
}
}
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Control class
package main;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class Control {
public void init() {
Frame frame = new Frame("첫 번째 AWT");
setLayout(frame);
frame.setLayout(null);
TextField tf = new TextField(10);
tf.setSize(100, 60);
tf.setLocation(100, 30);
frame.add(tf);
MyCanvas can = new MyCanvas();
can.setSize(500, 400);
can.setLocation(100, 100);
can.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case 37:
can.isLeft = false;
break;
case 38:
can.isUp = false;
break;
case 39:
can.isRight = false;
break;
case 40:
can.isDown = false;
break;
}
}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case 32:
can.addFire();
break;
case 37:
// can.goLeft();
can.isLeft = true;
break;
case 38:
// can.goUp();
can.isUp = true;
break;
case 39:
can.isRight = true;
// can.goRight();
break;
case 40:
can.isDown = true;
// can.goDown();
break;
}
}
});
frame.add(can);
frame.setVisible(true); // 보여주기
}
private void setLayout(Frame frame) {
int width = 700;
int height = 600;
Dimension scr = Toolkit.getDefaultToolkit().getScreenSize();
// System.out.println(scr.width + " : "+scr.height); //모니터 해상도
int posX = scr.width / 2 - (width / 2);
int posY = scr.height / 2 - (height / 2);
frame.setLocation(1920 + posX, posY); // 프레임 위치
frame.setSize(width, height); // 프레임 크기
frame.setResizable(false); // 프레임 크기 조정 가능여부
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
});
}
}
model package
ball class
package model;
import java.awt.Color;
public class Ball {
private int posX;
private int posY;
private int speedX;
private int speedY;
private int size;
private Color color;
public int life;
public Ball(int posX, int posY, int speedX, int speedY, int size, Color color) {
this.posX = posX;
this.posY = posY;
this.speedX = speedX;
this.speedY = speedY;
this.size = size;
this.color = color;
}
public void down() {
posY += speedY;
}
public void up() {
posY -= speedY;
}
public void right() {
posX += speedX;
}
public void left() {
posX -= speedX;
}
public void move() {
posX += speedX;
posY += speedY;
}
public void setPosX(int posX) {
this.posX = posX;
}
public void setPosY(int posY) {
this.posY = posY;
}
public int getSpeedX() {
return speedX;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public int getSpeedY() {
return speedY;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public int getPosX() {
return posX;
}
public int getPosY() {
return posY;
}
public int getSize() {
return size;
}
public Color getColor() {
return color;
}
}
fire class
package model;
public class Fire {
private int posX;
private int posY;
private int speedY;
private int width;
private int height;
public Fire(int posX, int posY, int speedY, int width, int height) {
this.posX = posX;
this.posY = posY;
this.speedY = speedY;
this.width = width;
this.height = height;
}
public void move() {
posY += speedY;
}
public int getPosY() {
return posY;
}
public void setPosY(int posY) {
this.posY = posY;
}
public int getPosX() {
return posX;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
'TEMP' 카테고리의 다른 글
비전공자 취준 넋두리 & 관련 링크 모음 (0) | 2021.03.01 |
---|---|
EX_단어장 팝업(커스텀 다이얼로그)/ 화면전환(intent) (0) | 2020.09.21 |
캔버스에 색 넣기(Canvas 상속) (0) | 2020.09.03 |
Sep1_멀티스레드에서 우선순위 지정(flag 개념) (0) | 2020.09.01 |
Sep1_멀티쓰레드 (0) | 2020.09.01 |
댓글