Presentation is loading. Please wait.

Presentation is loading. Please wait.

게임 API 프로그래밍 Lecture #12. 강의 목차 ▶ 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해 한다. ▶ 주요 게임 API 의 종류와 기본 사용법을 익힌다. ▶ 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다. 2Mobile Programming.

Similar presentations


Presentation on theme: "게임 API 프로그래밍 Lecture #12. 강의 목차 ▶ 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해 한다. ▶ 주요 게임 API 의 종류와 기본 사용법을 익힌다. ▶ 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다. 2Mobile Programming."— Presentation transcript:

1 게임 API 프로그래밍 Lecture #12

2 강의 목차 ▶ 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해 한다. ▶ 주요 게임 API 의 종류와 기본 사용법을 익힌다. ▶ 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다. 2Mobile Programming

3 게임 API 개요 ▶ 게임 API 클래스 3Mobile Programming

4 GameCanvas 클래스 (1) ▶ GameCanvas 클래스 개요 ▷ 게임용 사용자 인터페이스 제공 ▷ 주요 제공 기능 Canvas( 명령, 입력 이벤트 등 ) 에서 상속된 기능 off-screen 그래픽 버퍼 기능 – 깜박임 현상 예방 키 상태 쿼리 기능 4Mobile Programming

5 GameCanvas 클래스 (2) ▶ GameCanvas 클래스 생성자 ▷ suppressKeyEvents 일반 키 이벤트 기법의 억제 여부 결정 ▷ suppressKeyEvents=true 일 때 정의된 게임 키 (UP, DOWN, LEFT, RIGHT, FIRE, 1, 3, 7, 9) –keyPressed, keyRepeated, keyReleased 메소드 호출 안함 – 시스템이 이벤트 처리 – 성능 향상 ▷ suppressKeyEvents=false 일 때 게임 키에 일반 키 이벤트 기법을 적용 5Mobile Programming GameCanvas(boolean suppressKeyEvents)

6 GameCanvas 클래스 (3) ▶ GameCanvas 클래스 메소드 6Mobile Programming

7 GameCanvas 클래스 (4) ▶ flushGraphics() 메소드 ▶ getGraphics() 메소드 ▶ getKeyStates() 메소드 ▶ paint() 메소드 7Mobile Programming flushGraphics(int x, int y, int width, int height) getGraphics( ) getKeyStates( ) paint(Graphics g)

8 GameCanvas 클래스 (5) ▶ 볼 애니메이션 프로그램 8Mobile Programming 상하 좌우 방향 키 클릭 (a) 초기 화면 (b) 시작 후 화면

9 GameCanvas 클래스 (6) 9Mobile Programming 01 import javax.microedition.midlet.*; 02 import javax.microedition.lcdui.*; 03 04 public class MyCanvasMIDlet extends MIDlet implements CommandListener { 05 private Display display; 06 private MyCanvas canvas; 07 private Command exit_cmd; 08 public MyCanvasMIDlet() { 09 exit_cmd = new Command("Exit", Command.EXIT, 1); 10 display = Display.getDisplay(this); 11 canvas = new MyCanvas(); 12 canvas.addCommand(exit_cmd); 13 canvas.setCommandListener(this); 14 } [ 예제 10-1] MyCanvasMIDlet.java

10 GameCanvas 클래스 (7) 10Mobile Programming 15 public void startApp() { 16 display.setCurrent(canvas); 17 } 18 public void pauseApp() { } 19 public void destroyApp(boolean unconditional) { 20 if(canvas != null) { 21 canvas.stop(); 22 } 23 } 24 public void commandAction(Command cmd, Displayable disp) { 25 if(cmd == exit_cmd){ 26 destroyApp(true); 27 notifyDestroyed(); 28 } 29 } 30 } [ 예제 10-1] MyCanvasMIDlet.java

