게임 api 프로그래밍 lecture #12. 강의 목차 ▶ 모바일 게임 프로그래밍에...
DESCRIPTION
게임 API 개요 ▶ 게임 API 클래스 3Mobile ProgrammingTRANSCRIPT
게임 게임 APIAPI프로그래밍프로그래밍
Lecture #12Lecture #12
강의 목차강의 목차
▶ 모바일 게임 프로그래밍에 필요한 게임 API 의 개념을 이해한다 .
▶ 주요 게임 API 의 종류와 기본 사용법을 익힌다 .▶ 게임 API 를 이용해 실제 게임 동작을 직접 구현해 본다 .
2Mobile Programming
게임 게임 API API 개요개요
▶ 게임 API 클래스
3Mobile Programming
GameCanvas GameCanvas 클래스 클래스 (1)(1)
▶ GameCanvas 클래스 개요▷ 게임용 사용자 인터페이스 제공
▷ 주요 제공 기능 Canvas( 명령 , 입력 이벤트 등 ) 에서 상속된 기능 off-screen 그래픽 버퍼 기능
– 깜박임 현상 예방 키 상태 쿼리 기능
4Mobile Programming
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 GameCanvas 클래스 클래스 (3)(3)
▶ GameCanvas 클래스 메소드
6Mobile Programming
GameCanvas GameCanvas 클래스 클래스 (4)(4)
▶ flushGraphics() 메소드
▶ getGraphics() 메소드
▶ getKeyStates() 메소드
▶ paint() 메소드
7Mobile Programming
flushGraphics(int x, int y, int width, int height)
getGraphics( )
getKeyStates( )
paint(Graphics g)
GameCanvas GameCanvas 클래스 클래스 (5)(5)
▶ 볼 애니메이션 프로그램
8Mobile Programming
상하 좌우 방향 키 클릭
(a) 초기 화면 (b) 시작 후 화면
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
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
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
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
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
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
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
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
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
GameCanvas GameCanvas 클래스 클래스 (15)(15)
▶ MyCanvas 클래스와 MyGameCanvas 클래스의 차이
18Mobile Programming
MyCanvas MyGameCanvasimport 패키지 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() 메소드 정의게임 키 버튼을 눌렀을 때 실행된다 .
GameCanvas GameCanvas 클래스 클래스 (16)(16)
▶ MyCanvas 클래스와 MyGameCanvas 클래스 비교
19Mobile Programming
Thread
• Graphics( ); ► flushGraphics( );• getKeyStates( );• Thread.sleep
While 문
paint( )
keyPressed( )
Thread
• repaint( );• Thread.sleep
While 문
Layer Layer 클래스 클래스 (1)(1)
▶ Layer▷ 여러 이미지가 하나로 결합
▶ Layer 로 이미지를 중첩한 화면 예
20Mobile Programming
Layer Layer 클래스 클래스 (2)(2)
▶ Layer 클래스▷ 각 레이어의 위치 , 너비 , 높이 , 표시 여부를 선택할 수 있는
메소드 제공
21Mobile Programming
LayerManager LayerManager 클래스 클래스 (1)(1)
▶ LayerManager 클래스 ▷ 그래픽 레이어 관리▷ 레이어를 추가 , 삽입 , 삭제 , 유지 , 관리하는 메소드 제공▷ 레이어 순서
Z 축을 기준으로 추가 (Append) 할 때마다 0 부터 1 씩 증가 0 은 사용자에게 가장 가까운 레이어 숫자가 높을수록 멀어진다 .
▶ 레이어 2 인 sky.png 를 레이어 0 으로 만드는 경우▷ hany.png, background_tiles 이미지
화면에 보이지 않음▷ 하늘 이미지만 화면에 나타남
22Mobile Programming
LayerManager LayerManager 클래스 클래스 (2)(2)
▶ 보기창▷ 화면에 표시될 영역의 크기▷ 좌표계 위치 조정▷ setViewWindow() 메소드
화면에 출력되는 영역과 크기 설정
23Mobile Programming
setViewWindow(int x, int y, int width, int height)
• x : LayerManager 의 원점에서 상대적인 보기 창의 수평 위치
• y : LayerManager 의 원점에서 상대적인 보기 창의 수직 위치
• width : 보기 창의 넓이
• height : 보기 창의 높이
LayerManager LayerManager 클래스 클래스 (3)(3)
▶ 보기창
g : getGraphics() 메소드로 얻은 Graphics 객체 x : Graphics 의 변환 원점에서 상대적인 보기 창을 렌더링할 수평 위치 y : Graphics 의 변환 원점에서 상대적인 보기 창을 렌더링할 수직 위치
24Mobile Programming
paint(Graphics g, int x, int y)
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
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
LayerManager LayerManager 클래스 클래스 (6)(6)
▶ 레이어 순서▷ Z 축을 기준으로 0 부터 순차적으로 증가
▶ 색인 값이 가장 높은 레이어▷ 사용자에게서 가장 멀리 있는 레이어
▶ 색인이 0 인 레이어▷ 사용자에게서 가장 가까이 위치
27Mobile Programming
Layer 0
Layer 1Layer 2
Y 축
X 축
Z 축
LayerManager LayerManager 클래스 클래스 (7)(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)
LayerManager LayerManager 클래스 클래스 (7)(7)
▶ append() 메소드를 이용하여 레이어를 추가하는 방법▷ 예제 10-5 참조
▷ 실행 결과
29Mobile Programming
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
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
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
Sprite Sprite 클래스 클래스 (1)(1)
▶ Sprite 클래스▷ 하나의 이미지로 저장된 여러 프레임을 같은 크기의 프레임으로
분리하여 애니메이션 효과를 제공▷ setFrame(), setPosition() 등의 메소드 이용▷ 주요 기능
애니메이션 회전 /대칭 충돌 체크
▶ Sprite 클래스 생성자
33Mobile Programming
Sprite Sprite 클래스 클래스 (2)(2)
▶ Sprite 클래스 메소드
34Mobile Programming
Sprite Sprite 클래스 클래스 (3)(3)
▶ 애니메이션 적용하기▷ 프레임 여러 개로 구성된 하나의 이미지 파일
▶ 예제 10-6 참조
35Mobile Programming
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
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
Sprite Sprite 클래스 클래스 (6)(6)
▶ 객체 회전시키기▷ Sprite 클래스
객체를 회전 , 대칭시키는 메소드 제공– setTransform(transform)
90 도의 배수로 회전 또는 대칭 변환 가능▷ setTransform(transform) 에 적용할 수 있는 변환 종류
38Mobile Programming
Sprite Sprite 클래스 클래스 (7)(7)
▶ Sprite 변환 예
▶ 예제 10-7 참조
39Mobile Programming
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
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
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
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
Sprite Sprite 클래스 클래스 (12)(12)
▶ 충돌 체크하기▷ 충돌 체크 방법
직사각형 교차 충돌 픽셀 수준 충돌
44Mobile Programming
Sprite Sprite 클래스 클래스 (13)(13)
▶ 충돌 체크 관련 메소드
45Mobile Programming
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 final boolean collidesWith(Image image, int x, int y, boolean pixelLevel)
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(TiledLayer t, boolean pixelLevel)
Sprite Sprite 클래스 클래스 (16)(16)
▶ 충돌 체크 프로그램
48Mobile Programming
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
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
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
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
TiledLayer TiledLayer 클래스 클래스 (1)(1)
▶ TiledLayer 클래스▷ 여러 종류의 이미지로 구성된 하나의 이미지 파일을 이용▷ 커다란 스크롤 배경을 만들 때 이용
▶ 타일 만들기▷ 10 개의 다른 이미지▷ 크기 동일▷ TiledLayer bg_img = new TiledLayer(8, 6, background, 48,
48);
53Mobile Programming
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
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)
setCell(int col, int row, int tileIndex)
TiledLayer TiledLayer 클래스 클래스 (4)(4)
staticTileIndex : 연결된 타일의 색인 , 0 이나 유효한 정적 타일 색인
animatedTileIndex : 애니메이션 타일의 색인 staticTileIndex : 연결된 타일의 색인
56Mobile Programming
createAnimatedTile(int staticTileIndex)
setAnimatedTile(int animatedTileIndex, int staticTileIndex)
TiledLayer TiledLayer 클래스 클래스 (5)(5)
▶ 타일과 셀 구현 프로그램
57Mobile Programming
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
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
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