티스토리 뷰

옵저버 패턴

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;
	}
	
	
	
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함