11 GameCanvas 클래스 (8) 11Mobile Programming 01 import javax.microedition.lcdui.*; 02 03 class MyCanvas extends Canvas implements Runnable { 04 public static final int BALL_SIZE = 20; 05 private int ball_x; 06 private int ball_y; 07 private int move_x; 08 private int move_y; 09 private boolean running; 10 11 public MyCanvas(){ 12 ball_x = getWidth()/2; 13 ball_y = getHeight()/2; 14 move_x = 0; 15 move_y = 0; 16 running = true; 17 Thread t = new Thread(this); 18 t.start(); 19 } [ 예제 10-2] MyCanvas.java

12 GameCanvas 클래스 (9) 12Mobile Programming 20 public void run(){ 21 while(running) { 22 bound_check(); 23 repaint(); 24 try { 25 Thread.sleep(200); 26 } catch(InterruptedException e) { 27 stop(); 28 } 29 } 30 } 31 public void paint(Graphics g) { 32 g.setColor(255, 255, 255); 33 g.drawRect(0, 0, getWidth(), getHeight()); 34 g.setColor(0, 255, 0); 35 ball_x += move_x; 36 ball_y += move_y; 37 g.fillArc(ball_x, ball_y, BALL_SIZE, BALL_SIZE, 0, 360); 38 } [ 예제 10-2] MyCanvas.java

13 GameCanvas 클래스 (10) 13Mobile Programming 39 public void keyPressed(int keycode) { 40 switch(getGameAction(keycode)) { 41 case LEFT: 42 move_x = -10; 43 move_y = 0; 44 break; 45 case RIGHT: 46 move_x = 10; 47 move_y = 0; 48 break; 49 case UP: 50 move_x = 0; 51 move_y = -10; 52 break; 53 case DOWN: 54 move_x = 0; 55 move_y = 10; 56 break; 57 default: 58 } 59 } [ 예제 10-2] MyCanvas.java

14 GameCanvas 클래스 (11) 14Mobile Programming 60 private void bound_check() { 61 if(ball_x > getWidth()){ 62 ball_x = getWidth(); 63 } else if (ball_x < 0){ 64 ball_x = 0; 65 } 66 if(ball_y > getHeight()){ 67 ball_y = getHeight(); 68 } else if (ball_y < 0){ 69 ball_y = 0; 70 } 71 } 72 public void stop() { 73 running = false; 74 } 75 } [ 예제 10-2] MyCanvas.java

15 GameCanvas 클래스 (12) 15Mobile Programming 01 import javax.microedition.lcdui.*; 02 import javax.microedition.lcdui.game.*; 03 04 class MyGameCanvas extends GameCanvas implements Runnable { 05 public static final int BALL_SIZE = 20; 06 private int ball_x; 07 private int ball_y; 08 private int move_x; 09 private int move_y; 10 private boolean running; 11 public MyGameCanvas() { 12 super(true); 13 ball_x = getWidth()/2; 14 ball_y = getHeight()/2; 15 move_x = 0; 16 move_y = 0; 17 running = true; 18 Thread t = new Thread(this); 19 t.start(); 20 } [ 예제 10-3] MyGameCanvas.java

16 GameCanvas 클래스 (13) 16Mobile Programming 21 public void run() { 22 Graphics g = getGraphics(); 23 while(running) { 24 bound_check(); 25 g.setColor(255, 255, 255); 26 g.drawRect(0, 0, getWidth(), getHeight()); 27 g.setColor(0, 255, 0); 28 ball_x += move_x; 29 ball_y += move_y; 30 g.fillArc(ball_x, ball_y, BALL_SIZE, BALL_SIZE, 0, 360); 31 flushGraphics(); 32 int keyStates = getKeyStates(); 33 if((keyStates & LEFT_PRESSED)!= 0) { 34 move_x = -10; 35 move_y = 0; 36 } else if((keyStates & RIGHT_PRESSED) != 0) { 37 move_x = 10; 38 move_y = 0; 39 } else if((keyStates & UP_PRESSED) != 0) { 40 move_x = 0; 41 move_y = -10; 42 } else if((keyStates & DOWN_PRESSED) != 0) { 43 move_x = 0; 44 move_y = 10; 45 } [ 예제 10-3] MyGameCanvas.java

17 GameCanvas 클래스 (14) 17Mobile Programming 46 try { 47 Thread.sleep(200); 48 } catch(InterruptedException e) { 49 stop(); 50 } 51 } 52 } 53 private void bound_check() { 54 if(ball_x > getWidth()) { 55 ball_x = 0; 56 } else if (ball_x < 0) { 57 ball_x = getWidth(); 58 } 59 if(ball_y > getHeight()) { 60 ball_y = 0; 61 } else if(ball_y < 0){ 62 ball_y = getHeight(); 63 } 64 } 65 public void stop() { 66 running = false; 67 } 68 } [ 예제 10-3] MyGameCanvas.java

