들어가기 앞서서
개인적으로 Computer Graphics를 공부하는 과정에서 나오는 결과물들을 정리하여 여기에 올린다. Graphics 분야에는 수학, 물리, 정역학, 동역학과 같은 기본학문에 대한 지식이 필요하다. 이러한 학문들은 틈틈히 정리해서 올리도록 하고 여기서는 실질적으로 어떻게 Computer Graphics가 구현되는지를 알아보고자 한다. 어떻게 적분이 적용되며 기하처리를 어떻게 하는지 아주 구체적으로 Code를 보면서 이해해 나갈 것이다.
여기서 쓰이는 Code는 특정 Library 를 이용하지 않기 때문에 어떤 언어를 이용하더라도 상관이 없다. 다만 여기서는 Java를 이용해서 구현했으나 다른 언어가 편한 사람은 곧바로 이식이 가능할 것이다.
먼저 Graphics 를 실습하기 위한 기본적인 틀(Frame)이 필요하다. 틀이라고 하면 언어마다 사용자가 그림을 그릴 수 있게 도와주는 객체, 메서드그리고 그림을 동적으로 만들기 위한 Timer 등이 있다. 우선 창을 띄우기 위한 작업을 시작해보자.
Java에는 하나의 Window 창과 동일한 의미의 JFrame 이 존재한다. 그리고 그 안에서 JPanel이 창 내부에 존재하는 것들을 대표한다. 바로 코드를 보며 이해해보자. 참고로 오늘 실습에는 3개의 Java 파일인 BasicDemo, BasicDisplay, Ball 이 존재한다.
public class BasicDemo {
public static void main(String[] args) {
JFrame frame = new JFrame();
BasicDisplay game = new BasicDisplay();
frame.setSize(500, 500);
frame.add(game);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
여기서 중요한 것은 JFrame이다. frame의 Size를 결정하고 Visibility 를 true로 만듦으로 새로운 창 하나가 띄워진다. 그럼 BasicDisplay를 무엇일까. 이 BasicDisplay가 바로 JPanel이다. 창 내부를 관리하는 객체로 자신이 담당한 공간에 들어오는 객체들을 모두 관리한다. JPanel을 쓰기 위해서는 아래와 같이 JPanel을 상속 받아야 한다.
public class BasicDisplay extends JPanel{
Timer timer;
Ball ball;
public BasicDisplay() {
ball = new Ball(this, 250, 250, 30);
timer = new Timer(30, gameActionListener);
timer.start();
}
public void doAction(){
ball.move();
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
}
ActionListener gameActionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
doAction(); // event (1)
repaint(); // render (2)
}
};
}
여기서 중요한 점은 Timer와 ActionListener 그리고 paint() 메서드다. Timer는 30 밀리세컨드마다 gameActionListener에 구현된 actionPerformed() 메서드를 호출하게 된다. 그리고 actionPerformed() 메서드 내부에는 doAction() 과 repaint() 메서드가 호출되는 것을 볼 수 있는데 doAction()의 경우에는 어떤 사물의 움직임을 적용하거나 힘을 적용시키거나 하는 물리적인 변경 코드가 들어가는데 여기서는 Ball(공)이 move 한다고만 했다. 그리고 repaint() 메서드는 JPanel의 기본적인 paint(Graphics g) 메서드를 다시 호출시키는 역할을 한다. paint() 메서드에서는 실제로 Ball을 그리는 코드가 들어있다. 이 메서드 내부에서 super.paint(Graphics) 메서드를 호출하는 이유는 한번 그림을 그리고 나서 화면에 을 clear 해주기 때문이다.
사실 이 부분이 오늘 내용 중 가장 중요하다. Timer를 사용하는 방법과 그 속에서 그림을 그려내는 방법은 Graphics의 기본 중에 기본이다. 다음의 마지막 코드를 통해 Ball을 보도록 하자.
public class Ball {
private float x, y;
private float v_x, v_y;
private float radius;
private BasicDisplay game;
public Ball(BasicDisplay game, float x, float y, float radius) {
this.game = game;
this.x = x;
this.y = y;
this.radius = radius;
}
public void move(){
// fill out here.
}
public void paint(Graphics2D g2d){
g2d.setColor(Color.BLACK);
g2d.fillOval((int)x, (int)y, (int) radius, (int) radius);
}
}
Ball은 화면에서 실제로 움직이는 물체를 의미한다. 조금 전 JPanel 에서 Timer를 사용해 특정 메서드들을 호출할 때를 잘 살펴보면 Ball이 move() 한다거나 paint() 를 호출하는 것을 볼 수 있다. 여기서 move()는 Ball의 좌표 및 속력을 변경시키고 paint()를 통해 실제로 무엇을 그릴 것인지 결정하게 된다. 이 코드의 move()에서는 아무것도 채워넣지 않았다. 그러므로 이 코드들을 실행시키게 되면 아래와 같이 화면에 동그란 공 하나만 그려지게 될 것이다.
소스 코드가 첨부되어 있으므로 찬찬히 둘러보라.
댓글 없음:
댓글 쓰기