게임 api 프로그래밍

60
게게 게게 API API 게게게게게 게게게게게 Lecture #12 Lecture #12

Upload: izzy

Post on 27-Jan-2016

104 views

Category:

Documents


0 download

DESCRIPTION

게임 API 프로그래밍. Lecture #12. 강의 목차. 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해한다 . 주요 게임 API 의 종류와 기본 사용법을 익힌다 . 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다. 게임 API 개요. 게임 API 클래스. GameCanvas 클래스 (1). GameCanvas 클래스 개요 게임용 사용자 인터페이스 제공 주요 제공 기능 Canvas( 명령 , 입력 이벤트 등 ) 에서 상속된 기능 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 게임  API 프로그래밍

게임 게임 APIAPI프로그래밍프로그래밍

Lecture #12Lecture #12

Page 2: 게임  API 프로그래밍

강의 목차강의 목차

▶ 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해한다 .

▶ 주요 게임 API 의 종류와 기본 사용법을 익힌다 .

▶ 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다 .

2Mobile Programming

Page 3: 게임  API 프로그래밍

게임 게임 API API 개요개요

▶ 게임 API 클래스

3Mobile Programming

Page 4: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (1)(1)

▶ GameCanvas 클래스 개요▷ 게임용 사용자 인터페이스 제공

▷ 주요 제공 기능 Canvas( 명령 , 입력 이벤트 등 ) 에서 상속된 기능 off-screen 그래픽 버퍼 기능

– 깜박임 현상 예방 키 상태 쿼리 기능

4Mobile Programming

Page 5: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (2)(2)

▶ GameCanvas 클래스 생성자

▷ suppressKeyEvents 일반 키 이벤트 기법의 억제 여부 결정

▷ suppressKeyEvents=true 일 때 정의된 게임 키 (UP, DOWN, LEFT, RIGHT, FIRE, 1, 3, 7, 9)

– keyPressed, keyRepeated, keyReleased 메소드 호출 안함 – 시스템이 이벤트 처리– 성능 향상

▷ suppressKeyEvents=false 일 때 게임 키에 일반 키 이벤트 기법을 적용

5Mobile Programming

GameCanvas(boolean suppressKeyEvents)GameCanvas(boolean suppressKeyEvents)

Page 6: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (3)(3)

▶ GameCanvas 클래스 메소드

6Mobile Programming

Page 7: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (4)(4)

▶ flushGraphics() 메소드

▶ getGraphics() 메소드

▶ getKeyStates() 메소드

▶ paint() 메소드

7Mobile Programming

flushGraphics(int x, int y, int width, int height)flushGraphics(int x, int y, int width, int height)

getGraphics( )getGraphics( )

getKeyStates( )getKeyStates( )

paint(Graphics g)paint(Graphics g)

Page 8: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (5)(5)

▶ 볼 애니메이션 프로그램

8Mobile Programming

상하 좌우 방향 키 클릭

(a) 초기 화면 (b) 시작 후 화면

Page 9: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (6)(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-1] MyCanvasMIDlet.java