18 GameCanvas 클래스 (15) ▶ MyCanvas 클래스와 MyGameCanvas 클래스의 차이 18Mobile Programming MyCanvasMyGameCanvas import 패키지 02 행 : game 패키지 import 상속 03 행 : Canvas 클래스 04 행 : GameCanvas 클래스 상위 클래스 생성자 호출 12 행 : super(true); 스레드 생성동일 run( ) 메소드 22 행 : Graphics 객체 생성 Graphics g = getGraphics(); while 반복문 23 행 : repaint(); 25~30 행 : [ 예제 10-1] 에서 정의된 paint() 메소드를 따로 정의 하지 않고, while 문에서 off-screen 버퍼에 렌더링 31 행 : flushGraphics(); off-screen 버퍼의 내용을 화면에 출력하려고 GameCanvas 클래스에 정의된 flushGraphics() 메소드 호출 keyPressed() 메소드 대신 32 행에 있는 게임 키의 현재 상태 정보를 가져오려고 GameCanvas 클래스에 정의된 getKeyStates(); 메소드를 호출. 33~45 행의 게임 키 상태에 따 른 처리 부분을 정의. 버튼의 상태를 주기적으로 확인하여 갱 신된 내용을 처리 paint( ) 메소드 31~38 행 : paint() 메소드 정의 paint() 메소드는 repaint() 메소드를 호 출하면 JVM 이 실행 게임 키 이벤트 처리 게임 키 이벤트 처리 39~59 행 : keyPressed() 메소드 정의 게임 키 버튼을 눌렀을 때 실행된다.

19 GameCanvas 클래스 (16) ▶ MyCanvas 클래스와 MyGameCanvas 클래스 비교 19Mobile Programming Thread Graphics( ); ► flushGraphics( ); getKeyStates( ); Thread.sleep Graphics( ); ► flushGraphics( ); getKeyStates( ); Thread.sleep While 문 paint( ) keyPressed( ) Thread repaint( ); Thread.sleep repaint( ); Thread.sleep While 문

20 Layer 클래스 (1) ▶ Layer ▷ 여러 이미지가 하나로 결합 ▶ Layer 로 이미지를 중첩한 화면 예 20Mobile Programming

21 Layer 클래스 (2) ▶ Layer 클래스 ▷ 각 레이어의 위치, 너비, 높이, 표시 여부를 선택할 수 있는 메소드 제 공 21Mobile Programming

22 LayerManager 클래스 (1) ▶ LayerManager 클래스 ▷ 그래픽 레이어 관리 ▷ 레이어를 추가, 삽입, 삭제, 유지, 관리하는 메소드 제공 ▷ 레이어 순서 Z 축을 기준으로 추가 (Append) 할 때마다 0 부터 1 씩 증가 0 은 사용자에게 가장 가까운 레이어 숫자가 높을수록 멀어진다. ▶ 레이어 2 인 sky.png 를 레이어 0 으로 만드는 경우 ▷ hany.png, background_tiles 이미지 화면에 보이지 않음 ▷ 하늘 이미지만 화면에 나타남 22Mobile Programming

23 LayerManager 클래스 (2) ▶ 보기창 ▷ 화면에 표시될 영역의 크기 ▷ 좌표계 위치 조정 ▷ setViewWindow() 메소드 화면에 출력되는 영역과 크기 설정 23Mobile Programming setViewWindow(int x, int y, int width, int height) x : LayerManager 의 원점에서 상대적인 보기 창의 수평 위치 y : LayerManager 의 원점에서 상대적인 보기 창의 수직 위치 width : 보기 창의 넓이 height : 보기 창의 높이

24 LayerManager 클래스 (3) ▶ 보기창 g : getGraphics() 메소드로 얻은 Graphics 객체 x : Graphics 의 변환 원점에서 상대적인 보기 창을 렌더링할 수평 위치 y : Graphics 의 변환 원점에서 상대적인 보기 창을 렌더링할 수직 위치 24Mobile Programming paint(Graphics g, int x, int y)

25 LayerManager 클래스 (4) 25Mobile Programming 01 import java.io.IOException; 02 import javax.microedition.lcdui.*; 03 import javax.microedition.lcdui.game.*; 04 05 class LayerManagerTest extends GameCanvas implements Runnable { 06 private LayerManager layer_manager; 07 private TiledLayer bg_img; 08 public LayerManagerTest() throws IOException { 09 super(true); 10 layer_manager.new LayerManager(); 11 layer_manager.setViewWindow(96, 0, w, h); 12 createBackground("/background_tiles.png"); 13 Thread t = new Thread(this); 14 t.start(); 15 } 16 private void createBackground(String background_img_file) throws IOException { 17 Image background = Image.createImage(background_img_file); 18 int[] map = { 19 0, 0, 0, 0, 0, 8, 0, 0, 20 1, 2, 0, 0, 8, 0, 0, 0, 21 3, 3, 2, 0, 0, 0, 5, 0, 22 3, 3, 3, 2, 4, 1, 3, 2, 23 6, 6, 6, 6, 6, 6, 6, 6, 24 6, 6, 6, 6, 6, 6, 6, 6 25 }; [ 예제 10-4] LayerManagerTest.java

26 LayerManager 클래스 (5) 26Mobile Programming 26 bg_img = new TiledLayer(8, 6, background, 48, 48); 27 bg_img.setPosition(0, 0); 28 for(int i = 0; i < map.length; i++) { 29 int column = i % 8; 30 int row = (i - column) / 8; 31 bg_img.setCell(column, row, map[i]); 32 } 33 layer_manager.append(bg_img); 34 } 35 public void run() { 36 int w = getWidth(); 37 int h = getHeight(); 38 Graphics g = getGraphics(); 39 while (true) { 40 g.setColor(0xffffff); 41 g.fillRect(0, 0, w, h); 42 layer_manager.paint(g, 20, 20); 43 flushGraphics(); 44 try { 45 Thread.sleep(80); } 46 catch(InterruptedException ie) { } 47 } 48 } 49 } [ 예제 10-4] LayerManagerTest.java

27 LayerManager 클래스 (6) ▶ 레이어 순서 ▷ Z 축을 기준으로 0 부터 순차적으로 증가 ▶ 색인 값이 가장 높은 레이어 ▷ 사용자에게서 가장 멀리 있는 레이어 ▶ 색인이 0 인 레이어 ▷ 사용자에게서 가장 가까이 위치 27Mobile Programming Layer 0 Layer 1 Layer 2 Y축Y축 X축X축 Z축Z축

28 LayerManager 클래스 (7) ▶ append() 메소드 I : 추가되는 Layer ▶ insert() 메소드 I : 삽입되는 Layer index : 새 Layer 가 삽입되는 위치 ▶ remove() 메소드 I : 제거되는 Layer 28Mobile Programming public void append(Layer I) public void insert(Layer I, int index) public void remove(Layer I)

29 LayerManager 클래스 (7) ▶ append() 메소드를 이용하여 레이어를 추가하는 방법 ▷ 예제 10-5 참조 ▷ 실행 결과 29Mobile Programming

30 LayerManager 클래스 (8) 30Mobile Programming 01 import java.io.IOException; 02 import javax.microedition.lcdui.*; 03 import javax.microedition.lcdui.game.*; 04 class LayerManagerAppend extends GameCanvas implements Runnable { 05 private LayerManager layer_manager; 06 private TiledLayer sky_img; 07 private TiledLayer bg_img; 08 private int ani_idx; 09 private Sprite hany_img; 10 public LayerManagerAppend() throws IOException { 11 super(true); 12 layer_manager = new LayerManager(); 13 int w = getWidth(); 14 int h = getHeight(); 15 layer_manager.setViewWindow(96, 0, w, h); 16 createHany("/hanys.png"); 17 createBackground("/background_tiles.png"); 18 createSky("/sky.png"); 19 Thread t = new Thread(this); 20 t.start(); 21 } [ 예제 10-5] LayerManagerAppend.java

31 LayerManager 클래스 (9) 31Mobile Programming 22 private void createHany(String hany_img_file) throws IOException { 23 Image hany = Image.createImage(hany_img_file); 24 hany_img = new Sprite(hany, 48, 48); 25 hany_img.setPosition(96 + (getWidth() - 48) / 2, 197); 26 layer_manager.append(hany_img); 27 } 28 private void createBackground(String background_img_file) throws IOException { 29 Image background = Image.createImage(background_img_file); 30 int[] map = { 31 0, 0, 0, 0, 0, 0, 0, 0, 32 1, 2, 0, 0, 0, 0, 0, 0, 33 3, 3, 2, 0, 0, 0, 5, 0, 34 3, 3, 3, 2, 4, 1, 3, 2, 35 6, 6, 6, 6, 6, 6, 6, 6, 36 6, 6, 6, 6, 6, 6, 6, 6 37 }; 38 bg_img = new TiledLayer(8, 6, background, 48, 48); 39 bg_img.setPosition(0, 0); 40 for (int i = 0; i < map.length; i++) { 41 int column = i % 8; 42 int row = (i - column) / 8; 43 bg_img.setCell(column, row, map[i]); 44 } [ 예제 10-5] LayerManagerAppend.java

32 LayerManager 클래스 (10) 32Mobile Programming 45 ani_idx = bg_img.createAnimatedTile(8); 46 bg_img.setCell(4, 1, ani_idx); 47 bg_img.setCell(5, 0, ani_idx); 48 layer_manager.append(bg_img); 49 } 50 private void createSky(String sky_img_file) throws IOException { 51 Image sky = Image.createImage(sky_img_file); 52 sky_img = new TiledLayer(1, 1, sky, 53 sky.getWidth(), sky.getHeight()); 54 sky_img.fillCells(0, 0, 1, 1, 1); 55 sky_img.setPosition(0, 0); 56 layer_manager.append(sky_img); 57 } 58 public void run() { 59 int w = getWidth(); 60 int h = getHeight(); 61 Graphics g = getGraphics(); 62 while (true) { 63 g.setColor(0xffffff); 64 g.fillRect(0, 0, w, h); 65 layer_manager.paint(g, 0, 0); 66 flushGraphics(); 67 try { 68 Thread.sleep(80); 69 } catch (InterruptedException ie) {} 70 } 71 } 72 } [ 예제 10-5] LayerManagerAppend.java