Page 10: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (7)(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[ 예제 10-1] MyCanvasMIDlet.java

Page 11: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (8)(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[ 예제 10-2] MyCanvas.java

Page 12: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (9)(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[ 예제 10-2] MyCanvas.java

Page 13: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (10)(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[ 예제 10-2] MyCanvas.java

Page 14: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (11)(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[ 예제 10-2] MyCanvas.java

Page 15: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (12)(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[ 예제 10-3] MyGameCanvas.java

Page 16: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (13)(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[ 예제 10-3] MyGameCanvas.java

Page 17: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (14)(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[ 예제 10-3] MyGameCanvas.java

Page 18: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (15)(15)

▶ MyCanvas 클래스와 MyGameCanvas 클래스의 차이

18Mobile Programming

MyCanvas MyGameCanvas

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() 메소드 정의게임 키 버튼을 눌렀을 때 실행된다 .

Page 19: 게임  API 프로그래밍

GameCanvas GameCanvas 클래스 클래스 (16)(16)

▶ MyCanvas 클래스와 MyGameCanvas 클래스 비교

19Mobile Programming

Thread

• Graphics( ); ► flushGraphics( );• getKeyStates( );• Thread.sleep

• Graphics( ); ► flushGraphics( );• getKeyStates( );• Thread.sleep

While 문

paint( )paint( )

keyPressed( )keyPressed( )

Thread

• repaint( );• Thread.sleep• repaint( );• Thread.sleep

While 문

Page 20: 게임  API 프로그래밍

Layer Layer 클래스 클래스 (1)(1)

▶ Layer▷ 여러 이미지가 하나로 결합

▶ Layer 로 이미지를 중첩한 화면 예

20Mobile Programming

Page 21: 게임  API 프로그래밍

Layer Layer 클래스 클래스 (2)(2)

▶ Layer 클래스▷ 각 레이어의 위치 , 너비 , 높이 , 표시 여부를 선택할 수 있는

메소드 제공

21Mobile Programming

Page 22: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (1)(1)

▶ LayerManager 클래스 ▷ 그래픽 레이어 관리▷ 레이어를 추가 , 삽입 , 삭제 , 유지 , 관리하는 메소드 제공▷ 레이어 순서

Z 축을 기준으로 추가 (Append) 할 때마다 0 부터 1 씩 증가 0 은 사용자에게 가장 가까운 레이어 숫자가 높을수록 멀어진다 .

▶ 레이어 2 인 sky.png 를 레이어 0 으로 만드는 경우▷ hany.png, background_tiles 이미지

화면에 보이지 않음▷ 하늘 이미지만 화면에 나타남

22Mobile Programming

Page 23: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (2)(2)

▶ 보기창▷ 화면에 표시될 영역의 크기▷ 좌표계 위치 조정▷ setViewWindow() 메소드

화면에 출력되는 영역과 크기 설정

23Mobile Programming

setViewWindow(int x, int y, int width, int height)setViewWindow(int x, int y, int width, int height)

• x : LayerManager 의 원점에서 상대적인 보기 창의 수평 위치

• y : LayerManager 의 원점에서 상대적인 보기 창의 수직 위치

• width : 보기 창의 넓이

• height : 보기 창의 높이

Page 24: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (3)(3)

▶ 보기창

g : getGraphics() 메소드로 얻은 Graphics 객체 x : Graphics 의 변환 원점에서 상대적인 보기 창을 렌더링할 수평 위치 y : Graphics 의 변환 원점에서 상대적인 보기 창을 렌더링할 수직 위치

24Mobile Programming

paint(Graphics g, int x, int y)paint(Graphics g, int x, int y)

Page 25: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (4)(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, 625 };

[ 예제 10-4] LayerManagerTest.java[ 예제 10-4] LayerManagerTest.java

Page 26: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (5)(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[ 예제 10-4] LayerManagerTest.java

Page 27: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (6)(6)

▶ 레이어 순서▷ Z 축을 기준으로 0 부터 순차적으로 증가

▶ 색인 값이 가장 높은 레이어▷ 사용자에게서 가장 멀리 있는 레이어

▶ 색인이 0 인 레이어▷ 사용자에게서 가장 가까이 위치

27Mobile Programming

Layer 0

Layer 1Layer 2

Y 축

X 축

Z 축

Page 28: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (7)(7)

▶ append() 메소드

I : 추가되는 Layer

▶ insert() 메소드

I : 삽입되는 Layer index : 새 Layer 가 삽입되는 위치

▶ remove() 메소드

I : 제거되는 Layer

28Mobile Programming

public void append(Layer I)public void append(Layer I)

public void insert(Layer I, int index)public void insert(Layer I, int index)

public void remove(Layer I)public void remove(Layer I)

Page 29: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (7)(7)

▶ append() 메소드를 이용하여 레이어를 추가하는 방법▷ 예제 10-5 참조

▷ 실행 결과

29Mobile Programming

Page 30: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (8)(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[ 예제 10-5] LayerManagerAppend.java

Page 31: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (9)(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, 637 };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 [ 예제 10-5] LayerManagerAppend.java

Page 32: 게임  API 프로그래밍

LayerManager LayerManager 클래스 클래스 (10)(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[ 예제 10-5] LayerManagerAppend.java

Page 33: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (1)(1)

▶ Sprite 클래스▷ 하나의 이미지로 저장된 여러 프레임을 같은 크기의 프레임으로

분리하여 애니메이션 효과를 제공▷ setFrame(), setPosition() 등의 메소드 이용▷ 주요 기능

애니메이션 회전 /대칭 충돌 체크

▶ Sprite 클래스 생성자

33Mobile Programming

Page 34: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (2)(2)

▶ Sprite 클래스 메소드

34Mobile Programming

Page 35: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (3)(3)

▶ 애니메이션 적용하기▷ 프레임 여러 개로 구성된 하나의 이미지 파일

▶ 예제 10-6 참조

35Mobile Programming

Page 36: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (4)(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[ 예제 10-6] SpriteSkiingCanvas.java

Page 37: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (5)(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[ 예제 10-6] SpriteSkiingCanvas.java

Page 38: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (6)(6)

▶ 객체 회전시키기▷ Sprite 클래스

객체를 회전 , 대칭시키는 메소드 제공– setTransform(transform)

90 도의 배수로 회전 또는 대칭 변환 가능▷ setTransform(transform) 에 적용할 수 있는 변환 종류

38Mobile Programming

Page 39: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (7)(7)

▶ Sprite 변환 예

▶ 예제 10-7 참조

39Mobile Programming

Page 40: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (8)(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_ROT27017 };18 private static final int [] transMirrorArray = {19 Sprite.TRANS_MIRROR,20 Sprite.TRANS_MIRROR_ROT90,21 Sprite.TRANS_MIRROR_ROT180,22 Sprite.TRANS_MIRROR_ROT27023 };

[ 예제 10-7] SpriteTransCanvas.java[ 예제 10-7] SpriteTransCanvas.java

Page 41: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (9)(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[ 예제 10-7] SpriteTransCanvas.java

Page 42: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (10)(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[ 예제 10-7] SpriteTransCanvas.java

Page 43: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (11)(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[ 예제 10-7] SpriteTransCanvas.java

Page 44: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (12)(12)

▶ 충돌 체크하기▷ 충돌 체크 방법

직사각형 교차 충돌 픽셀 수준 충돌

44Mobile Programming

Page 45: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (13)(13)

▶ 충돌 체크 관련 메소드

45Mobile Programming

Page 46: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (14)(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 void defineCollisionRectangle(int x, int y, int width, int height)

public final boolean collidesWith(Image image, int x, int y, boolean

pixelLevel)

public final boolean collidesWith(Image image, int x, int y, boolean

pixelLevel)

Page 47: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (15)(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(Sprite s, boolean pixelLevel)

public final boolean collidesWith(TiledLayer t, boolean pixelLevel)

public final boolean collidesWith(TiledLayer t, boolean pixelLevel)

Page 48: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (16)(16)

▶ 충돌 체크 프로그램

48Mobile Programming

Page 49: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (17)(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[ 예제 10-8] SpriteCollisionCanvas.java

Page 50: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (18)(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[ 예제 10-8] SpriteCollisionCanvas.java

Page 51: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (19)(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[ 예제 10-8] SpriteCollisionCanvas.java

Page 52: 게임  API 프로그래밍

Sprite Sprite 클래스 클래스 (20)(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[ 예제 10-8] SpriteCollisionCanvas.java

Page 53: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (1)(1)

▶ TiledLayer 클래스▷ 여러 종류의 이미지로 구성된 하나의 이미지 파일을 이용▷ 커다란 스크롤 배경을 만들 때 이용

▶ 타일 만들기▷ 10 개의 다른 이미지▷ 크기 동일▷ TiledLayer bg_img = new TiledLayer(8, 6, background, 48,

48);

53Mobile Programming

Page 54: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (2)(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

Page 55: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (3)(3)

columns : TiledLayer 열의 크기 rows : TiledLayer 행의 크기 image : 타일이 포함된 이미지 파일의 객체명 tileWidth : 타일의 가로 크기 tileHeight : 타일의 세로 크기

col : 설정할 셀의 열 row : 설정할 셀의 행 tileIndex : 셀에 설정할 타일의 색인

55Mobile Programming

TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight)

TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight)

setCell(int col, int row, int tileIndex)setCell(int col, int row, int tileIndex)

Page 56: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (4)(4)

staticTileIndex : 연결된 타일의 색인 , 0 이나 유효한 정적 타일 색인

animatedTileIndex : 애니메이션 타일의 색인 staticTileIndex : 연결된 타일의 색인

56Mobile Programming

createAnimatedTile(int staticTileIndex)createAnimatedTile(int staticTileIndex)

setAnimatedTile(int animatedTileIndex, int staticTileIndex)setAnimatedTile(int animatedTileIndex, int staticTileIndex)

Page 57: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (5)(5)

▶ 타일과 셀 구현 프로그램

57Mobile Programming

Page 58: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (6)(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[ 예제 10-9] TiledLayerCanvas.java

Page 59: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (7)(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, 629 };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[ 예제 10-9] TiledLayerCanvas.java

Page 60: 게임  API 프로그래밍

TiledLayer TiledLayer 클래스 클래스 (8)(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[ 예제 10-9] TiledLayerCanvas.java