33 Sprite 클래스 (1) ▶ Sprite 클래스 ▷ 하나의 이미지로 저장된 여러 프레임을 같은 크기의 프레임으로 분리 하여 애니메이션 효과를 제공 ▷ setFrame(), setPosition() 등의 메소드 이용 ▷ 주요 기능 애니메이션 회전 / 대칭 충돌 체크 ▶ Sprite 클래스 생성자 33Mobile Programming

34 Sprite 클래스 (2) ▶ Sprite 클래스 메소드 34Mobile Programming

35 Sprite 클래스 (3) ▶ 애니메이션 적용하기 ▷ 프레임 여러 개로 구성된 하나의 이미지 파일 ▶ 예제 10-6 참조 35Mobile Programming

36 Sprite 클래스 (4) 36Mobile Programming 01 import javax.microedition.lcdui.*; 02 import javax.microedition.lcdui.game.*; 03 import java.io.IOException; 04 class SpriteSkiingCanvas extends GameCanvas implements Runnable { 05 private Sprite skiing; 06 private Image skiing_img; 07 private int skiing_img_idx; 08 private boolean running; 09 public SpriteSkiingCanvas() { 10 super(true); 11 try { 12 skiing_img = Image.createImage("/animation.png"); 13 } catch (IOException e){ 14 System.out.println("We can't read Image file"); 15 } 16 skiing = new Sprite(skiing_img, 66, 54); 17 running = true; 18 skiing_img_idx = 0; 19 Thread t = new Thread(this); 20 t.start(); 21 } [ 예제 10-6] SpriteSkiingCanvas.java

37 Sprite 클래스 (5) 37Mobile Programming 22 public void run(){ 23 Graphics g = getGraphics(); 24 while(running) { 25 play_skiing(); 26 draw_skiing(g); 27 try { 28 Thread.sleep(200); 29 } catch(InterruptedException e) { 30 stop(); 31 } 32 } 33 } 34 private void play_skiing() { 35 skiing_img_idx = (skiing_img_idx + 1) % 10; 36 skiing.setFrame(skiing_img_idx); 37 skiing.setPosition(getWidth()/2, getHeight()/2); 38 } 39 private void draw_skiing(Graphics g) { 40 skiing.paint(g); 41 flushGraphics(); 42 } 43 public void stop() { 44 running = false; 45 } 46 } [ 예제 10-6] SpriteSkiingCanvas.java

38 Sprite 클래스 (6) ▶ 객체 회전시키기 ▷ Sprite 클래스 객체를 회전, 대칭시키는 메소드 제공 –setTransform(transform) 90 도의 배수로 회전 또는 대칭 변환 가능 ▷ setTransform(transform) 에 적용할 수 있는 변환 종류 38Mobile Programming

39 Sprite 클래스 (7) ▶ Sprite 변환 예 ▶ 예제 10-7 참조 39Mobile Programming

40 Sprite 클래스 (8) 40Mobile Programming 01 import javax.microedition.lcdui.*; 02 import javax.microedition.lcdui.game.*; 03 import java.io.IOException; 04 05 class SpriteTransCanvas extends GameCanvas implements Runnable { 06 private Sprite hany; 07 String trans_info = ""; 08 private Image hany_img; 09 private boolean running; 10 int array_idx =0; 11 int mirror_idx =0; 12 private static final int [] transformArray = { 13 Sprite.TRANS_NONE, 14 Sprite.TRANS_ROT90, 15 Sprite.TRANS_ROT180, 16 Sprite.TRANS_ROT270 17 }; 18 private static final int [] transMirrorArray = { 19 Sprite.TRANS_MIRROR, 20 Sprite.TRANS_MIRROR_ROT90, 21 Sprite.TRANS_MIRROR_ROT180, 22 Sprite.TRANS_MIRROR_ROT270 23 }; [ 예제 10-7] SpriteTransCanvas.java

41 Sprite 클래스 (9) 41Mobile Programming 24 String transForm[] = new String[]{"Sprite.TRANS_NONE", 25 "Sprite.TRANS_ROT90", 26 "Sprite.TRANS_ROT180", 27 "Sprite.TRANS_ROT270"}; 28 String transMirror[] = new String[]{"Sprite.TRANS_MIRROR", 29 "Sprite.TRANS_MIRROR_ROT90", 30 "Sprite.TRANS_MIRROR_ROT180", 31 "Sprite.TRANS_MIRROR_ROT270"}; 32 public SpriteTransCanvas() { 33 super(true); 34 try { 35 hany_img = Image.createImage("/hany.png"); 36 } catch (IOException e){ 37 System.out.println("We can't read Image file"); 38 } 39 hany = new Sprite(hany_img, 33, 40); 40 running = true; 41 play_hany(); 42 Thread t = new Thread(this); 43 t.start(); 44} [ 예제 10-7] SpriteTransCanvas.java

42 Sprite 클래스 (10) 42Mobile Programming 45 public void run() { 46 Graphics g = getGraphics(); 47 while(running) { 48 int keyStates = getKeyStates(); 49 if((keyStates & LEFT_PRESSED)!= 0) { 50 array_idx++; 51 array_idx = array_idx%4; 52 hany.setTransform(transformArray[array_idx]); 53 trans_info = transForm[array_idx]; 54 } else if((keyStates & RIGHT_PRESSED) != 0) { 55 if(array_idx == 0 ) array_idx = 3; 56 else array_idx--; 57 array_idx = array_idx%4; 58 hany.setTransform(transformArray[array_idx]); 59 trans_info = transForm[array_idx]; 60 } else if((keyStates & UP_PRESSED) != 0) { 61 mirror_idx++; 62 mirror_idx = mirror_idx%4; 63 hany.setTransform(transMirrorArray[mirror_idx]); 64 trans_info = transMirror[mirror_idx]; 65 } else if((keyStates & DOWN_PRESSED) != 0) { 66 if(mirror_idx == 0) mirror_idx = 3; 67 else mirror_idx--; 68 mirror_idx = mirror_idx %4; 69 hany.setTransform(transMirrorArray[mirror_idx]); [ 예제 10-7] SpriteTransCanvas.java

43 Sprite 클래스 (11) 43Mobile Programming 70 trans_info = transMirror[mirror_idx]; 71 } 72 draw_hany(g); 73 try { 74 Thread.sleep(200); 75 } catch(InterruptedException e) { 76 stop(); 77 } 78 } 79 } 80 private void play_hany() { 81 hany.setTransform(Sprite.TRANS_NONE); 82 hany.setPosition(getWidth()/2, getHeight()/2); 83 } 84 private void draw_hany(Graphics g) { 85 g.setColor(255, 255, 255); 86 g.fillRect(0, 0, getWidth(), getHeight()); 87 g.setColor(0, 0, 0); 88 g.drawString(trans_info, 70, 200, Graphics.TOP | Graphics.LEFT); 89 hany.paint(g); 90 flushGraphics(); 91 } 92 public void stop(){ 93 running = false; 94 } 95 } [ 예제 10-7] SpriteTransCanvas.java

44 Sprite 클래스 (12) ▶ 충돌 체크하기 ▷ 충돌 체크 방법 직사각형 교차 충돌 픽셀 수준 충돌 44Mobile Programming

45 Sprite 클래스 (13) ▶ 충돌 체크 관련 메소드 45Mobile Programming

46 Sprite 클래스 (14) ▶ 충돌 체크 관련 메소드 x : 변환되지 않은 Sprite 의 좌측 모서리에서 충돌 직사각형의 수평 위치 y : 변환되지 않은 Sprite 의 상단 모서리에서 충돌 직사각형의 수직 위치 width : 충돌 직사각형의 너비 height : 충돌 직사각형의 높이 image : 충돌을 체크할 Image x : Image 좌측 상단 모서리의 수평 위치 y : Image 좌측 상단 모서리의 수직 위치 pixelLevel : 픽셀 단위로 충돌을 체크하려면 true, 단순한 경계 검사를 사 용하여 체크하려면 false 를 지정 반환 값 : Sprite 가 Image 와 충돌하면 true, 그렇지 않으면 false 를 반환 46Mobile Programming public void defineCollisionRectangle(int x, int y, int width, int height) public final boolean collidesWith(Image image, int x, int y, boolean pixelLevel)

47 Sprite 클래스 (15) ▶ 충돌 체크 관련 메소드 s : 충돌을 체크할 Sprite pixelLevel : 픽셀 단위로 충돌을 체크하려면 true, 간단한 경계 검사를 체 크하려면 false 를 정의 반환 값 : 두 Sprite 가 충돌하면 true, 그렇지 않으면 false 를 반환 t : 충돌을 체크할 TiledLayer pixelLevel : 픽셀 단위로 충돌을 체크하려면 true, 비어 있지 않은 셀의 간 단한 경계를 체크하려면 false 를 정의 반환 값 : 이 Sprite 가 TiledLayer 와 충돌하면 true, 그렇지 않으면 false 를 반환 47Mobile Programming public final boolean collidesWith(Sprite s, boolean pixelLevel) public final boolean collidesWith(TiledLayer t, boolean pixelLevel)

48 Sprite 클래스 (16) ▶ 충돌 체크 프로그램 48Mobile Programming

49 Sprite 클래스 (17) 49Mobile Programming 01 import javax.microedition.lcdui.*; 02 import javax.microedition.lcdui.game.*; 03 import java.io.IOException; 04 05 class SpriteCollisionCanvas extends GameCanvas implements Runnable { 06 private MySprite rocket; 07 private MySprite stone; 08 private Image rocket_img; 09 private Image stone_img; 10 private int img_idx; 11 private boolean running; 12 private final int MOVEING_SIZE = 5; 13 private LayerManager layerManager; 14 15 private boolean colliding = false; 16 17 public SpriteCollisionCanvas() { 18 super(true); 19 layerManager = new LayerManager(); 20 try { 21 rocket_img = Image.createImage("/rocket.png"); 22 stone_img = Image.createImage("/stone.png"); [ 예제 10-8] SpriteCollisionCanvas.java

50 Sprite 클래스 (18) 50Mobile Programming 23 } catch (IOException e){ 24 System.out.println("We can't read Image file"); 25 } 26 rocket = new MySprite(rocket_img, 32, 32, getWidth(), getHeight()); 27 layerManager.append(rocket); 28 stone = new MySprite(stone_img, 24, 24, getWidth(), getHeight()); 29 layerManager.append(stone); 30 } 31 public void start() { 32 rocket.setRefPixelPosition(getWidth()/2, getHeight()/2); 33 stone.setRefPixelPosition(getWidth()/2, getHeight()/2); 34 rocket.setDirection(0, -MOVEING_SIZE); 35 running = true; 36 img_idx = 0; 37 Thread t = new Thread(this); 38 t.start(); 39 } 40 public void stop() { 41 running = false; 42 } 43 public void run() { 44 Graphics g = getGraphics(); [ 예제 10-8] SpriteCollisionCanvas.java

51 Sprite 클래스 (19) 51Mobile Programming 45 while(running) { 46 tick(); 47 keyEvent(getKeyStates()); 48 draw_rocket(g); 49 try { 50 Thread.sleep(200); 51 } catch(InterruptedException e) { 52 stop(); 53 } 54 } 55 } 56 private void tick() { 57 img_idx = (img_idx + 1) % 4; 58 rocket.setFrame(img_idx); 59 rocket.move(); 60 colliding = false; 61 if(rocket.collidesWith(stone, true)) { 62 colliding = true; 63 } 64 } 65 private void keyEvent(int keyStates) { 66 if((keyStates & LEFT_PRESSED)!= 0) { 67 rocket.setDirection(-MOVEING_SIZE, 0); 68 rocket.setTransform(Sprite.TRANS_ROT270); [ 예제 10-8] SpriteCollisionCanvas.java

52 Sprite 클래스 (20) 52Mobile Programming 69 } else if((keyStates & RIGHT_PRESSED) != 0) { 70 rocket.setDirection(MOVEING_SIZE, 0); 71 rocket.setTransform(Sprite.TRANS_ROT90); 72 } else if((keyStates & UP_PRESSED) != 0) { 73 rocket.setDirection(0, -MOVEING_SIZE); 74 rocket.setTransform(Sprite.TRANS_NONE); 75 } else if((keyStates & DOWN_PRESSED) != 0) { 76 rocket.setDirection(0, MOVEING_SIZE); 77 rocket.setTransform(Sprite.TRANS_ROT180); 78 } 79 } 80 private void draw_rocket(Graphics g) { 81 if(colliding) { 82 g.setColor(0, 0, 255); 83 } else { 84 g.setColor(255, 255, 255); 85 } 86 g.fillRect(0, 0, getWidth(), getHeight()); 87 layerManager.paint(g, 0, 0); 88 flushGraphics(); 89 } 90 } [ 예제 10-8] SpriteCollisionCanvas.java

53 TiledLayer 클래스 (1) ▶ TiledLayer 클래스 ▷ 여러 종류의 이미지로 구성된 하나의 이미지 파일을 이용 ▷ 커다란 스크롤 배경을 만들 때 이용 ▶ 타일 만들기 ▷ 10 개의 다른 이미지 ▷ 크기 동일 ▷ TiledLayer bg_img = new TiledLayer(8, 6, background, 48, 48); 53Mobile Programming

54 TiledLayer 클래스 (2) ▶ 셀 만들기 ▷ bg_img = new TiledLayer(8, 6, background, 48, 48); ▷ ani_idx = bg_img.createAnimatedTile(8); ▷ bg_img.setCell(4, 1, ani_idx); ▷ bg_img.setAnimatedTile(ani_idx, 8); 54Mobile Programming

55 TiledLayer 클래스 (3) columns : TiledLayer 열의 크기 rows : TiledLayer 행의 크기 image : 타일이 포함된 이미지 파일의 객체명 tileWidth : 타일의 가로 크기 tileHeight : 타일의 세로 크기 col : 설정할 셀의 열 row : 설정할 셀의 행 tileIndex : 셀에 설정할 타일의 색인 55Mobile Programming TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight) setCell(int col, int row, int tileIndex)

56 TiledLayer 클래스 (4) staticTileIndex : 연결된 타일의 색인, 0 이나 유효한 정적 타일 색인 animatedTileIndex : 애니메이션 타일의 색인 staticTileIndex : 연결된 타일의 색인 56Mobile Programming createAnimatedTile(int staticTileIndex) setAnimatedTile(int animatedTileIndex, int staticTileIndex)

57 TiledLayer 클래스 (5) ▶ 타일과 셀 구현 프로그램 57Mobile Programming

58 TiledLayer 클래스 (6) 58Mobile Programming 01 import java.io.IOException; 02 import javax.microedition.lcdui.*; 03 import javax.microedition.lcdui.game.*; 04 05 class TiledLayerCanvas extends GameCanvas implements Runnable { 06 private LayerManager layer_manager; 07 private TiledLayer bg_img; 08 private int ani_idx; 09 public TiledLayerCanvas() throws IOException { 10 super(true); 11 layer_manager = new LayerManager(); 12 int w = getWidth(); 13 int h = getHeight(); 14 layer_manager.setViewWindow(0, 0, w, h); 15 createBackground("/background_tiles.png"); 16 Thread t = new Thread(this); 17 t.start(); 18 } [ 예제 10-9] TiledLayerCanvas.java

59 TiledLayer 클래스 (7) 59Mobile Programming 19 private void createBackground(String background_img_file) 20 throws IOException { 21 Image background = Image.createImage(background_img_file); 22 int[] map = { 23 0, 0, 0, 0, 0, 8, 0, 0, 24 1, 2, 0, 0, 8, 0, 0, 0, 25 3, 3, 2, 0, 0, 0, 5, 0, 26 3, 3, 3, 2, 4, 1, 3, 2, 27 6, 6, 6, 6, 6, 6, 6, 6, 28 6, 6, 6, 6, 6, 6, 6, 6 29 }; 30 bg_img = new TiledLayer(8, 6, background, 48, 48); 31 bg_img.setPosition(0, 0); 32 for(int i = 0; i < map.length; i++) { 33 int column = i % 8; 34 int row = (i - column) / 8; 35 bg_img.setCell(column, row, map[i]); 36 } 37 ani_idx = bg_img.createAnimatedTile(8); 38 bg_img.setCell(4, 1, ani_idx); 39 bg_img.setCell(5, 0, ani_idx); 40 layer_manager.append(bg_img); 41 } [ 예제 10-9] TiledLayerCanvas.java

60 TiledLayer 클래스 (8) 60Mobile Programming 42 public void run() { 43 int w = getWidth(); 44 int h = getHeight(); 45 Graphics g = getGraphics(); 46 int ani_delta = 0; 47 while(true) { 48 bg_img.setAnimatedTile(ani_idx, 8+ani_delta++); 49 if(ani_delta == 3) ani_delta = 0; 50 g.setColor(0xffffff); 51 g.fillRect(0, 0, w, h); 52 layer_manager.paint(g, 0, 0); 53 flushGraphics(); 54 try { 55 Thread.sleep(80); 56 } catch (InterruptedException ie) { } 57 } 58 } 59 } [ 예제 10-9] TiledLayerCanvas.java


Download ppt "게임 API 프로그래밍 Lecture #12. 강의 목차 ▶ 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해 한다. ▶ 주요 게임 API 의 종류와 기본 사용법을 익힌다. ▶ 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다. 2Mobile Programming."

Similar presentations


Ads by Google