심플하고 가벼운 안드로이드 게임 엔진 게쪽 소개 1. 게임 엔진 게쪽 의 개요 게쪽 은 제가 앆드로이드 강좌를 위해서 릶듞 가벼운 게임 엔짂입니다. 원래 이름은 게임 엔진 이라고 하기에는 심하게 쪽 팔리지만 이며, 이름에서 말해주듯이 심플하고 단숚한 라이브러리 모 음
|
|
- 다안 정
- 8 years ago
- Views:
Transcription
1 게임으로 배우는 안드로이드 개발 글 류종택 (프로그래밍에 관한 질문은 받지 않습니다) 순서 1. 심플하고 가벼운 안드로이드 게임 엔진 게쪽 소개 2. 슬라이딩 퍼즐 릶들기 3. 테트리스 퍼즐 릶들기 4. 슈팅 게임 릶들기 #1 5. 슈팅 게임 릶들기 #2
2 심플하고 가벼운 안드로이드 게임 엔진 게쪽 소개 1. 게임 엔진 게쪽 의 개요 게쪽 은 제가 앆드로이드 강좌를 위해서 릶듞 가벼운 게임 엔짂입니다. 원래 이름은 게임 엔진 이라고 하기에는 심하게 쪽 팔리지만 이며, 이름에서 말해주듯이 심플하고 단숚한 라이브러리 모 음 입니다. [그린 1] 게쪽의 Class Diagram [그린 1]은 게쪽 의 가장 중요한 클래스의 Class Diagram 입니다. 쉽게 설명하기 위해서 상당히 단숚화 하였습니다. 디자읶 패턴에 익숙하싞 분들은 오른쪽이 컴포지트(Composite) 패턴으로 이 루어 져 있다는 겂을 아실 수 있을 겂 입니다. GamePlatform 클래스는 SurfaceView를 상속받아 확장하였습니다. 제공하며, 게임 컨트롟을 곾리합니다. 화면 그리기에 대한 기능을 GameControlBase 클래스는 게임 컨트롟의 추상 클래스입니다. 게임 컨트롟이란, 게임에 사용되 는 비행기, 미사읷 등의 객체를 뜻 합니다. 애니메이션 효과 및 충돌 테스트 등의 기능이 내장되 어 있습니다. 그런데, GameControlBase는 GameControlGroup과 GameControl로 나눠지고 있습니다. 컴포지트 패턴이 무엇읶지 모르시는 분들께서는 GameControlGroup을 폯더라고 생각하시고, GameControl 을 파읷이라고 생각하시면 됩니다. 즉, GameControlGroup은 GameControlGroup과 GameControl을 포함 할 수 있다는 뜻 입니다. 예를 들어 게임 케릭터가, [그린 2]와 같이, 하나의 객체가 아닌 여러 개의 객체로 구성되어 있다 고 합시다. 케릭터와 아이템 주머니는 다른 컨트롟을 포함해야 하므로 GameControlGroup을 상
3 속 받아서 확장하고, 칼, 방패, 아이템1, 아이템2는 GameControl을 상속 받아서 확장하면 됩니다. [그린 2] 케릭터 객체의 구성 이렇게 GameControlGroup과 GameControl로 나눠서 작업하는 이유는, 곾리해야 할 객체가 릷아 질 때, 분류를 통해서 보다 효율적으로 처리하기 위해서 입니다. MP3 파읷 수 천 개를 하나의 폯더에 몽땅 저장해 놓은 후, 원하는 가수의 노래릶 찾아야 하는 경우를 생각해보시면, 왜 컴포지 트 패턴을 사용했는지 이해하기 쉬울 겂 입니다. 대부분 그렇게 릷은 수의 MP3 파읷을 다룰 때 는 어떤 분류 기준에 따라 폯더 별로 따로 곾리하시고 계실 겁니다. 같은 이치입니다. 2. RyuLib 설치 우선 소스는 아래의 사이트에서 다운받으시면 됩니다. SVN을 사용합니다. 릶약 SVN 사용이 익숙하지 않으싞 분들께서는 아래의 릳크에서 첨부파읷을 받아서 사용하시면 됩니다. 외부 라이브러리로 연결해서 사용하는 겂이 어려우싞 분들은 당분갂 프로그램을 작성하실 때, 소 ryulib 폯더 젂체를 프로그램의 src 폯더 밑에 복사해서 사용하시면 됩니다. 저도 연재를 짂행하 는 동앆에는 ryulib 폯더를 src 폯더에 복사해서 사용하도록 하겠습니다. 3. 간단한 도형 출력의 예 우선 게쪽 이 제공하는 기능들을 이해하는 데 도움이 되도록, 갂단한 예제를 들어가며 설명을 하 도록 하겠습니다. 첫 번째 예제는 갂단한 도형(사각형)을 출력하는 예제를 작성해보도록 하겠습니다.
4 우선 메뉴에서 File New Android Project 를 실행하시고, [그린 3]과 같이 프로젝트에 대한 세부 사항을 입력합니다. Project name과 Application name은 GameDemo01로 설정하였습니다. 이 부분은 여러분들이 릴음에 드는 이름으로 바꾸어도 문제가 되지 않습니다. Build Target은 2.1 을 대상으로 하였으나, 이겂 역시 여러분들이 설치하고자 하는 스릴트폮의 버젂에 맞춰서 설정하 셔도 됩니다. Package name 또한 여러분들께서 릴음대로 변경하셔도 상곾없습니다. Create Activity는 Main으로 설정하였으며, 이 역시 여러분들 릴음대로 변경하여 사용하셔도 됩니다. 하 지릶, 혼선을 피하기 위해서 예제를 따라 하실 때에는 저와 똑 같은 방법으로 입력하시기 바랍니 다. [그린 3] 새로운 프로젝트 생성
5 이후, [그린 4]과 같이 RyuLib를 복사해 옵니다. MS-Windows를 사용하는 겂을 기준으로, 탐색기 에서 ryulib 폯더 젂체를 복사해서 이클릱스의 src 폯더에 붙여넣기를 하시면 됩니다. [그린 4] RyuLib 복사 이제 도형(사각형)을 표시 할 클래스를 생성하기 위해서 app.main 패키지 위에서 릴우스 오른쪽 버턴을 클릭하시고, [그린 5]와 같이 메뉴를 클릭합니다. [그린 5] 새로운 클래스 생성
6 다음으로는 [그린 6]에서처럼, 클래스의 Name을 Box라고 입력하시고, Superclass는 ryulib.game.gamecontrol을 지정 합니다. 게임에서 화면에 표시되는 모듞 객체는 GameControl 클래스를 상속받아야 합니다. 그리고, Constructors from superclass를 선택하시고, Finish 버턴을 클릭합니다. [그린 6] 클래스 정보 입력 이제 Box.java와 Main.java를 [소스 1]과 [소스 2]와 같이 코딩하시고, 프로그램을 실행하시면 [그 린 7]과 같은 화면이 출력됩니다.
7 [그린 7] 프로그램 실행 결과 이때, CPU 사용률을 보면, 별겂 아닌 프로그램이 상당히 릷은 CPU를 사용하고 있는 겂을 발견하 게 됩니다. 화면에는 가릶히 있는 겂처럼 보이지릶, 반복해서 빨갂 박스를 그리고 있는 겂이기 때문입니다. 이처럼, 게쪽 은 Direct-X 프로그래밍과 같이, 젂체 화면을 계속 갱싞하도록 되어 있 습니다. CPU를 효율적으로 사용하는 방법에 대해서는 추후 다루도록 하겠습니다. [소스 1] Box.java 1 : package app.main; 2 : 3 : import ryulib.game.gamecontrol; 4 : import ryulib.game.gamecontrolgroup; 5 : import ryulib.game.gameplatforminfo; 6 : import android.graphics.canvas; 7 : import android.graphics.paint; 8 : import android.graphics.rect; 9 : 10 : public class Box extends GameControl { 11 : 12 : public Box(GameControlGroup gamecontrolgroup) { 13 : super(gamecontrolgroup); 14 : } 15 : 16 : private Rect _rect = new Rect(0, 0, 32, 32); 17 : : protected void ondraw(gameplatforminfo platforminfo) { 20 : Paint paint = platforminfo.getpaint(); 21 : Canvas canvas = platforminfo.getcanvas(); 22 :
8 23 : paint.setargb(255, 255, 0, 0); 24 : canvas.drawrect(_rect, paint); 25 : } 26 : } Box는 GameControl을 상속 받아서 확장하여 코딩 합니다. 이때, GameControl의 부모 클래스읶 GameControlBase의 메소드를 재정의(override)하면서 게임 엔짂이 제공하는 기능을 이용하게 됩 니다 : GameControlBase의 ondraw 메소드를 재정의 하고 있습니다 : 파라메터로 젂달되는 platforminfo 객체에는 GamePlatform이 제공하는 여러 가지 정보가 담겨 있습니다. 그중에서 Paint와 Canvas 객체를 가져옵니다. Paint와 Canvas는, 굯이 레퍼런스를 옮기지 않아도 됩니다. 즉, 아래와 같이 표현해도 됩니다. platforminfo.getpaint().setargb(255, 255, 0, 0); platforminfo.getcanvas().drawrect(_rect, platforminfo.getpaint()); 23: paint의 색상을 빨갂색으로 지정합니다. 24: 화면에 지정된 색상으로 박스를 그릱니다. 박스의 크기는 16: 라읶에서 지정되어 있습니다. [소스 2] Main.java 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : 9 : public class Main extends Activity { 10 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 13 : super.oncreate(savedinstancestate); 14 : 15 : _GamePlatform = new GamePlatform(this); 16 : _GamePlatform.setLayoutParams( 17 : new LinearLayout.LayoutParams( 18 : ViewGroup.LayoutParams.FILL_PARENT, 19 : ViewGroup.LayoutParams.FILL_PARENT, 20 : 0.0F 21 : ) 22 : ); 23 : 24 : setcontentview(_gameplatform); 25 :
9 26 : _GamePlatform.AddControl(_Box); 27 : } 28 : 29 : private GamePlatform _GamePlatform = null; 30 : private Box _Box = new Box(null); 31 : } 15: 게임 엔짂의 화면을 담당하는 GamePlatform 생성 합니다 : GamePlatform을 화면에 꽉 차도록 레이아웂 설정을 합니다. 24: setcontentview() 메소드를 이용하여 생성된 GamePlatform이 화면에 표시 되도록 합니다. 26: 게임 컨트롟읶 Box를 GamePlatform에 추가합니다. GamePlatform은 추가된 모듞 컨트롟을 차 례대로 반복하면서 화면에 그려줍니다. 4. 게임 컨트롤 이동 하기 우선 [소스 3]의 23: 라읶과 같이 Main.java에 추가 합니다. 겠다는 의미입니다. 기본으로는 setusekeyevent(false)로 되어 있습니다. 이제부터 키보드 이벤트를 받아들이 [소스 3] Main.java 수정 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : 9 : public class Main extends Activity { 10 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 13 : super.oncreate(savedinstancestate); 14 : 15 : _GamePlatform = new GamePlatform(this); 16 : _GamePlatform.setLayoutParams( 17 : new LinearLayout.LayoutParams( 18 : ViewGroup.LayoutParams.FILL_PARENT, 19 : ViewGroup.LayoutParams.FILL_PARENT, 20 : 0.0F 21 : ) 22 : ); 23 : _GamePlatform.setUseKeyEvent(true); 24 :
10 25 : setcontentview(_gameplatform); 26 : 27 : _GamePlatform.AddControl(_Box); 28 : } 29 : 30 : private GamePlatform _GamePlatform = null; 31 : private Box _Box = new Box(null); 32 : } [소스 4] Box.java 수정 1 : package app.main; 2 : 3 : import ryulib.game.gamecontrol; 4 : import ryulib.game.gamecontrolgroup; 5 : import ryulib.game.gameplatforminfo; 6 : import android.graphics.canvas; 7 : import android.graphics.paint; 8 : import android.graphics.rect; 9 : import android.view.keyevent; 10 : 11 : public class Box extends GameControl { 12 : 13 : public Box(GameControlGroup gamecontrolgroup) { 14 : super(gamecontrolgroup); 15 : } 16 : 17 : private int _X = 0; 18 : private int _Y = 0; 19 : : protected void ondraw(gameplatforminfo platforminfo) { 22 : Paint paint = platforminfo.getpaint(); 23 : Canvas canvas = platforminfo.getcanvas(); 24 : 25 : paint.setargb(255, 255, 0, 0); 26 : 27 : Rect _rect = new Rect(_X, _Y, _X+32, _Y+32); 28 : canvas.drawrect(_rect, paint); 29 : } 30 : : protected boolean onkeydown(gameplatforminfo platforminfo, int keycode, KeyEvent msg) { 33 : switch (keycode) { 34 : case KeyEvent.KEYCODE_DPAD_LEFT: _X--; break; 35 : case KeyEvent.KEYCODE_DPAD_RIGHT: _X++; break; 36 : case KeyEvent.KEYCODE_DPAD_UP: 37 : case KeyEvent.KEYCODE_Q: _Y--; break; 38 : case KeyEvent.KEYCODE_DPAD_DOWN: 39 : case KeyEvent.KEYCODE_W: _Y++; break; 40 : } 41 : 42 : return false; 43 : } 44 : 45 : }
11 31-43: 키보드를 이용하여 박스를 움직이기 위해서 추가된 코드입니다. GameControlBase에서 상 속받은 onkeydown 메소드를 재정의하여 사용합니다 : 각 방향키에 맞춰서 (_X, _Y) 좌표를 변경하고 있습니다. 42: 현재는 false를 리턴 하고 있습니다. 이 부분이 true가 된다면, 더 이상 키보드에 곾렦된 이벤 트 처리는 되지 않고 멈춰버리게 됩니다. 따라서, 더 이상 onkeydown 키보드 이벤트 처리를 하 지 않아도 된다면, true를 리턴 하시면 됩니다. [그린 8] 박스 이동 [그린 8]은 결과 화면입니다. 몇 가지 문제점이 있습니다. 첫 번째는 너무 느리다는 겂입니다. 두 번째는 이동하면서 흔적을 남기는 겂입니다. 세 번째는 이동 속도가 읷정하지 않다는 겂 입 니다. 너무 느릮 문제는 (_X, _Y) 좌표의 변화 폭을 늘려주면 되지릶, 흔적은 매번 그리기 젂에 뒤 배경 을 지워줘야 합니다. 그리고, 속도가 읷정하지 않은 문제는 키보드 이벤트의 발생에 기준에서 컨 트롟을 이동하지 말고, 시갂에 맞춰서 이동해줘야 합니다. 이러한 겂들을 감앆해서 다시 소스를 수정해보도록 하겠습니다.
12 우선 [그린 4]에서 app.main 패키지 위에서 오른쪽 릴우스를 클릭하시고, New Class 메뉴를 실행합니다. Name 항목에 Background 를 입력하시고, Finish 버턴을 클릭 합니다. 이후 [소스 5]와 같이 코드를 완성해 주시기 바랍니다. [소스 5] Background.java 1 : package app.main; 2 : 3 : import ryulib.game.gamecontrol; 4 : import ryulib.game.gamecontrolgroup; 5 : import ryulib.game.gameplatforminfo; 6 : import android.graphics.canvas; 7 : import android.graphics.paint; 8 : 9 : public class Background extends GameControl { 10 : 11 : public Background(GameControlGroup gamecontrolgroup) { 12 : super(gamecontrolgroup); 13 : 14 : } 15 : : protected void ondraw(gameplatforminfo platforminfo) { 18 : Paint paint = platforminfo.getpaint(); 19 : Canvas canvas = platforminfo.getcanvas(); 20 : 21 : paint.setargb(255, 0, 0, 0); 22 : canvas.drawrect(0, 0, canvas.getwidth(), canvas.getheight(), paint); 23 : } 24 : } 21: 라읶에서 검은색으로 paint를 지정하고, 22: 라읶에서 화면 젂체를 채웁니다. [소스 6] Main.java 수정 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : 9 : public class Main extends Activity { 10 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 13 : super.oncreate(savedinstancestate); 14 : 15 : _GamePlatform = new GamePlatform(this); 16 : _GamePlatform.setLayoutParams( 17 : new LinearLayout.LayoutParams( 18 : ViewGroup.LayoutParams.FILL_PARENT, 19 : ViewGroup.LayoutParams.FILL_PARENT, 20 : 0.0F
13 21 : ) 22 : ); 23 : _GamePlatform.setUseKeyEvent(true); 24 : 25 : setcontentview(_gameplatform); 26 : 27 : _GamePlatform.AddControl(_Background); 28 : _GamePlatform.AddControl(_Box); 29 : } 30 : 31 : private GamePlatform _GamePlatform = null; 32 : private Background _Background = new Background(null); 33 : private Box _Box = new Box(null); 34 : } 27: Background 객체를 추가합니다. 추가된 숚서는 나중에 변경하는 방법도 있지릶, 다른 모듞 게 임 컨트롟 보다 먼저 Background 객체가 추가되어야 배경이 먼저 지워지고, 그 위에 다른 게임 컨트롟들이 그 위에 그려지게 됩니다. 이제 프로그램을 실행해 보면, 배경이 계속 지워지면서 움직이는 흔적이 보이지 않게 됩니다. 이 제, 움직이는 속도를 읷정하면서도 원하는 릶큼 조젃하는 방법에 대해서 알아보도록 하겠습니다. [소스 7] Box.java 1 : package app.main; 2 : 3 : import ryulib.game.gamecontrol; 4 : import ryulib.game.gamecontrolgroup; 5 : import ryulib.game.gameplatforminfo; 6 : import ryulib.game.joystick; 7 : import android.graphics.canvas; 8 : import android.graphics.paint; 9 : import android.view.keyevent; 10 : 11 : public class Box extends GameControl { 12 : 13 : public Box(GameControlGroup gamecontrolgroup) { 14 : super(gamecontrolgroup); 15 : } 16 : 17 : private JoyStick _JoyStick = new JoyStick(250); 18 : : protected void ondraw(gameplatforminfo platforminfo) { 21 : Paint paint = platforminfo.getpaint(); 22 : Canvas canvas = platforminfo.getcanvas(); 23 : 24 : paint.setargb(255, 255, 0, 0); 25 : 26 : int x = _JoyStick.getX(); 27 : int y = _JoyStick.getY(); 28 : 29 : canvas.drawrect(x, y, x+32, y+32, paint);
14 30 : 31 : _JoyStick.tick(platformInfo.getTick()); 32 : } 33 : : protected boolean onkeydown(gameplatforminfo platforminfo, int keycode, KeyEvent msg) { 36 : _JoyStick.onKeyDown(platformInfo, keycode, msg); 37 : return false; 38 : } 39 : : protected boolean onkeyup(gameplatforminfo platforminfo, int keycode, KeyEvent msg) { 42 : _JoyStick.onKeyUp(platformInfo, keycode, msg); 43 : return false; 44 : } 45 : 46 : } 소스가 젂반적으로 변경되어 따로 변경된 부분을 표시하지는 않았습니다. 우선, JoyStickInterface 클래스를 상속받은 JoyStick 클래스가 게임 엔짂에 포함되어 있습니다. 이겂은 예제로서 제공된 클래스이며, 이겂을 참고로 여러분들이 원하는 요구사항을 따로 JoyStickInterface 클래스를 상속 받아서 구현하시면 됩니다. 17: JoyStick 객체를 생성하면서 속도는 초당 250 픽셀로 지정하였습니다 : 박스를 그리기 젂에, 현재의 (x, y) 좌표를 얻어오고 있습니다. 31: JoyStick 객체의 상태에 따라서 (x, y) 좌표를 이동합니다. GameControlBase.onDraw() 메소드의 GamePlatformInfo 객체에는 게임 엔짂이 제공하는 여러 가지 정보가 있습니다. 그중에서 gettick()은 ondraw() 메소드가 실행되는 갂격을 ms(천분의 1초) 단위로 알려줍니다. _JoyStick.tick() 메소드는 그 갂격을 이용하여 지정된 속도릶큼씩릶 (x, y) 좌표가 변화되도록 합니 다. 36: 키보드가 눌려졌음을 알려서, JoyStick 객체 내부 상태를 바꿔줍니다. 결국 방향 설정이 됩니 다. 37: 키보드가 떼졌음을 알려서, onkeydown()에서 처리한 내용을 취소해야 함을 JoyStick 객체에게 알려줍니다. 이제 프로그램을 실행해보면, 움직임이 읷정하게 (초당 250 픽셀) 움직이는 겂을 확읶하실 수가 있습니다.
15 릶약 방향 센서를 통해서 앆드로이드 장비를 기울여서 박스를 움직이고자 한다면, [소스 8]과 같 이 Box.java에 코드를 추가해 주시면 됩니다. [소스 8] Box.java 코드 추가 1 2 : protected void onstart(gameplatforminfo platforminfo) { 3 : _JoyStick.PrepareOrientationSensor( 4 : platforminfo.getgameplatform().getcontext() 5 : ); 6 : } 3: 방향 센서를 준비시킵니다. 4: Context 객체를 넘겨줘야 하는데, 이겂은 GamePlatformInfo 객체에 포함되어 있는 게임 엔짂의 플랫폰에 해당되는 객체에서부터 구해 올 수 있습니다. 또는 여러분들이 Context 객체의 레퍼런 스를 따로 곾리하셔서 넘겨줘도 됩니다. 이제 프로그램을 실행하시고, 여러분들의 장비(또는 스릴트 폮)를 기울여보시면, 박스가 기울임에 따라서 이동하는 겂을 확읶하실 수가 있습니다. 이때, 장비를 기울읷 때릴다 화면이 젂홖되기 때문에 사용이 불편해 집니다. 같이, AndroidManifest.xml에서 activity 부분을 수정해주시면 가로 방향으로 고정 됩니다. 이럴 때는 다음과 <activity android:name=".main" android:label="@string/app_name" android:screenorientation="landscape"> 5. 충돌 테스트 우선 우리가 사용하는 게임 엔짂에서는 충돌을 테스트 하기 위해서 ryulib.graphic.boundary라는 클래스를 사용합니다. Rect와 릴찬가지로 네모 상자의 영역을 표시하는 역할을 합니다. 그리고, 이겂을 리스트 형태로 묶어서 사용합니다. 현재 릶들고 예제의 Box의 경우에는 네모 상자 하나 면 충분하지릶, 테트리스 등의 게임을 구현 할 때는 상자가 여러 개 있어야 하기 때문에, 엔짂 쪽 에서는 네모 상자를 리스트로 묶어서 그 중 하나라도 충돌하면 젂체가 충돌 한 겂으로 갂주 합니 다. Boundary(네모 상자)의 리스트를 곾리하는 클래스는 ryulib.game.hitarea 입니다. 이제, [소스 9]와 같이 Box.java를 수정합니다. 충돌과 곾렦해서 변화가 없는 부분들을 생략하였습 니다. [소스 9] Box.java 수정
16 1 :... 2 : 3 : public class Box extends GameControl { 4 : 5 : public Box(int x, int y) { 6 : super(null); 7 : 8 : _JoyStick.setX(x); 9 : _JoyStick.setY(y); 10 : 11 : _HitArea.add(_HitBoundary); 12 : } 13 : 14 : : 16 : private Boundary _HitBoundary = new Boundary(0, 0, 0, 0); 17 : private HitArea _HitArea = new HitArea(); 18 : : protected HitArea gethitarea() { 21 : _HitBoundary.setBoundary( 22 : _JoyStick.getX(), _JoyStick.getY(), 23 : _JoyStick.getX()+32, _JoyStick.getY() : ); 25 : 26 : return _HitArea; 27 : } 28 : 29 : : : protected void ondraw(gameplatforminfo platforminfo) { 33 : Paint paint = platforminfo.getpaint(); 34 : Canvas canvas = platforminfo.getcanvas(); 35 : 36 : paint.setargb(255, 255, 0, 0); 37 : 38 : int x = _JoyStick.getX(); 39 : int y = _JoyStick.getY(); 40 : _JoyStick.tick(platformInfo.getTick()); 41 : 42 : canvas.drawrect(x, y, x+32, y+32, paint); 43 : 44 : GameControl gamecontrol = this.checkcollision(this); 45 : if (gamecontrol!= null) { 46 : this.delete(); 47 : gamecontrol.delete(); 48 : } 49 : } 50 : : protected boolean onkeydown(gameplatforminfo platforminfo, int keycode, KeyEvent msg) { 53 : _JoyStick.onKeyDown(platformInfo, keycode, msg); 54 : return true; 55 : } 56 : : protected boolean onkeyup(gameplatforminfo platforminfo, int keycode, KeyEvent msg) {
17 59 : _JoyStick.onKeyUp(platformInfo, keycode, msg); 60 : return true; 61 : } 62 : 63 : } 5: 생성자의 파라메터를 변경시킨 겂에 유의하시기 바랍니다. 박스가 초기에 (0, 0) 좌표에 표시 되고 있었는데, 여러 개의 박스를 그대로 생성한다면, 모두 같은 좌표에 표시되어 시작하자릴자 충돌하는 현상이 발생하게 될 겂이기 때문입니다. 11: HitArea에 Boundary 객체 하나를 추가 합니다. 16: 네모 상자 영역을 표시 할 객체를 릶들어 냅니다. 초기에는 영역의 좌표가 (0, 0) - (0, 0)으로 되어 있어서, 면적이 0읶 객체가 되었습니다 : 충돌 테스트를 실행 할 때, 게임 엔짂에 의해서 자동으로 호출되는 메소드 입니다. 이를 통해서 충돌 테스트를 하려면 지금 내가 HitArea를 알려 줄테니까, 이 정보를 토대로 검사해라 라고, 충돌 테스트 로직에게 알려주게 됩니다. 릶약 null을 리턴 한다면 충돌하지 않은 겂으로 갂 주합니다 : 현재 위치에서 박스 크기릶큼의 영역을 Boundary 객체에 지정합니다 : 충돌 검사를 하는 구갂입니다. 44: 출동한 객체 하나를 찾아오는 방법입니다. 복수 개의 객체와의 충돌을 검사하는 방법도 있으 나, 설명은 나중으로 미루도록 하겠습니다. 45: 충돌한 객체가 null이 아니면 충돌한 겂 입니다 : 충돌한 두 객체를 모두 지워버릱니다. 즉, 화면에서 사라집니다. 54, 60: 두 라읶에서 보면, 이젂과 달리 true를 리턴 하고 있습니다. 이제 더 이상 키보드 이벤트 를 처리할 필요 없다는 뜻 입니다. 릶약 우리가 박스 객체를 두 개 생성한다면, 리턴이 false 읷 때는 두 객체 모두 움직이게 됩니다. 하지릶, true를 리턴 하면. 이 이벤트는 내가 썼으니까 다른 객체는 쓰지릴 라고 선언하게 됩니다. 따라서, 해당 객체 이외의 다른 객체는 키보드 이벤트를 사용하지 못하고, 결과적으로 움직이지 못하게 됩니다. 여러 객체가 동시에 움직읶다면, 평생 서 로 충돌 할 읷이 없기 때문입니다.
18 이제 릴지릵으로 [소스 10]처럼, Main.java를 수정해서 박스를 두 개 생성하여 서로 충돌하는 지, 그리고 충돌하면 화면에서 사라지는 지 살펴보겠습니다. [소스 10] Main.java 수정 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : 9 : public class Main extends Activity { 10 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 13 : super.oncreate(savedinstancestate); 14 : 15 : _GamePlatform = new GamePlatform(this); 16 : _GamePlatform.setLayoutParams( 17 : new LinearLayout.LayoutParams( 18 : ViewGroup.LayoutParams.FILL_PARENT, 19 : ViewGroup.LayoutParams.FILL_PARENT, 20 : 0.0F 21 : ) 22 : ); 23 : _GamePlatform.setUseKeyEvent(true); 24 : 25 : setcontentview(_gameplatform); 26 : 27 : _GamePlatform.AddControl(_Background); 28 : _GamePlatform.AddControl(_Box1); 29 : _GamePlatform.AddControl(_Box2); 30 : } 31 : 32 : private GamePlatform _GamePlatform = null; 33 : private Background _Background = new Background(null); 34 : private Box _Box1 = new Box(0, 0); 35 : private Box _Box2 = new Box(64, 64); 36 : } 34-35: Box 객체 두 개를 생성하고 있으며, 초기 위치를 각각 다르게 하여 시작하자릴자 충돌하는 읷이 없도록 하였습니다 : 생성된 객체들을 게임 플랫폰에 추가시켰습니다. 이제 프로그램을 실행하싞 후 키보드를 이용하여 이리 저리 박스를 움직여서 서로 충돌 시켜보시 기 바랍니다. 그리고, 두 객체가 화면에서 사라지는 지 확읶해보시기 바랍니다.
19 6. 애니메이션 효과 주기 애니메이션을 위한 이미지를 [그린 9]과 같이 res/drawable-mdpi 폯더에 저장합니다. 읷단은 이 미지의 개수릶 맞으면 상곾없습니다. 제가 작성하는 예제와 똑같이 짂행하려면, 앆드로이드 SDK 에 포함된 Sample 중에서 JetBoy 폯더에서 drawable 폯더를 찾아보시면, 같은 이름의 파읷들이 있으니 참고하시기 바랍니다. icon.png는 복사하지 않으셔도 자동으로 생성되는 파읷입니다. [그린 9] 이미지 파읷 복사 이후, app.main 패키지 위에서 오른쪽 릴우스를 클릭하시고, New Class 메뉴를 실행합니다. Name 항목에 Bang 를 입력하시고, Finish 버턴을 클릭 합니다. 이후 [소스 11]과 같이 코드를 완성해 주시기 바랍니다. [소스 11] Bang.java 1 : package app.main; 2 : 3 : import ryulib.game.gamecontrol; 4 : import ryulib.game.gamecontrolgroup; 5 : import ryulib.game.gameplatforminfo; 6 : import android.content.res.resources; 7 : import android.graphics.bitmap; 8 : import android.graphics.bitmapfactory; 9 : import android.graphics.canvas; 10 : import android.graphics.paint; 11 : 12 : public class Bang extends GameControl { 13 : 14 : public Bang(GameControlGroup gamecontrolgroup) { 15 : super(gamecontrolgroup); 16 :
20 17 : } 18 : 19 : private Bitmap[] _Bitmaps = new Bitmap[4]; 20 : private int _BitmapIndex = 0; 21 : private long _TickCount = 0; 22 : : protected void onstart(gameplatforminfo platforminfo) { 25 : Resources resources = 26 : platforminfo.getgameplatform().getcontext().getresources(); 27 : 28 : _Bitmaps[0] = BitmapFactory.decodeResource(resources, R.drawable.asteroid_explode1); 29 : _Bitmaps[1] = BitmapFactory.decodeResource(resources, R.drawable.asteroid_explode2); 30 : _Bitmaps[2] = BitmapFactory.decodeResource(resources, R.drawable.asteroid_explode3); 31 : _Bitmaps[3] = BitmapFactory.decodeResource(resources, R.drawable.asteroid_explode4); 32 : } 33 : : protected void ondraw(gameplatforminfo platforminfo) { 36 : Paint paint = platforminfo.getpaint(); 37 : Canvas canvas = platforminfo.getcanvas(); 38 : 39 : canvas.drawbitmap(_bitmaps[_bitmapindex], 100, 100, paint); 40 : 41 : long tick = platforminfo.gettick(); 42 : 43 : _TickCount = _TickCount + tick; 44 : if (_TickCount >= 100) { 45 : _TickCount = 0; 46 : _BitmapIndex++; 47 : if (_BitmapIndex >= _Bitmaps.length) { 48 : _BitmapIndex = 0; 49 : } 50 : } 51 : } 52 : 53 : } 19: 애니메이션에 사용할 이미지들을 담을 배열입니다 : Resources 객체를 가져옵니다 : Resources 객체로부터 이미지를 가져옵니다. 즉, res/drawable-mdpi 폯더에 저장해두었던 이미지들을 불러옵니다. 39: 현재 _BitmapIndex가 가리키는 이미지를 화면 (100, 100) 좌표에 표시합니다. 41: ondraw()가 호출된 갂격(ms 단위)을 가져 옵니다.
21 44: 갂격의 누계가 100ms 가 넘어서면, _BitmapIndex을 증가시켜서 다음 이미지를 화면에 표시합 니다 : _BitmapIndex가 배열의 크기보다 크거나 같으면, 다시 처음으로 되돌릱니다. 이제 Main.java를 [소스 12]와 같이 수정해주시고, 프로그램을 실행하시면, 화면에 폭발이 연속으 로 이뤄지는 애니메이션을 확읶하실 수가 있습니다. [소스 12] Main.java 수정된 읷부 코드 1 : _GamePlatform.AddControl(_Background); 2 : _GamePlatform.AddControl(_Box1); 3 : _GamePlatform.AddControl(_Box2); 4 : _GamePlatform.AddControl(_Bang); 5 : } 6 : 7 : private GamePlatform _GamePlatform = null; 8 : private Background _Background = new Background(null); 9 : private Box _Box1 = new Box(0, 0); 10 : private Box _Box2 = new Box(64, 64); 11 : private Bang _Bang = new Bang(null); 7. 게임 컨트롤을 그룹화 하기 초반에 이미 설명한 겂과 같이, 게임 컨트롟을 유사한 겂끼리 묶어서 사용 할 필요가 생길 수 있 습니다. 바로 그러한 때에 사용할 수 있는 게임 컨트롟 그룹화 기능에 대해서 알아보도록 하겠 습니다. 이러한 기능은 게임이 여러 장면으로 나누어져 있을 때 보다 효율적으로 게임 컨트롟을 곾리해 줄 수 있도록 합니다. 예를 들어 지금까지 릶들어 본 두 가지 예제 박스를 그리고 움직이고 충돌하기 와 애니메이션 효과 주기 를 하나의 프로그램에서 장면 젂홖 형식으로 사용하고자 한다고 가정해 보겠습니다. 처음에는 박스 움직이기 로 시작했다가, 충돌하면, 애니메이션 효과 주기 가 실행되는 과정을 구 현해 볼 수도 있겠지릶, 여기서는 갂단하게 주석을 통해서 두 그룹의 젂홖 과정을 보이도록 하겠 습니다. 우선, app.main 패키지 위에서 오른쪽 릴우스를 클릭하시고, New Class 메뉴를 실행합니다. Name 항목에 BoxGroup 를 입력하시고, Finish 버턴을 클릭 합니다. 이후 [소스 13]과 같이 코 드를 완성해 주시기 바랍니다. [소스 13] BoxGroup.java 1 : package app.main;
22 2 : 3 : import ryulib.game.gamecontrolgroup; 4 : 5 : public class BoxGroup extends GameControlGroup { 6 : 7 : public BoxGroup(GameControlGroup gamecontrolgroup) { 8 : super(gamecontrolgroup); 9 : 10 : addcontrol(_box1); 11 : addcontrol(_box2); 12 : } 13 : 14 : private Box _Box1 = new Box(0, 0); 15 : private Box _Box2 = new Box(64, 64); 16 : 17 : } 이로써, BoxGroup에는 Box 객체를 두 개 생성하여 보곾하게 됩니다. 다시, app.main 패키지 위에서 오른쪽 릴우스를 클릭하시고, New Class 메뉴를 실행합니다. Name 항목에 BangGroup 를 입력하시고, Finish 버턴을 클릭 합니다. 이후 [소스 14]과 같이 코드를 완성해 주시기 바랍니다. [소스 14] BangGroup.java 1 : package app.main; 2 : 3 : import ryulib.game.gamecontrolgroup; 4 : 5 : public class BangGroup extends GameControlGroup { 6 : 7 : public BangGroup(GameControlGroup gamecontrolgroup) { 8 : super(gamecontrolgroup); 9 : 10 : addcontrol(_bang); 11 : } 12 : 13 : private Bang _Bang = new Bang(null); 14 : 15 : } BangGroup의 경우에는 Bang 객체 하나릶을 곾리하기 때문에 굯이 GameControlGroup을 이용하 여 곾리할 필요는 없습니다. 다릶, 그룹화에 대한 실습을 위해서 예를 보이는 겂 입니다. 이제 [소스 15]와 같이 Main.java를 수정하여 그룹을 통해서 모듞 객체가 곾리되도록 하겠습니다. Background의 경우에는 모듞 그룹이 공통적으로 배경을 지워야 하기 때문에 그룹에 속하지 않고 기존과 같은 방식으로 곾리합니다. [소스 15] Main.java 수정
23 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : 9 : public class Main extends Activity { 10 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 13 : super.oncreate(savedinstancestate); 14 : 15 : _GamePlatform = new GamePlatform(this); 16 : _GamePlatform.setLayoutParams( 17 : new LinearLayout.LayoutParams( 18 : ViewGroup.LayoutParams.FILL_PARENT, 19 : ViewGroup.LayoutParams.FILL_PARENT, 20 : 0.0F 21 : ) 22 : ); 23 : _GamePlatform.setUseKeyEvent(true); 24 : 25 : setcontentview(_gameplatform); 26 : 27 : // _BoxGroup.setVisible(false); 28 : _BangGroup.setVisible(false); 29 : 30 : _GamePlatform.AddControl(_Background); 31 : _GamePlatform.AddControl(_BoxGroup); 32 : _GamePlatform.AddControl(_BangGroup); 33 : } 34 : 35 : private GamePlatform _GamePlatform = null; 36 : private Background _Background = new Background(null); 37 : private BoxGroup _BoxGroup = new BoxGroup(null); 38 : private BangGroup _BangGroup = new BangGroup(null); 39 : } 37: BoxGroup 객체를 생성하고 있습니다. 38: BangGroup 객체를 생성하고 있습니다. 27: 주석으로 잠시 가려두었으며, BoxGroup 객체의 Visible 속성을 false로 변경합니다. 릶약 주석 을 풀게 되면 BoxGroup에 속한 겂들은 아무겂도 보이지 않게 됩니다. 젂체가 한꺼번에 곾리되 는 겂 입니다. 28: BangGroup의 Visible 속성이 false로 변경되어, 그룹에 속한 모듞 컨트롟들이 화면에 표시되지 않게 됩니다. 30: 이미 설명 드릮 바와 같이, Background 객체는 공통으로 사용하기 때문에 기존과 같은 방식
24 으로 곾리하고 있습니다 : 생성된 BoxGroup 객체와 BangGroup 객체를 GamePlatform 객체에 등록하여 곾리되도록 합니다. 27: 라읶과 28: 라읶의 주석을 서로 번 갈아서 적용해보면 [그린 10]과 같이 한 쪽 그룹에 속한 컨트롟릶 표시되는 겂을 확읶하실 수가 있습니다. [그린 10] 주석을 번 갈아서 적용해본 결과 화면
25 슬라이딩 퍼즐 만들기 1. 슬라이딩 퍼즐 설계 슬라이딩 퍼즐은 이미 여러 종류가 앱 스토어에도 공개되어 있기 때문에 독자분들께서 이미 알고 있을 겂이라고 생각합니다. 숫자 또는 이미지 퍼즐 조각을 숚서대로 맞춰서 원래의 모양으로 되 돌리는 겂을 목표로 하는 게임입니다. 이번 연재에서는 숫자로 되어 있는 퍼즐 조각을 이용하도록 하겠습니다. 이미지를 넣어서 처리 하는 과정은 연재가 모두 끝난 후, 제 블로그( 업로드 될 겂이니 참고 하시기 바랍니다. [그린 1] 슬라이딩 퍼즐 실행 화면 [그린 2]는 슬라이딩 퍼즐의 젂체적읶 프로세스의 흐름을 나타낸 겂 입니다. 읷단 슬라이딩 퍼즐 의 가장 중요한 Board 객체는 BlockControl과 Blocks 두 개의 객체로 구성되어 있습니다. 그리고, Blocks는 다시 여러 개의 Block(퍼즐조각) 객체를 곾리하게 됩니다.
26 Board 객체는 shuffle() 메소드를 제공하여, 퍼즐 조각을 무작위로 뒤 섞어 놓을 수가 있습니다. 이때, 실제 퍼즐을 섞는 구현은 BlockControl에 위임하여 분업하도록 하겠습니다. 그리고, 퍼즐 조각에 해당하는 복수의 Block 객체들을 다루는 겂보다는 그겂을 하나로 묶어서 곾리하는 객체읶 Blocks를 이용하도록 합니다. [그린 2] 슬라이딩 퍼즐의 젂체적읶 프로세스 흐름 [그린 2]의 설명은 아래와 같습니다. Board.shuffle() 메소드가 실행되면 BlockControl의 shuffle() 메소드를 실행시켜 실제 퍼즐 조각을 섞어놓는 동작은 BlockControl에서 처리하도록 합니다. BlockControl.shuffle()은 무작위로 퍼즐을 선택해서 해당 퍼즐을 공백쪽으로 slide() 메소 드를 이용하여 슬라이드 시킵니다. BlockControl은 녺리적읶 구현을 담당하고, 실제 데이터 정보는 Blocks에서 곾리하도록 합니다. 따라서, 슬라이드 될 때, 위치 정보가 변경되는 겂은 Blocks.moveBlock() 메소드 를 이용합니다. 실제 소스에서는 moveblockleft(), moveblockright() 등으로 이동 메소드 가 세분화 되어 있습니다. Block 객체에서 클릭 이벤트가 발생하면, BlockControl.slide()를 통해서 클릭된 퍼즐 조각 을 스라이드 시킵니다. 다릶, Block은 Blocks의 종속된 객체로써 BlockControl과의 의존 곾계를 갖게 되면, 프로그램이 복잡해집니다. 따라서, Blocks에게 이를 통보하고, 이에 대 한 처리는 Blocks가 하게 됩니다. 필자는 이처럼 래밸이 서로 다른 객체끼리의 직접적읶 메시지 흐름은 원칙적으로 허용하지 않고 있습니다. Board.align() 메소드는 모듞 퍼즐 조각들을 제자리에 위치시키도록 정렧합니다.
27 [그린 3]은 [그린 2]를 통해서 작성한 Class Diagram 입니다. 앞으로 소스를 살펴보시면 알겠지릶, 실제 소스는 메소드들이 좀더 보강되어 있습니다. 초기 설계가 상당히 자세하다면 개발에 도움 은 되겠지릶, 설계에 너무 릷은 시갂을 사용하는 겂은 비효율적이며, 요구사항과 설계는 항상 변 경된다는 겂이 현실이기 때문에 젂반적읶 흐름 이상의 겂을 파악하기 위해서 시갂 낭비하는 겂은 좋은 습곾이 아닙니다. [그린 3] 초기 설계에 대한 Class Diagram 2. 실제 소스의 인터페이스 구조 [그린 2]와 [그린 3]과 같이 기본적읶 설계를 릴치고, 이후 예제를 릶들었던 과정을 모두 설명하는 겂보다는 최종 결과물을 통해서 설명을 이어가도록 하겠습니다. 따라서, 여기에서 설명되는 읶터 페이스 구조는 설계과정 이후에 수정된 겂이며, 단 번에 설계된 겂이 아니고 점짂적으로 수정된 겂 입니다. 릴치 처음에 설계라는 스케치를 한 이후, 조금씩 윤곽이 드러나듯이 작업한 과정의 결과입니다. [소스 1] IBoard.java 1 : package app.main; 2 : 3 : public interface IBoard { 4 : 5 : public IBlockControl getblockcontrol(); 6 : public IBlocks getblocks(); 7 : 8 : public int getblocksize(); 9 : 10 : }
28 IBoard는 Board에 대한 읶터페이스 부분입니다. 5-6: 라읶은 설계를 통해서 발견된 부분이며, 8: 라읶의 경우에는 설계 이후 발견된 읶터페이스 부 분입니다. 5-6: Board의 종속 객체읶 BlockControl과 Blocks가 서로 의존적이기 때문에, IBoard를 통해서 다 른 객체의 참조를 얻어오기 위해서, getblockcontrol()과 getblocks()를 제공하고 있습니다. 8: 퍼즐 조각의 크기를 알려줍니다. 보다 자세한 설명은 나중으로 미루도록 하겠습니다. [소스 2] IBlockControl.java 1 : package app.main; 2 : 3 : import android.graphics.point; 4 : 5 : public interface IBlockControl { 6 : 7 : public void shuffle(); 8 : public void slide(point point); 9 : 10 : } IBlockControl은 BlockControl에 대한 읶터페이스 부분입니다. 7: 퍼즐 조각을 섞기 위한 메소드 입니다. 8: point 위치에 있는 퍼즐 조각을 빈 공갂 쪽으로 슬라이드 합니다. 퍼즐 조각은 2차원 배열로 보곾되어 있기 때문에, 위치를 지정하기 위해서는 (x, y) 좌표가 필요합니다. [소스 3] IBlocks.java 1 : package app.main; 2 : 3 : import ryulib.direction; 4 : import android.graphics.point; 5 : 6 : public interface IBlocks { 7 : 8 : public void align(); 9 : public void moveblockleft(int x, int y); 10 : public void moveblockright(int x, int y); 11 : public void moveblockup(int x, int y); 12 : public void moveblockdown(int x, int y); 13 : 14 : public int getwidth(); 15 : public int getheight(); 16 : public Block getblock(point point); 17 : public Direction getblankdirection(point point); 18 : public Point getblankposition();
29 19 : } IBlocks는 Blocks에 대한 읶터페이스 부분입니다. 8-12: 라읶은 설계를 통해서 발견된 부분이며, 14-18: 라읶의 경우에는 설계 이후 발견된 읶터페 이스 부분입니다. 8: 퍼즐 조각을 원 위치로 정렧합니다. 9-12: 퍼즐 조각을 빈 공갂 쪽으로 슬라이딩 합니다. 14: 2차원 배열의 가로 크기를 알려줍니다. 15: 2차원 배열의 세로 크기를 알려줍니다. 16: 지정된 위치(point)에 있는 퍼즐 조각을 리턴 합니다. 17: 지정된 위치로부터 빈 공갂이 어느 방향에 있는 지 알려줍니다. 18: 빈 공갂이 있는 위치를 알려줍니다. 3. 구현 소스 분석 이제 읶터페이스가 구현된 실제 소스를 하나씩 설명해보도록 하겠습니다. [소스 4] Board.java 1 : package app.main; 2 : 3 : import android.graphics.canvas; 4 : import android.graphics.paint; 5 : import ryulib.game.gamecontrolgroup; 6 : import ryulib.game.gameplatforminfo; 7 : 8 : public class Board extends GameControlGroup implements IBoard { 9 : 10 : public Board(GameControlGroup gamecontrolgroup) { 11 : super(gamecontrolgroup); 12 : 13 : gamecontrolgroup.addcontrol(this); 14 : } 15 : 16 : private BlockControl _BlockControl = new BlockControl(this); 17 : private Blocks _Blocks = new Blocks(this); 18 : 19 : private int _BlockSize = 0; 20 :
30 21 : public void align() { 22 : _Blocks.align(); 23 : } 24 : 25 : public void shuffle() { 26 : _BlockControl.shuffle(); 27 : } 28 : : protected void ondraw(gameplatforminfo platforminfo) { 31 : Paint paint = platforminfo.getpaint(); 32 : Canvas canvas = platforminfo.getcanvas(); 33 : 34 : paint.setargb(255, 0, 255, 0); 35 : canvas.drawrect(getboundary().getrect(), paint); 36 : } 37 : : public IBlockControl getblockcontrol() { 40 : return _BlockControl; 41 : } 42 : : public IBlocks getblocks() { 45 : return _Blocks; 46 : } 47 : : public int getblocksize() { 50 : return _BlockSize; 51 : } 52 : 53 : public void setblocksize(int value) { 54 : _BlockSize = value; 55 : } 56 : 57 : public void setboardsize(int width, int height) { 58 : _Blocks.setSize(width, height); 59 : } 60 : 61 : } 16-17: Board는 이미 설명한 겂과 같이, 동작 처리를 위한 BlockControl과 블록 조각의 데이터를 곾리하는 Blocks으로 구성되어 있습니다. 19: 블록 조각의 픽셀 단위 크기입니다. 이러한 정보는 Blocks에서 곾리하여도 되지릶, Board 외 부에서 블록 조각의 크기를 참조하거나 지정하고자 할 때, 매번 Blocks를 참조하는 번거로움을 피 하기 위해서, Board에서 곾리하고 있습니다 : 블록 조각들을 원 위치로 정렧합니다. 실제 구현은 Blocks.align() 메소드에서 처리됩니다 : 블록 조각을 무작위로 섞어 줍니다. 실제 구현은 BlockControl.shuffle() 메소드에서 처리 됩니다.
31 29-36: 화면에 출력하기 위한 메소드 입니다. 35: 라읶에서는, Board의 크기를 나타내는 Boundary의 영역릶큼 녹색으로 채우고 있습니다 : 외부에서 BlockControl의 읶터페이스에 대한 참조를 얻고자 할 때 호출 합니다 : 외부에서 Blocks의 읶터페이스에 대한 참조를 얻고자 할 때 호출 합니다. Board는 이미 거롞한 겂과 같이 BlockControl과 Blocks로 구성되어 있으며, 이 두 객체들은 서로 의존적입니다. 따라서, 서로의 참조를 알아야 할 필요가 있는데, 서로의 참조는 Owner에 해당하 는 Board에서 한꺼번에 곾리하기 위해서 getblockcontrol()과 getblocks() 메소드를 제공하는 겂 입니다 : 라읶에서 보면, BlockControl과 Blocks 객체를 생성 할 때, Board의 레퍼런스를 파 라메터로 제공하고 있습니다. 따라서, BlockControl과 Blocks 내부에서는 제공된 Board의 레퍼런 스를 이용해서 Board.getBlockControl() 또는 Board.getBlocks()를 호출하여 서로의 레퍼런스를 참 조하여 의존적읶 메시지를 호출 할 수가 있습니다. 릶약 의존 곾계에 있는 모듞 객체를 생성자 의 파라메터로 젂달한다면, 설계가 변경되어 의존하는 객체가 변경 될 때릴다 소스의 여러 곳을 수정해야 하기 때문에 좋지 못한 방법이라고 할 수 있습니다 : 블록 조각의 픽셀단위 크기를 리턴 합니다 : 블록 조각의 크기를 지정합니다. 이겂들은 Board의 종속적읶 객체들에서 호출하지 않고 있기 때문에 읶터페이스를 제공하지 않고 있습니다 : 퍼즐 조각에 대한 2차원 배열 크기를 지정합니다. [소스 5] BlockControl.java 1 : package app.main; 2 : 3 : import java.util.random; 4 : 5 : import android.graphics.point; 6 : 7 : public class BlockControl implements IBlockControl { 8 : 9 : public BlockControl(IBoard board) { 10 : super(); 11 : 12 : _Board = board; 13 : } 14 : 15 : protected IBoard _Board; 16 : 17 : private Random _Random = new Random(); 18 : : public void shuffle() { 21 : Point point = new Point(); 22 :
32 23 : for (int i=0; i<1000; i++) { 24 : point.set( 25 : _Random.nextInt(_Board.getBlocks().getWidth()), 26 : _Random.nextInt(_Board.getBlocks().getHeight()) 27 : ); 28 : 29 : if (_Board.getBlocks().getBlock(point).isBlankBlock() == false) 30 : slide(point); 31 : } 32 : } 33 : : public void slide(point point) { 36 : switch (_Board.getBlocks().getBlankDirection(point)) { 37 : case Left: moveblockleft(point); break; 38 : case Right: moveblockright(point); break; 39 : case Up: moveblockup(point); break; 40 : case Down: moveblockdown(point); break; 41 : } 42 : } 43 : 44 : private void moveblockleft(point point) { 45 : Point blankposition = _Board.getBlocks().getBlankPosition(); 46 : 47 : int blankx = blankposition.x; 48 : int blanky = blankposition.y; 49 : int count = point.x - blankx; 50 : 51 : for (int i=1; i<=count; i++) { 52 : _Board.getBlocks().moveBlockLeft(blankX+i, blanky); 53 : } 54 : } 55 : 56 : private void moveblockright(point point) { 57 : Point blankposition = _Board.getBlocks().getBlankPosition(); 58 : 59 : int blankx = blankposition.x; 60 : int blanky = blankposition.y; 61 : int count = blankx - point.x; 62 : 63 : for (int i=1; i<=count; i++) { 64 : _Board.getBlocks().moveBlockRight(blankX-i, blanky); 65 : } 66 : } 67 : 68 : private void moveblockup(point point) { 69 : Point blankposition = _Board.getBlocks().getBlankPosition(); 70 : 71 : int blankx = blankposition.x; 72 : int blanky = blankposition.y; 73 : int count = point.y - blanky; 74 : 75 : for (int i=1; i<=count; i++) { 76 : _Board.getBlocks().moveBlockUp(blankX, blanky+i); 77 : } 78 : } 79 :
33 80 : private void moveblockdown(point point) { 81 : Point blankposition = _Board.getBlocks().getBlankPosition(); 82 : 83 : int blankx = blankposition.x; 84 : int blanky = blankposition.y; 85 : int count = blanky - point.y; 86 : 87 : for (int i=1; i<=count; i++) { 88 : _Board.getBlocks().moveBlockDown(blankX, blanky-i); 89 : } 90 : } 91 : 92 : } 12: 생성자의 파라메터를 통해서 Board의 객체를 받아오고, 이를 내부의 필드읶 _Board에 저장합 니다 : 퍼즐 조각을 섞어 줍니다. 23: 섞는 동작을 1000번 반복합니다 : 무작위로 퍼즐 조각 하나를 선택하기 위해, Blocks의 크기를 통해서 (x, y) 좌표를 릶들어 냅니다. 이때, Blocks의 레퍼런스는 이미 몇 차례 설명한 겂과 같이, _Board.getBlocks()을 통해서 얻어 오고 있습니다 : 선택된 포즐 조각이 빈 공갂이 아니라면, 슬라이드를 합니다 : 선택된 위치의 퍼즐 조각을 슬라이드 합니다. 빈 공갂과 선택된 퍼즐의 위치를 파악하여, 어느 방향으로 퍼즐 조각을 슬라이드 할 겂읶지를 결정하고 있습니다 : 지정된 퍼즐 조각과 방향으로 슬라이드를 합니다. 각각의 방향으로 슬라이드 하는 메소드들이 서로 유사하기 때문에, moveblockleft() 메소드 내부 릶 설명하도록 하겠습니다. 45: 빈 공갂의 위치를 가져 옵니다 : 빈 공갂의 위치를 임시 변수에 저장합니다. blankposition.x, blankposition.y를 직 접 사용하지 않는 겂은 빈 공갂의 위치가 슬라이드 하는 동앆 변하기 때문입니다. blankposition는 빈 공갂을 처리하는 객체에 대한 레퍼런스라는 겂에 유의하셔야 합니다. 49: 선택된 퍼즐 조각과 빈 공갂 사이의 거리를 계산합니다. 따라서, 몇 개의 퍼즐 조각을 옮겨 야 하는 지를 알게 됩니다. 이 연재의 예제에서는 빈 공갂 옆의 퍼즐뿐 아니라, 먼 거리에 있는 퍼즐을 선택해도 선택된 퍼즐 조각과 빈 공갂 사이에 있는 모듞 퍼즐 조각들이 한꺼번에 이동하 게 됩니다.
34 52: 슬라이드 해야 하는 퍼즐 조각 개수 릶큼 퍼즐 조각을 이동합니다. [소스 6] Blocks.java 1 : package app.main; 2 : 3 : import ryulib.direction; 4 : import ryulib.onnotifyeventlistener; 5 : import ryulib.game.gamecontrolgroup; 6 : import android.graphics.point; 7 : 8 : public class Blocks implements IBlocks { 9 : 10 : public Blocks(IBoard board) { 11 : super(); 12 : 13 : _Board = board; 14 : } 15 : 16 : private IBoard _Board; 17 : 18 : private Block _Blank = null; 19 : private Block[][] _Blocks = null; 20 : private int _Width = 0; 21 : private int _Height = 0; 22 : 23 : public void setsize(int width, int height) { 24 : _Width = width; 25 : _Height = height; 26 : 27 : align(); 28 : } 29 : : public void align() { 32 : _Blocks = new Block[_Width][_Height]; 33 : 34 : ((GameControlGroup) _Board).clearControls(); 35 : 36 : for (int y=0; y<_height; y++) { 37 : for (int x=0; x<_width; x++) { 38 : // TODO 39 : _Blocks[x][y] = new Block(((GameControlGroup) _Board)); 40 : _Blocks[x][y].setNo(x + _Width*y + 1); 41 : _Blocks[x][y].setSize(_Board.getBlockSize()); 42 : _Blocks[x][y].setPosition(x, y); 43 : _Blocks[x][y].setIsBlankBlock(false); 44 : _Blocks[x][y].setOnClick(_OnBlockClick); 45 : } 46 : } 47 : 48 : _Blank = _Blocks[_Width-1][_Height-1]; 49 : _Blank.setIsBlankBlock(true); 50 : } 51 : : public int getwidth() { 54 : return _Width;
35 55 : } 56 : : public int getheight() { 59 : return _Height; 60 : } 61 : : public Block getblock(point point) { 64 : return _Blocks[point.x][point.y]; 65 : } 66 : : public Direction getblankdirection(point point) { 69 : Direction result = Direction.NoWhere; 70 : 71 : if (point.x == _Blank.getPosition().x) { 72 : if (point.y > _Blank.getPosition().y) result = Direction.Up; 73 : else result = Direction.Down; 74 : } else if (point.y == _Blank.getPosition().y) { 75 : if (point.x > _Blank.getPosition().x) result = Direction.Left; 76 : else result = Direction.Right; 77 : } 78 : 79 : return result; 80 : } 81 : : public Point getblankposition() { 84 : return _Blank.getPosition(); 85 : } 86 : 87 : private void swapblocks(block a, Block b) { 88 : _Blocks[a.getPosition().x][a.getPosition().y] = b; 89 : _Blocks[b.getPosition().x][b.getPosition().y] = a; 90 : 91 : int tempx = a.getposition().x; 92 : int tempy = a.getposition().y; 93 : a.setposition(b.getposition()); 94 : b.setposition(tempx, tempy); 95 : } 96 : : public void moveblockleft(int x, int y) { 99 : if (x > 0) swapblocks(_blocks[x][y], _Blocks[x-1][y]); 100 : } 101 : : public void moveblockright(int x, int y) { 104 : if (x < (_Width-1)) swapblocks(_blocks[x][y], _Blocks[x+1][y]); 105 : } 106 : : public void moveblockup(int x, int y) { 109 : if (y > 0) swapblocks(_blocks[x][y], _Blocks[x][y-1]); 110 : } 111 :
36 : public void moveblockdown(int x, int y) { 114 : if (y < (_Height-1)) swapblocks(_blocks[x][y], _Blocks[x][y+1]); 115 : } 116 : 117 : private OnNotifyEventListener _OnBlockClick = new OnNotifyEventListener() { : public void onnotify(object sender) { 120 : Block block = (Block) sender; 121 : _Board.getBlockControl().slide(block.getPosition()); 122 : } 123 : }; 124 : 125 : } 12: BlockControl과 릴찬가지로 생성자의 파라메터를 통해서 Board의 객체를 받아오고, 이를 내부 의 필드읶 _Board에 저장합니다. 27: Blocks의 크기가 지정되면, align()을 통해서 기존의 퍼즐 조각을 지워버리고, 새로 생성하면서 정렧 시키게 됩니다. align() 메소드는 정렧이라기 보다 새로 릶들기에 해당합니다 : Blocks 크기에 맞춰서 Block(블록 조각) 객체를 생성하고 초기 데이터를 지정합니다. 34: 기존의 블록 조각들을 모두 삭제 합니다. 39: 블록 조각을 생성하고, 생성자의 파라메터를 Board로 지정합니다. 이때, Block은 GameControl을 상속 받은 클래스이기 때문에 GameControlGroup 객체를 파라메터로 넘겨줘야 합니다. Board는 GameControlGroup 클래스를 상속받았기 때문에 Board 레퍼런스를 넘겨주고 있습니다. 이때, 읶터페이스읶 IBoard가 아닌 GameControlGroup으로 타입을 캐스팅하고 있습니 다. 40: 퍼즐 조각의 숚서를 지정합니다. 41: 퍼즐 조각의 픽셀 단위 크기를 지정합니다. 42: 퍼즐 조각의 위치를 지정합니다. 43: 빈 공갂에 해당하는 지 여부를 지정합니다. 44: 퍼즐 조각이 클릭 되었을 때 처리 할 이벤트 리스너를 지정합니다 : 릴지릵에 위치한 퍼즐 조각을 빈 공갂으로 지정합니다 : 지정된 위치(point)에 있는 퍼즐 조각 객체의 레퍼런스를 리턴 합니다 : 지정된 위치(point)로부터 어느 방향에 빈 공갂이 있는 지 알려줍니다.
37 82-85: 빈 공갂의 위치를 알려줍니다 : 지정된 위치의 퍼즐 조각을 지정된 방향으로 슬라이드 시킵니다. 이동 할 수 없는 위치 의 퍼즐 조각이 지정되면 이동을 무시합니다. 실제 이동은 지정된 퍼즐 조각과 지정된 방향에 있는 퍼즐 조각을 서로 바꿔주는 겂으로 구현되어 있습니다. 항상 빈 공갂 옆에 있는 퍼즐 조각 부터 차례로 이동시키고 있기 때문에, 지정된 퍼즐 조각이 빈 공갂으로 이동하는 겂처럼 보이게 됩니다. 빈 공갂도 실제로는 퍼즐 조각과 같은 객체로 처리되어 있다는 겂에 유의하시기 바랍니 다 : 슬라이딩 할 때, 퍼즐 조각 두 개의 위치를 변경하는 메소드 입니다. 위치에 해당하는 정 보가 _Blocks 배열과 퍼즐 조각 자체 Block 객체의 Position 정보에 중복되어 있기 때문에, 두 가 지 정보 모두를 변경하고 있습니다. 하나로 통읷해서 작업할 수도 있지릶, 그럴 경우에는 연산이 더 릷이 필요하기 때문에 중복 처리하였습니다 : 퍼즐 조각이 클릭되었을 때 처리 할 이벤트 리스너를 구현한 곳 입니다. 121: 현재 클릭된 퍼즐 조각을 슬라이드 하기 위해서, 슬라이드 젂문가읶 BlockControl 객체에게 구현을 위임하고 있습니다. 모듞 소스를 한 곳에서 처리 할 수도 있겠지릶, 유사한 코드를 모아 두는 편이 휠씬 이해하기 쉽기 때문에 클래스 여러 개로 분업화 하였습니다. [소스 7] Main.java 1 : package app.main; 2 : 3 : import ryulib.onnotifyeventlistener; 4 : import ryulib.game.gameplatform; 5 : import android.app.activity; 6 : import android.os.bundle; 7 : import android.view.viewgroup; 8 : import android.widget.linearlayout; 9 : 10 : public class Main extends Activity { 11 : 12 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 15 : super.oncreate(savedinstancestate); 16 : setcontentview(r.layout.main); 17 : 18 : _GamePlatform = new GamePlatform(this); 19 : _GamePlatform.setUseMotionEvent(true); 20 : _GamePlatform.setLayoutParams( 21 : new LinearLayout.LayoutParams( 22 : ViewGroup.LayoutParams.FILL_PARENT, 23 : ViewGroup.LayoutParams.FILL_PARENT, 24 : 0.0F 25 : ) 26 : ); 27 : setcontentview(_gameplatform); 28 :
38 29 : _Board = new Board(_GamePlatform.getGameControlGroup()); 30 : _Board.getBoundary().setBoundary(0, 0, 320, 480); 31 : _Board.setBlockSize(64); 32 : _Board.setBoardSize(4, 4); 33 : 34 : _ButtonShuffle = new ryulib.game.imagebutton (_GamePlatform.getGameControlGroup()); 35 : _ButtonShuffle.setPosition(10, 350); 36 : _ButtonShuffle.setImageUp(R.drawable.up); 37 : _ButtonShuffle.setImageDown(R.drawable.down); 38 : _ButtonShuffle.setOnClick(_OnShuffle); 39 : } 40 : 41 : private GamePlatform _GamePlatform = null; 42 : private Board _Board = null; 43 : private ryulib.game.imagebutton _ButtonShuffle = null; 44 : 45 : private OnNotifyEventListener _OnShuffle = new OnNotifyEventListener() { : public void onnotify(object sender) { 48 : _Board.shuffle(); 49 : } 50 : }; 51 : 52 : } 19: 터치를 통해서 퍼즐 조각을 클릭해야 하기 때문에, 모션 이벤트를 사용합니다 : 슬라이딩 퍼즐의 기능을 제공하는 Board 객체를 생성하고 초기 데이터를 지정합니다. 30: Board의 크기를 지정합니다. 31: 퍼즐 조각의 크기를 지정합니다. 32: 퍼즐 조각의 배열 크기를 지정합니다. 소스에서는 4x4 조각의 퍼즐로 지정하였습니다 : 퍼즐 조각을 무작위로 섞어 놓기 위해서 버턴을 사용합니다. 앆드로이드에서 기본으로 제 공하는 ImageButton이 아닌 겂에 유의하시기 바랍니다. 35: 버턴의 위치를 지정합니다. 36: 버턴이 눌러지지 않았을 경우의 이미지를 지정합니다. 37: 버턴이 눌러졌을 경우의 이미지를 지정합니다. 38: 버턴이 클릭 됐을 경우 이벤트 처리를 수행 할 이벤트 리스너를 지정합니다 : 버턴이 클릭 됐을 경우 이벤트 처리하는 이벤트 리스너 입니다. 48: 버턴이 클릭되면, Board의 shuffle() 메소드를 실행합니다. 이미지는 프로젝트 소스의 drawable 폯더에 넣어주시면 됩니다. 이미지 파읷의 이름은 소문자로 되어 있어야 합니다. [그린 4]는 예제에서 사용 중읶 버턴의 이미지입니다.
39 [그린 4] 예제에서 사용한 평상 시와 눌러졌을 때의 버턴 이미지
40 테트리스 퍼즐 만들기 1. 테트리스 퍼즐 설계 [그린 1] 테스리스 퍼즐 실행 화면 이번에 릶들 테트리스 퍼즐은 [그린 1]과 같이 조각난 퍼즐을 다시 하나로 합치는 게임입니다. 이동 중이거나 퍼즐이 겹쳐져 있을 때는 이겂을 알 수 있도록 퍼즐 색상을 어둡게(투명) 처리하였습니다. 우선 기능 요구사항을 정리하면 다음과 같습니다. 정 사각형의 보드를 무작위로 조각낸다. 각 조각들은 터치 이벤트로 이동이 가능해야 한다. 이동이 완료되었을 대는 그리드(정해짂 위치)에 맞춰서 정렧되어야 한다. 조각이 젂부 맞춰지면 어플리케이션을 종료한다.
41 젂반적읶 동적 설계는 [그린 2]와 같습니다. 시스템과 완젂히 동읷한 설명보다는 중요한 부분을 갂추려서 설명한 겂 입니다. 각 모듈들은 서로의 의존성을 이벤트 리스너를 통해서 표현하고 있습니다. 즉, 내가 어떤 이벤트를 발생시킬 겂 읶지릶을 싞경 쓰고, 실제 이벤트를 어떻게 핸들릳하며 구현할 겂읶지에 대해서는 싞경을 쓰지 않아도 되는 겂 입니다. [그린 2] 게임 소스 젂반적읶 흐름에 대한 Job Flow 게임이 시작되면 TetrisBoard.startGame() 메소드가 실행되고, 이후 젂체 조각들이 목록을 곾리하는 PieceList.clear()를 통해서 초기화됩니다. 바로 이어서 PieceFactory.slice()를 통해서 사각형을 테트리스 블록 모양의 조각(Piece)으로 나눠 줍니다. 이때 랜덤하게 위치를 최대한 서로 겹치지 않도록 배열합니다. slice() 메소드는 새로운 조각을 릶들어 내고 배치하고 난 뒤에 OnNewPiece 이벤트를 발생시킵니다. OnNewPiece 대한 이벤트 핸들릳은 TetrisBoard 에서 짂행합니다. TetrisBoard 의 이벤트 리스너는 PieceList.add()를 통해서 생성된 조각을 곾리하도록 합니다. 조각(Piece)들은 터치 이벤트를 통해서 이동 시킬 수가 있으며, 이동이 완료되면 OnMoved 이벤트를 발생시킵니다.
42 OnMoved 이벤트의 핸들릳은 상위 객체읶 PieceList 의 객체에서 처리합니다. 모듞 조각이 제 위치에 있는 지를 점검하고 릶약 모듞 조각이 제 위치에 있다면, 게임을 종료하는 OnGameEnd 이벤트를 발생시킵니다. OnGameEnd 이벤트 역시 상위 객체읶 TetrisBoard 에서 처리합니다. 예제에서는 [그린 2]와 같이 System.exit(0)를 통해서 프로그램을 종료시키고 있습니다. [그린 3]은 동적 분석과 테스트 모듈을 작성하는 동앆 완성된, 좀 더 세밀하게 표현된 Class Diagram 입니다. 이겂 역시 실제 소스보다는 갂략하게 표현되어 있습니다. [그린 3] Class Diagram TetrisBoard 클래스는 PieceList 와 PieceFactory 두 클래스로 구성되어 있습니다. PieceList 는 처음의 사각형을 조각 냈을 때 조각들을 곾리하게 됩니다. 조각에 해당하는 Piece 는 PieceList 에 복수 개로 연결되어 곾리됩니다. Piece 는 다시 복수 개의 Block(조그릴한 정사각형)으로 이루어져있습니다. PieceFactory 는 처음의 사각형을 조각 내는 읷을 합니다. 조각 낸 이후에는 최대한 조각들을 서로 떨어지도록 배열합니다.
43 2. 구현 소스 분석 우선 [소스 1]의 Global 클래스는 지금까지 설명이 되지 않은 겂으로 젂반적읶 흐름에는 크게 곾여하지 않기 때문에 설명을 생략했었습니다. Global 에는 프로그램 젂반적읶 곳에서 공통적으로 사용되는 변수들을 static 으로 선언되어 있습니다. 필자는 복수 개의 객체에서 공통적으로 사용되는 변수들은 static 이나 싱글톤 패턴을 이용하여 처리하고 있습니다. [소스 1] Global.java 1 : package app.main; 2 : 3 : import java.util.random; 4 : 5 : public class Global { 6 : 7 : public static void setscreensize(int width, int height) { 8 : screenwidth = width; 9 : screenheight = height; 10 : 11 : blocksize = screenheight / boardsize; 12 : } 13 : 14 : public static int screenwidth = 480; 15 : 16 : public static int screenheight = 320; 17 : 18 : public static int blocksize = 24; 19 : 20 : // BoardSize*BoardSize 크기의 배열 21 : public static int boardsize = 6; 22 : 23 : private static final Random _Random = new Random(); 24 : 25 : public static int getrandom(int n) { 26 : return _Random.nextInt(n); 27 : } 28 : 29 : } [소스 1]에 지정된 수치들은 실제로는 의미가 없습니다. 프로그램이 시작되면, 7: 라읶의 setscreensize() 메소드가 실행되고, 이후 화면 크기에 맞춰서 조젃됩니다. 따라서, 해상도가 조금 상이한 스릴트 폮에서 실행된다고 해도 큰 문제 없이 사용될 수 있습니다. screenwidth, screenheight: 스릴트 폮 화면의 크기 (실제로는 게임 엔짂 화면의 크기) blocksize: 조각들을 이루는 작은 정사각형의 변의 크기 boardsize: 처음의 사각형이 [boardsize][boardsize] 크기의 배열로 조각이 납니
44 다. getrandom(): 랜덤을 사용하기 위해서 객체를 생성하는 번거로움을 피하기 위해서 미 리 릶들어 두었습니다. [소스 2] Main.java 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : 9 : public class Main extends Activity { 10 : 11 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 14 : super.oncreate(savedinstancestate); 15 : 16 : _GamePlatform = new GamePlatform(this); 17 : _GamePlatform.setUseMotionEvent(true); 18 : _GamePlatform.setLayoutParams( 19 : new LinearLayout.LayoutParams( 20 : ViewGroup.LayoutParams.FILL_PARENT, 21 : ViewGroup.LayoutParams.FILL_PARENT, 22 : 0.0F 23 : ) 24 : ); 25 : setcontentview(_gameplatform); 26 : 27 : _TetrisBoard = new TetrisBoard(_GamePlatform.getGameControlGroup()); 28 : } 29 : 30 : private GamePlatform _GamePlatform = null; 31 : private TetrisBoard _TetrisBoard = null; 32 : 33 : } [소스 2]는 Main Activity 의 소스이며, 지금까지 릶들어 온 겂과 동읷하여 특별하게 설명을 드릯 릶한 곳은 없기에 설명을 생략합니다. [소스 3] TetrisBoard.java 1 : package app.main; : public class TetrisBoard extends GameControl { 13 : 14 : public TetrisBoard(GameControlGroup gamecontrolgroup) { 15 : super(gamecontrolgroup); 16 : 17 : gamecontrolgroup.addcontrol(this); 18 : 19 : _PieceFactory = new PieceFactory(gameControlGroup); 20 : _PieceFactory.setOnNewPiece(_OnNewPiece);
45 21 : 22 : _PieceList.setOnGameEnd(_OnGameEnd); 23 : } 24 : 25 : private PieceFactory _PieceFactory = null; 26 : private PieceList _PieceList = new PieceList(); 27 : 28 : private OnNotifyEventListener _OnNewPiece = new OnNotifyEventListener() { : public void onnotify(object sender) { 31 : getgamecontrolgroup().addcontrol((piece) sender); 32 : _PieceList.add((Piece) sender); 33 : } 34 : }; 35 : 36 : private OnNotifyEventListener _OnGameEnd = new OnNotifyEventListener() { : public void onnotify(object sender) { 39 : System.exit(0); 40 : } 41 : }; 42 : 43 : private Bitmap _BoardBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888); 44 : private Canvas _BoardCanvas = new Canvas(); 45 : 46 : private Canvas _Canvas = null; 47 : private Paint _Paint = new Paint(); 48 : 49 : public void startgame() { 50 : _PieceList.clear(); 51 : _PieceFactory.slice(); 52 : } 53 : : protected void onstart(gameplatforminfo platforminfo) { 56 : _Canvas = platforminfo.getcanvas(); 57 : 58 : Global.setScreenSize(_Canvas.getWidth(), _Canvas.getHeight()); 59 : setboardsize(global.blocksize * Global.boardSize); 60 : 61 : startgame(); 62 : } 63 : : protected void ondraw(gameplatforminfo platforminfo) { 66 : _Paint.setARGB(255, 0, 0, 0); 67 : _Canvas.drawRect(platformInfo.getRect(), _Paint); 68 : 69 : _Canvas.drawBitmap(_BoardBitmap, 0, 0, _Paint); 70 : } 71 : 72 : private int _BoardSize = 0; 73 : 74 : public int getboardsize() { 75 : return _BoardSize; 76 : }
46 77 : 78 : public void setboardsize(int _BoardSize) { 79 : this._boardsize = _BoardSize; 80 : prepareboardbitmap(_boardsize); 81 : } 82 : 83 : private void prepareboardbitmap(int boardsize) { : } 97 : 98 : } 소스가 길어서 몇 굮데의 소스를 생략하였습니다 : PieceFactory 객체를 생성하고, OnNewPiece 이벤트를 처리할 리스너를 지정합니다. PieceList 는 26: 라읶에서 객체를 생성하고, 22: 라읶에서 OnGameEnd 이벤트를 처리할 리스너를 지정합니다 : PieceFactory 가 처음의 사각형을 조각 내어 조각 객체를 생성할 때릴다 발생하는 OnNewPiece 이벤트를 처리할 리스너를 구현하고 있습니다 : Piece(조각)들이 이동할 때릴다 모듞 조각들이 제 위치에 있는 지를 확읶하고, 모두 제 위치에 있을 경우에 발생하는 OnGameEnd 이벤트를 처리할 리스너 입니다. 39: 라읶을 통해서 모듞 조각들이 제 위치에 있을 경우에는 프로그램을 종료 합니다 : 배경에 쓰읷 Bitmap 이미지를 작성합니다. Global.boardSize 에 맞도록 바둑판 모양의 격자를 그리는 부분이며 소스는 생략하였습니다. 매번 바둑판을 그리는 겂이 비효율적이기에 Bitmap 이미지를 준비하여 재사용하도록 하였습니다. 이미지를 미리 준비하여 리소스로 지정하여 불러 들여도 됩니다. 58: 프로그램이 시작되자 릴자 Global.setScreenSize() 메소드를 호출하여 게임 엔짂의 화면 크기를 지정합니다. 이겂으로 필요한 모듞 변수들이 초기화 됩니다. 61: 게임을 시작합니다. startgame()가 58: 라읶의 Global.setScreenSize()보다 나중에 실행되어야 하는 겂을 유의하시기 바랍니다 : [그린 2]에서 본 겂과 같이 게임이 시작되면, PieceList 를 초기화 하고, PieceFactory 를 통해서 처음의 사각형을 조각 냅니다. [소스 4] PieceList.java 1 : package app.main; 2 : 3 : import java.util.arraylist;
47 4 : 5 : import ryulib.onnotifyeventlistener; 6 : 7 : public class PieceList { 8 : 9 : private ArrayList<Piece> _List = new ArrayList<Piece>(); 10 : 11 : public void clear() { 12 : _List.clear(); 13 : } 14 : 15 : private OnNotifyEventListener _OnPieceMoved = new OnNotifyEventListener() { : public void onnotify(object sender) { 18 : checkgameend(); 19 : } 20 : }; 21 : 22 : public void add(piece piece) { 23 : _List.add(piece); 24 : piece.setonmoved(_onpiecemoved); 25 : } 26 : 27 : private void checkgameend() { : if (_OnGameEnd!= null) _OnGameEnd.onNotify(this); 55 : } 56 : 57 : private OnNotifyEventListener _OnGameEnd = null; 58 : 59 : public void setongameend(onnotifyeventlistener _OnGameEnd) { 60 : this._ongameend = _OnGameEnd; 61 : } 62 : 63 : public OnNotifyEventListener getongameend() { 64 : return _OnGameEnd; 65 : } 66 : 67 : } 22-25: PieceFactory에 의해서 릶들어짂 조각들을 _List 목록에 포함시키면서 이벤트 리스너를 지 정하고 있습니다. 이제 각 Piece(조각)들이 움직읷 때릴다 18: 라읶이 실행되어, 소스가 생략된 27-55: 라읶에서 모듞 조각들이 제 위치에 있는 지를 확읶하여, 54: 라읶을 통해 리스너를 호출하 게 됩니다. 이벤트가 실제 어떻게 처리하는 지는 이벤트 리스너를 보유한 객체에게 위임하고 자 싞을 싞경 쓰지 않습니다. [소스 5-1] PieceFactory.java #1 1 : package app.main; : public class PieceFactory extends GameControl { 12 : 13 : public PieceFactory(GameControlGroup gamecontrolgroup) { 14 : super(gamecontrolgroup); 15 : 16 : }
48 17 : 18 : private Boundary[][] _Boundaries = null; 19 : private int _BoundriesCount; 20 : 21 : public void slice() { 22 : createcells(); 23 : makepieces(); 24 : } 25 : 26 : private void makepieces() { 27 : _BoundriesCount = Global.boardSize * Global.boardSize; 28 : while (_BoundriesCount > 0) { 29 : makepiece(); 30 : } 31 : } 32 : 33 : private void makepiece() { 34 : int piecesize = getrandompiecesize(); 35 : Piece piece = new Piece(getGameControlGroup()); 36 : Point point = getrandompointchoice(); 37 : 38 : addboundarytopiece(point, piece); 39 : piecesize--; 40 : _BoundriesCount--; 41 : 42 : while ((piecesize > 0) && (_BoundriesCount > 0)) { 43 : point = getnextrandompoint(point); 44 : if (point == null) break; 45 : 46 : addboundarytopiece(point, piece); 47 : piecesize--; 48 : _BoundriesCount--; 49 : } 50 : 51 : piece.arrange(); : if (_OnNewPiece!= null) _OnNewPiece.onNotify(piece); 64 : } 65 : 66 : private void createcells() { 67 : _Boundaries = new Boundary[Global.boardSize][Global.boardSize]; 68 : 69 : for (int y=0; y<global.boardsize; y++) { 70 : for (int x=0; x<global.boardsize; x++) { 71 : _Boundaries[x][y] = new Boundary(x*Global.blockSize, y*global.blocksize, (x+1)*global.blocksize, (y+1)*global.blocksize); 72 : } 73 : } 74 : } 소스가 너무 길어서 나누어서 설명하고자 합니다 : PieceFactory의 가장 중요한 역할읶 조각내기에 해당 합니다 : 우선 조각을 내기 젂에 Global.boardSize의 2차원 배열로 Boundary 객체를 생성합니다.
49 즉, 최초의 사각형을 boardsize *boardsize 개수릶큼의 정사각형으로 조각 냅니다 : 정사각형의 조각의 개수릶큼 반복하면서 이겂들을 서로 랜덤한 모양과 랜덤한 개수로 묶 어 줍니다. 이겂이 릴치 테트리스 블록처럼 보이게 됩니다. 그리고, 이러한 묶음을 Piece라고 부 르겠습니다 : 실제 조각을 Piece로 묶어주는 곳 입니다. 63: 라읶에서 묶어짂 Piece를 이벤트를 발생시 켜 리스너에게 알려주고 있습니다. [소스 5-2] PieceFactory.java #2 76 : private void addboundarytopiece(point point, Piece piece) { 77 : _Boundaries[point.x][point.y] = null; 78 : piece.addblock(point.x, point.y); 79 : } 80 : 81 : private Point getrandompointchoice() { 82 : int x = Global.getRandom(Global.boardSize); 83 : int y = Global.getRandom(Global.boardSize); 84 : 85 : while (_Boundaries[x][y] == null) { 86 : x = Global.getRandom(Global.boardSize); 87 : y = Global.getRandom(Global.boardSize); 88 : } 89 : 90 : return new Point(x, y); 91 : } 92 : 93 : // 해당 좌표에 Boundary를 가져 올 수 있는 가? 있으면 좌표를 리턴한 94 : private Point getpoint(int x, int y) { 95 : if ((x < 0) (x >= Global.boardSize)) return null; 96 : if ((y < 0) (y >= Global.boardSize)) return null; 97 : 98 : if (_Boundaries[x][y]!= null) { 99 : return new Point(x, y); 100 : } else { 101 : return null; 102 : } 103 : } 104 : 105 : private Point getnextrandompoint(point basepoint) { 106 : ArrayList<Point> points = new ArrayList<Point>(); 107 : 108 : Point point; 109 : 110 : point = getpoint(basepoint.x-1, basepoint.y); 111 : if (point!= null) points.add(point); 112 : 113 : point = getpoint(basepoint.x+1, basepoint.y); 114 : if (point!= null) points.add(point); 115 : 116 : point = getpoint(basepoint.x, basepoint.y-1); 117 : if (point!= null) points.add(point); 118 : 119 : point = getpoint(basepoint.x, basepoint.y+1);
50 120 : if (point!= null) points.add(point); 121 : 122 : if (points.size() == 0) { 123 : return null; 124 : } else { 125 : int index = Global.getRandom(points.size()); 126 : return points.get(index); 127 : } 128 : } 129 : 130 : private int getrandompiecesize() { 131 : // TODO Auto-generated method stub 132 : return 5; 133 : } 134 : 135 : public void setonnewpiece(onnotifyeventlistener _OnNewPiece) { 136 : this._onnewpiece = _OnNewPiece; 137 : } 138 : 139 : public OnNotifyEventListener getonnewpiece() { 140 : return _OnNewPiece; 141 : } 142 : 143 : private OnNotifyEventListener _OnNewPiece = null; 144 : 145 : } 76-78: Piece는 이미 설명한 겂과 같이 복수 개의 Block으로 구성되어 있습니다. 77: 라읶에서는 Piece로 구성될 위치의 정사각형이 이미 사용되었음을 선언합니다. null로 표시하여 더 이상 사 용할 수 없음을 알리고 있습니다. 78: 라읶에서는 해당 블록을 Piece에 구성시킵니다 : _Boundaries에서 아무 정사각형(Block)이나 선택합니다. null로 지정되지 않은 넘릶을 선별 합니다. 36: 라읶에서처럼 처음에는 아무 겂이나 랜덤하게 선택하여 Piece로 구성합니다. 이후에 는 근처에 있는 정사각형을 찾아서 Piece에 포함시킵니다. 대각선 방향이나, 동 떨어져 있는 겂 을 하나로 묶어둓 수는 없기 때문입니다. 이때, : 에서는 젂후/좌우에 있는 정사각형 중 null이 아닌 하나를 선별하여 Piece에 묶어줍니다 : 이 부분은 34: 라읶에서 호출되며, Piece에 묶여질 수 있는 정사각형의 최대 개수를 나 타냅니다. 5를 리턴 하는 겂으로 고정되어 있지릶, 추후 게임의 재미를 위해서 랜덤하게 또는 레 벨에 맞춰서 변동시킬 부분 입니다. [소스 6-1] Piece.java #1 1 : package app.main; : public class Piece extends GameControl { 15 : 16 : public Piece(GameControlGroup gamecontrolgroup) { 17 : super(gamecontrolgroup); 18 : 19 : gamecontrolgroup.addcontrol(this);
51 20 : } 21 : 22 : private HitArea _HitArea = new HitArea(); 23 : : protected HitArea gethitarea() { 26 : return _HitArea; 27 : } 19: 모듞 GameControl은 GameControlGroup에 addcontrol() 메소드로 등록되어야 화면에 표시되 는 등에 동작이 이루어지는 겂에 유의하시기 바랍니다. 이 소스에서는 상당히 중요한 충돌 처리 부분이 존재합니다. 우선 22: 라읶처럼 HitArea 객체가 필요합니다. 이겂은 자싞의 영역을 알리는 역할을 합니다. 또한, 이 객체는 복수 개의 Boundary 를 묶어서 사용할 수 있도록 되어 있습니다. 이겂은 비행기와 달리 테트리스 블록은 모양이 복 잡하기 때문입니다. 처리 속도를 위해서 곡선대싞 네모 모양의 Boundary를 여러 개 묶어서 사용 하고 있습니다 : 라읶에서는 GameControlBase에 선언되어 있는 gethitarea() 메소드를 재 정의하고 있습니다. 여기서 우리가 생성한 HitArea 객체를 되돌려 주기릶 하면, 게임 엔짂이 충 돌 체트를 할 때, 방금 넘겨준 HitArea 객체를 통해서 나의 위치를 파악하고 다른 객체들과 충돌 했는 지 여부를 알려주게 됩니다. 실제 충돌되는 위치를 지정하는 곳은 : 입니다. HitArea 객체에 현재 Piece가 가지고 있 는 Block()들의 Boundary 객체를 묶어 줍니다. 이겂을 한 번에 끝내지 않고 매번 Piece가 움직읷 때릴다 다시 계산하는 이유는, Piece가 움직읷 때릴다 HitArea도 같이 움직읷 수 밖에 없기 때문 입니다. [소스 6-2] Piece.java #2 29 : private int _X = 0; 30 : private int _Y = 0; 31 : private int _MinLeft = 0xFFFF; 32 : private int _MinTop = 0xFFFF; 33 : private int _MaxLeft = -1; 34 : private int _MaxTop = -1; 35 : 36 : ArrayList<Block> _Blocks = new ArrayList<Block>(); 37 : 38 : public int getwidth() { 39 : return _MaxLeft - _MinLeft + 1; 40 : } 41 : 42 : public int getheight() { 43 : return _MaxTop - _MinTop + 1; 44 : } 45 : 46 : public void clearblocks() { 47 : _MinLeft = 0xFFFF; 48 : _MinTop = 0xFFFF; 49 : 50 : _Blocks.clear(); 51 : }
52 52 : 53 : public void addblock(int x, int y) { 54 : if (x < _MinLeft) _MinLeft = x; 55 : if (y < _MinTop ) _MinTop = y; 56 : 57 : if (x > _MaxLeft) _MaxLeft = x; 58 : if (y > _MaxTop ) _MaxTop = y; 59 : 60 : Block block = new Block(x, y); 61 : _Blocks.add(block); 62 : } 63 : 64 : public void arrange() { 65 : for (Block block : _Blocks) { 66 : block.decx(_minleft); 67 : block.decy(_mintop); 68 : } 69 : 70 : aftermoved(); 71 : } 72 : 73 : private int _A = 255; 74 : private int _R = (int) (Math.random() * 100) + 155; 75 : private int _G = (int) (Math.random() * 100) + 155; 76 : private int _B = (int) (Math.random() * 100) + 155; 77 : : protected void ondraw(gameplatforminfo platforminfo) { 80 : Paint paint = platforminfo.getpaint(); 81 : 82 : if (_ismoving) { 83 : paint.setargb(100, _R, _G, _B); 84 : } else { 85 : if ((checkcollision(this)!= null)) { 86 : paint.setargb(100, _R, _G, _B); 87 : } else { 88 : paint.setargb(_a, _R, _G, _B); 89 : } 90 : } 91 : 92 : int left = _X*Global.blockSize + _TouchMove.x-_TouchDown.x; 93 : int top = _Y*Global.blockSize + _TouchMove.y-_TouchDown.y; 94 : 95 : for (Block block : _Blocks) { 96 : platforminfo.getcanvas().drawrect( 97 : block.getboundary().getrect(left, top), 98 : paint 99 : ); 100 : } 101 : } 29-30: Piece의 현재 위치를 나타냅니다. 픽셀 단위가 아니고 화면을 블록 크기로 나누어짂 바둑 판으로 보았을 때의 좌표입니다 : PieceFactory를 통해서 묶어서 사용할 Block의 좌표를 입력받으면, 실제 Block 객체를 생성 해서 묶어주는 역할을 담당합니다. 이때, MinLeft와 MinTop은 묶어짂 블록들 중에서 좌상단에 위
53 치한 불록의 좌표를 계산하기 위해서 입니다. 이후 64-71: 라읶의 arrange() 메소드를 통해서 좌 상단의 블록의 좌표가 (0, 0)이 되도록 모듞 블록들의 좌표를 줄여 나갑니다 : Piece의 색상을 랜덤하게 결정합니다 : Piece를 상황에 맞도록 그릱니다. 82: 라읶에서는 움직이는 도중읶가를 파악하고, 85: 라 읶에서는 다른 Piece들과 충돌하는 가를 파악합니다. 두 가지에 해당하면, Piece에 투명도를 주어 서 상황을 알 수 있도록 합니다 : Piece에 포함된 블록 젂체를 그릱니다. [소스 6-3] Piece.java #3 103 : // Action Down, Move 읷 때, event 발생 위치 104 : private Point _TouchDown = new Point(); 105 : private Point _TouchMove = new Point(); 106 : 107 : private void doactiondown(int x, int y) { 108 : _TouchDown.set(x, y); 109 : _TouchMove.set(x, y); 110 : } 111 : 112 : private void doactionup(int x, int y) { 113 : int cx = (_X*Global.blockSize) + (x - _TouchDown.x) + (Global.blockSize / 2); 114 : int cy = (_Y*Global.blockSize) + (y - _TouchDown.y) + (Global.blockSize / 2); 115 : 116 : _TouchDown.set(0, 0); 117 : _TouchMove.set(0, 0); 118 : 119 : if (cx < 0) cx = 0; 120 : if (cy < 0) cy = 0; 121 : 122 : if (cx > (Global.screenWidth - getwidth())) cx = Global.screenWidth - getwidth(); 123 : if (cy > (Global.screenHeight - getheight())) cy = Global.screenHeight - getheight(); 124 : 125 : cx = (cx / Global.blockSize); 126 : cy = (cy / Global.blockSize); 127 : 128 : setpoint(cx, cy); 129 : } 130 : 131 : private void doactionmove(int x, int y) { 132 : _TouchMove.set(x, y); 133 : } 134 : 135 : private boolean _ismoving = false; 136 : : protected boolean ontouchevent(gameplatforminfo platforminfo, MotionEvent event) {
54 : } 172 : 173 : private boolean getismyarea(int x, int y) { 174 : for (Block block : _Blocks) { 175 : if (block.getboundary(_x, _Y).isMyArea(x, y)) return true; 176 : } 177 : return false; 178 : } : private void aftermoved() { 191 : _HitArea.clear(); 192 : for (Block block : _Blocks) { 193 : _HitArea.add(block.getBoundary(_X, _Y)); 194 : } 195 : 196 : if (_OnMoved!= null) _OnMoved.onNotify(this); 197 : } 198 : : } : 터치가 되었을 때 실행됩니다. 최초에 터치된 곳을 _TouchDown에 저장합니다. _TouchMove는 터치 이후에 이동(Move) 이벤트가 발생할 때릴다 해당 위치를 저장합니다 : 터치 이후에 이동 이벤트가 발생할 때릴다 그 위치를 _TouchMove에 저장합니다. _TouchMove의 좌표를 기준으로 Piece가 그려지게 됩니다. 이동 중에 Piece의 좌표는 그대로 두 고, _TouchMove를 통해서 현재 이동 중읶 곳의 좌표를 사용합니다. 그 이유는 릶약 Piece를 이 동하다가 잘 못된 공갂에 내려 놓으면 원래의 위치로 돌아가거나, 또는 이동 중에 충돌이나 또는 게임의 종료 처리가 되지 않도록 해야 하기 때문입니다 : Piece를 이동하다가 내려 놓게 되는 동작입니다 : 내려짂 Piece의 픽셀 단위의 좌표 (cx, cy)를 구하고 있습니다. 이때, (Global.blockSize / 2)릶큼 더하는 이유는 바둑판 모양의 격자에서 중앙을 표시하기 위해서 입니다 : 최초의 터치 위치와 이동 중 위치를 초기화 합니다 : 화면의 범위를 벖어나지 못하도록 합니다 : 픽셀 단위 좌표에서 바둑판 모양의 좌표로 변경합니다. 정수형태로 나눠지면서 가장 가까운 바둑판 격자의 위치로 이동됩니다. 128: 실제 위치를 변경합니다 : 실제 터치 이벤트를 처리하는 부분입니다. 상황에 따라서, 이미 설명한 doactiondown,
55 doactionup, doactionmove를 실행합니다 : 지정된 좌표가 내(Piece) 영역읶지를 확읶합니다 : Piece가 이동되면 HitArea 앆의 Boundary 위치를 다시 지정합니다. 그리고, OnMoved 이벤트를 발생하여 외부 리스너에게 알려줍니다. 193: block.getboundary(_x, _Y)에서 (_X, Y)의 의미는 모듞 Boundary가 상대 좌표를 사용하고 있어 서, Piece의 현재 좌표를 더해주어야지릶 실제 좌표가 되기 때문입니다. [소스 7] Block.java 1 : package app.main; 2 : 3 : import ryulib.graphic.boundary; 4 : import android.graphics.point; 5 : 6 : public class Block { 7 : 8 : public Block(int x, int y) { 9 : super(); 10 : 11 : _Point.set(x, y); 12 : updateboundary(); 13 : } 14 : 15 : private Point _Point = new Point(); 16 : private Boundary _Boundary = new Boundary(1, 1, Global.blockSize-2, Global.blockSize-2); 17 : 18 : public Point getpoint() { 19 : return _Point; 20 : } 21 : 22 : public int getx() { 23 : return _Point.x; 24 : } 25 : 26 : public int gety() { 27 : return _Point.y; 28 : } 29 : 30 : private void updateboundary() { 31 : _Boundary.setBoundary( 32 : (_Point.x * Global.blockSize) + 1, 33 : (_Point.y * Global.blockSize) + 1, 34 : ((_Point.x+1) * Global.blockSize) - 2, 35 : ((_Point.y+1) * Global.blockSize) : ); 37 : } 38 : 39 : public void decx(int value) { 40 : _Point.x = _Point.x - value; 41 : updateboundary(); 42 : }
56 43 : 44 : public void decy(int value) { 45 : _Point.y = _Point.y - value; 46 : updateboundary(); 47 : } 48 : 49 : public Boundary getboundary() { 50 : return _Boundary; 51 : } 52 : 53 : private Boundary _BoundaryCopy = new Boundary(_Boundary); 54 : 55 : public Boundary getboundary(int x, int y) { 56 : _BoundaryCopy.setBoundary(_Boundary); 57 : _BoundaryCopy.incLeft(x * Global.blockSize); 58 : _BoundaryCopy.incTop (y * Global.blockSize); 59 : 60 : return _BoundaryCopy; 61 : } 62 : 63 : } 조각을 이루는 작은 정사각형의 기능을 담당합니다 : 위치가 변동될 때릴다 실제 좌표를 계산하게 됩니다.
57 슈팅 게임 만들기 #1 1. 화면 전환 [그린 1] 화면 젂홖에 대한 상태도 [그린 1]은 게임 젂반적이 화면 젂홖에 대한 상태도입니다. 이에 대한 설명은 아래와 같습니다. Intro: 게임이 시작될 때 보여주는 화면. 화면이 보여지고 난 뒤 2초 후면 Main으로 이동 합니다. 실제 게임에서는 필요한 데이터 등을 로딩하는 동앆 보여주는 형식을 취합니다. Main: 게임의 Main Menu에 해당하는 화면 사용자의 선택에 따라 Option/Game/Finish 화면으로 이동 할 수 있습니다. Option: 게임의 옵션을 설정하고자 할 때 이용하는 화면 옵션을 설정한 이후에는 Main 화면으로 이동합니다. Game: 게임 화면 게임이 짂행되는 화면입니다. 게임은 여러 개의 레벨로 구성되어 있을 수 있으며, 한 레벨을 완료하면 다음 레벨 로 자동으로 이동하게 됩니다. 게임 로직에 의해서 게임이 끝나게 되면 게임 결과에 해당하는 Result 화면으로 이 동합니다. Result: 게임 결과 내용을 표시하는 화면 사용자가 내용을 확읶하면, 다시 Main 화면으로 이동합니다. Finish: 게임이 종료될 때 보여주는 화면
58 게임 어플리케이션이 완젂히 종료되기 젂에 표시되는 화면이며, 2초 정도 표시한 후 에 어플리케이션이 종료됩니다. [그린 2] Class Diagram [그린 2]는 화면을 표시하기 위하여 작성한 클래스들의 Class Diagram 입니다. 우선 화면릴다 클 래스를 따로 릶들어서 곾리할 예정입니다. 그리고, 화면이 복수 개로 존재하다 보니, 이겂을 한 곳에서 읷곾성 있도록 곾리하기 위해서 SceneManager를 두어서 접근하려고 합니다. 모듞 화면은 자싞이 표시될 때 초기화를 처리하는 actionin()과 자싞에게서 다른 화면으로 젂홖될 때 종료화를 처리하는 actionout() 메소드를 공통적으로 가지고 있기 때문에, Scene 클래스를 부 모 클래스로 하고 이를 상속받아서 처리하도록 하였습니다. [소스 1] Scene.java 1 : package app.scene; 2 : 3 : import ryulib.valuelist; 4 : import ryulib.game.gamecontrol; 5 : import ryulib.game.gamecontrolgroup; 6 : 7 : public class Scene extends GameControl { 8 : 9 : public Scene(GameControlGroup gamecontrolgroup) { 10 : super(gamecontrolgroup); 11 : 12 : setvisible(false); 13 : } 14 : 15 : final void doactionin(scene oldscene, ValueList params) { 16 : setvisible(true);
59 17 : actionin(oldscene, params); 18 : } 19 : 20 : public void actionin(scene oldscene, ValueList params) { 21 : // Override 해서 사용 22 : } 23 : 24 : final void doactionout(scene newscene) { 25 : setvisible(false); 26 : actionout(newscene); 27 : } 28 : 29 : public void actionout(scene newscene) { 30 : // Override 해서 사용 31 : } 32 : 33 : } 15: 이미 설명한 겂과 같이 자싞이 표시될 때 초기화를 실행하는 메소드 입니다. 파라메터로 이 젂 화면과 params를 사용합니다. params는 화면 젂홖 시에 부가 정보가 필요할 경우를 대비해 서 작성하였습니다. 현재 짂행하는 예제에서는 사용하지 않기 때문에 null로 처리하고 있습니다. 17: 자식 클래스에서 Override 하여 사용하게될 actionin()을 호출합니다. 각 화면릴다 처리할 내 용이 달라질 겂이 자명하기 때문입니다. 이와 같은 형태를 템플릲 메소드 패턴이라고 합니다. actionout()도 actionin()과 처리가 같기 때문에 설명을 생략합니다. 다릶, params가 녺리상으로 필요하지 않기 때문에 새로 표시될 화면에 해당하는 newscene 객체릶을 파라메터를 젂달 받습니 다. [소스 2] SceneManager.java 1 : package app.scene; 2 : 3 : import ryulib.valuelist; 4 : import ryulib.game.gamecontrolgroup; 5 : 6 : 7 : public class SceneManager { 8 : 9 : private static SceneManager _MyObject = new SceneManager(); 10 : 11 : private SceneManager() {} 12 : 13 : public static SceneManager getinstance() { 14 : return _MyObject; 15 : } 16 : 17 : private GameControlGroup _GameControlGroup = null; 18 : 19 : private Scene _Scene = null; 20 : private SceneIntro _SceneIntro = null; 21 : private SceneMain _SceneMain = null; 22 : private SceneOption _SceneOption = null;
60 23 : private SceneGame _SceneGame = null; 24 : private SceneResult _SceneResult = null; 25 : private SceneFinish _SceneFinish = null; 26 : 27 : public void intro(valuelist params) { 28 : if (_SceneIntro == null) _SceneIntro = new SceneIntro(_GameControlGroup); 29 : setscene(_sceneintro, params); 30 : } 31 : 32 : public void main(valuelist params) { 33 : if (_SceneMain == null) _SceneMain = new SceneMain(_GameControlGroup); 34 : setscene(_scenemain, params); 35 : } 36 : 37 : public void option(valuelist params) { 38 : if (_SceneOption == null) _SceneOption = new SceneOption(_GameControlGroup); 39 : setscene(_sceneoption, params); 40 : } 41 : 42 : public void game(valuelist params) { 43 : if (_SceneGame == null) _SceneGame = new SceneGame(_GameControlGroup); 44 : setscene(_scenegame, params); 45 : } 46 : 47 : public void result(valuelist params) { 48 : if (_SceneResult == null) _SceneResult = new SceneResult(_GameControlGroup); 49 : setscene(_sceneresult, params); 50 : } 51 : 52 : public void finish(valuelist params) { 53 : if (_SceneFinish == null) _SceneFinish = new SceneFinish(_GameControlGroup); 54 : setscene(_scenefinish, params); 55 : } 56 : 57 : public void setgamecontrolgroup(gamecontrolgroup value) { 58 : _GameControlGroup = value; 59 : } 60 : 61 : public GameControlGroup getgamecontrolgroup() { 62 : return _GameControlGroup; 63 : } 64 : 65 : public void setscene(scene value, ValueList params) { 66 : Scene temp = _Scene; 67 : _Scene = value; 68 : 69 : if (temp!= null) temp.doactionout(_scene); 70 : if (_Scene!= null) _Scene.doActionIn(temp, params); 71 : } 72 : 73 : public Scene getscene() { 74 : return _Scene; 75 : } 76 :
61 77 : } 각 화면으로 이동하기 위해서는 intro(), main(), option() 등의 메소드를 호출하기릶 하면 됩니다. 이 메소드들은 상당히 유사한 코드 형식을 보이고 있기 때문에 중복을 제거하는 겂이 좋을 수도 있습니다. 하지릶, 화면의 개수가 거의 고정이며, 변화가 된다고 해도 심할 가능성이 없기 때문 에 갂단하게 표현하였습니다. 변화가 없을 가능성이 높은데 굯이 코드를 복잡하게 작성하는 겂 이 득이 되지 않을 겂이라는 판단입니다. 9-15: SceneManager는 싱글톤 패턴으로 작성되어 있기 때문에 참조할 변수를 사용하지 않고, SceneManager.getInstance()를 호출해서 참조하면 됩니다. 65: 실제 화면을 젂홖하는 메소드 입니다. 69: 이젂 화면이 null 이 아니라면, 이젂 화면 객체의 doactionout() 메소드를 호출 합니다. 70: 현재 표시될 화면 객체의 doactionin() 메소드를 호출 합니다. 2. Main Activity [소스 3] Main.java 1 : package app.main; 2 : 3 : import ryulib.game.gameplatform; 4 : import android.app.activity; 5 : import android.os.bundle; 6 : import android.view.viewgroup; 7 : import android.widget.linearlayout; 8 : import app.scene.scenemanager; 9 : 10 : public class Main extends Activity { 11 : 12 : /** Called when the activity is first created. */ : public void oncreate(bundle savedinstancestate) { 15 : super.oncreate(savedinstancestate); 16 : 17 : _GamePlatform = new GamePlatform(this); 18 : _GamePlatform.setUseMotionEvent(true); 19 : _GamePlatform.setLayoutParams( 20 : new LinearLayout.LayoutParams( 21 : ViewGroup.LayoutParams.FILL_PARENT, 22 : ViewGroup.LayoutParams.FILL_PARENT, 23 : 0.0F 24 : ) 25 : ); 26 : setcontentview(_gameplatform);
62 27 : 28 : SceneManager.getInstance().setGameControlGroup( 29 : _GamePlatform.getGameControlGroup()); 30 : SceneManager.getInstance().intro(null); 31 : } 32 : 33 : private GamePlatform _GamePlatform = null; 34 : 35 : } 소스가 지금까지의 Main.java와 유사하기 때문에 틀리 부분릶 설명하도록 하겠습니다. 28: 곾리하고 있는 화면 객체들이 GameControl을 상속 받고 있기 때문에 GameControlGroup 객 체를 지정해줘야 합니다. _GamePlatform.getGameControlGroup()을 지정하여, 모듞 화면 객체들이 소속 될 GameControlGroup을 지정합니다. 29: 어플리케이션이 실행되자 릴자 intro 화면을 표시합니다. 앞서 설명한 겂과 같이 params는 현재의 예제에서는 사용하지 않기 때문에 null을 젂달하고 있습니다. 이는 다른 게임에서도 같은 소스를 재사용하기 위해서 미리 릶들어둒 읶터페이스 입니다. 3. 초기 화면 표시 [그린 3] 초기 화면
63 [소스 4] SceneIntro.java 1 : package app.scene; 2 : 3 : import ryulib.valuelist; 4 : import ryulib.game.gamecontrolgroup; 5 : import ryulib.game.gameplatforminfo; 6 : import android.graphics.bitmap; 7 : import android.graphics.bitmapfactory; 8 : import android.graphics.canvas; 9 : import android.graphics.paint; 10 : 11 : public class SceneIntro extends Scene { 12 : 13 : public SceneIntro(GameControlGroup gamecontrolgroup) { 14 : super(gamecontrolgroup); 15 : 16 : gamecontrolgroup.addcontrol(this); 17 : } 18 : 19 : private Canvas _Canvas = null; 20 : private Paint _Paint = null; 21 : private Bitmap _Bitmap = null; 22 : private long _DisplayTime = 0; 23 : : public void actionin(scene oldscene, ValueList params) { 26 : _DisplayTime = 2000; 27 : } 28 : : public void actionout(scene oldscene) { 31 : _Bitmap = null; 32 : } 33 : : protected void onstart(gameplatforminfo platforminfo) { 36 : _Canvas = platforminfo.getcanvas(); 37 : _Paint = platforminfo.getpaint(); 38 : } 39 : : protected void ondraw(gameplatforminfo platforminfo) { 42 : _DisplayTime = _DisplayTime - platforminfo.gettick(); 43 : if (_DisplayTime <= 0) { 44 : SceneManager.getInstance().main(null); 45 : return; 46 : } 47 : 48 : if (_Bitmap == null) { 49 : _Bitmap = BitmapFactory.decodeResource( 50 : platforminfo.getgameplatform().getcontext().getresources(), 51 : app.main.r.drawable.begin); 52 : } 53 : 54 : _Canvas.drawBitmap(_Bitmap, 0, 0, _Paint); 55 : } 56 : 57 : }
64 26: 표시될 시갂을 2초로 설정합니다. 31: 현재 화면이 다른 화면으로 젂홖될 때 _Bitmap 객체 참조를 삭제합니다 : _DisplayTime을 화면 표시 갂격읶 gettick() 릶큼씩 줄여나가다가, 2초가 지난 시점에서 main 화면으로 젂홖합니다. 48: _Bitmap 객체가 null이면 초기화면의 이미지를 불러들입니다. 54: 초기화면 이미지를 [그린 3]과 같이 표시합니다. 4. 메인 화면 표시 [그린 4] 메읶 화면 메읶 화면에서는 option, game, finish 화면으로 이동할 수 있으며, 이를 위해서 버턴 3개를 통해 서 이동하도록 하였습니다. 버턴은 ryulib.game.imagebutton 클래스를 사용합니다. [소스 5] SceneMain.java 1 : package app.scene; 2 : 3 : import ryulib.onnotifyeventlistener; 4 : import ryulib.valuelist; 5 : import ryulib.game.gamecontrolgroup;
65 6 : import ryulib.game.gameplatforminfo; 7 : import ryulib.game.imagebutton; 8 : import android.graphics.bitmap; 9 : import android.graphics.bitmapfactory; 10 : import android.graphics.canvas; 11 : import android.graphics.paint; 12 : import android.graphics.typeface; 13 : import app.main.r; 14 : 15 : public class SceneMain extends Scene { 16 : 17 : public SceneMain(GameControlGroup gamecontrolgroup) { 18 : super(gamecontrolgroup); 19 : 20 : gamecontrolgroup.addcontrol(this); 21 : } 22 : 23 : private Canvas _Canvas = null; 24 : private Paint _Paint = null; 25 : private Bitmap _Bitmap = null; 26 : 27 : private ImageButton _btoption = null; 28 : private ImageButton _btgame = null; 29 : private ImageButton _btexit = null; 30 : : public void actionin(scene oldscene, ValueList params) { 33 : _btoption = new ImageButton(getGameControlGroup()); 34 : _btoption.getpaint().settextsize(16); 35 : _btoption.getpaint().settypeface(typeface.default_bold); 36 : _btoption.setcaption("option"); 37 : _btoption.setposition(235, 24); 38 : _btoption.setimageup(r.drawable.btn_up); 39 : _btoption.setimagedown(r.drawable.btn_dn); 40 : _btoption.setonclick(_onoptionclick); 41 : 42 : _btgame = new ImageButton(getGameControlGroup()); 43 : _btgame.getpaint().settextsize(16); 44 : _btgame.getpaint().settypeface(typeface.default_bold); 45 : _btgame.setcaption("start Game"); 46 : _btgame.setposition(235, *1); 47 : _btgame.setimageup(r.drawable.btn_up); 48 : _btgame.setimagedown(r.drawable.btn_dn); 49 : _btgame.setonclick(_ongameclick); 50 : 51 : _btexit = new ImageButton(getGameControlGroup()); 52 : _btexit.getpaint().settextsize(16); 53 : _btexit.getpaint().settypeface(typeface.default_bold); 54 : _btexit.setcaption("exit"); 55 : _btexit.setposition(235, *2); 56 : _btexit.setimageup(r.drawable.btn_up); 57 : _btexit.setimagedown(r.drawable.btn_dn); 58 : _btexit.setonclick(_onexitclick); 59 : } 60 : : public void actionout(scene newscene) { 63 : _Bitmap = null; 64 : 65 : _btoption.delete();
66 66 : _btoption = null; 67 : 68 : _btgame.delete(); 69 : _btgame = null; 70 : 71 : _btexit.delete(); 72 : _btexit = null; 73 : } 74 : : protected void onstart(gameplatforminfo platforminfo) { 77 : _Canvas = platforminfo.getcanvas(); 78 : _Paint = platforminfo.getpaint(); 79 : } 80 : : protected void ondraw(gameplatforminfo platforminfo) { 83 : if (_Bitmap == null) { 84 : _Bitmap = BitmapFactory.decodeResource( 85 : platforminfo.getgameplatform().getcontext().getresources(), 86 : app.main.r.drawable.main); 87 : } 88 : 89 : _Canvas.drawBitmap(_Bitmap, 0, 0, _Paint); 90 : } 91 : 92 : private OnNotifyEventListener _OnOptionClick = new OnNotifyEventListener() { : public void onnotify(object sender) { 95 : SceneManager.getInstance().option(null); 96 : } 97 : }; 98 : 99 : private OnNotifyEventListener _OnGameClick = new OnNotifyEventListener() { : public void onnotify(object sender) { 102 : SceneManager.getInstance().game(null); 103 : } 104 : }; 105 : 106 : private OnNotifyEventListener _OnExitClick = new OnNotifyEventListener() { : public void onnotify(object sender) { 109 : SceneManager.getInstance().finish(null); 110 : } 111 : }; 112 : 113 : } 31-59: 화면의 초기화에서 필요한 버턴 3개를 생성하고 있습니다. 38,47,56: 버턴은 평상시에 해당하는 이미지와 39,48,57: 눌러졌을 때 사용하는 이미지 두 개를 지정하여 사용합니다.
67 36,45,54: ImageButton 클래스의 setcaption("표시할 문자열") 메소드는 버턴 위에 표시될 문자열 을 지정할 수 있도록 합니다 : 화면의 종료 처리에서는 배경화면과 버턴의 참조를 null로 지정합니다. 사용하지 않는 리 소스를 반홖하기 위해서 입니다 : _btoption 버턴이 클릭되면 option 화면으로 이동합니다 : _btgame 버턴이 클릭되면 game 화면으로 이동합니다 : _Exit 버턴이 클릭되면 finish 화면으로 이동합니다. [그린 5]는 _ btoption 버턴이 클릭됐을 때의 화면입니다. [그린 5] 버턴이 눌러졌을 때 (터치) 5. 게임 화면 표시 게임 화면의 경우에는 자체적으로도 레벨에 따른 화면 곾리가 필요합니다. 따라서 [그린 6]과 같 이 클래스를 구성하도록 하였습니다.
68 [그린 6] 게임 화면에 대한 Class Diagram [소스 6] SceneGame.java 1 : package app.scene; 2 : 3 : import ryulib.valuelist; 4 : import ryulib.game.gamecontrolgroup; 5 : import app.game.level.gamelevel; 6 : import app.game.level.gamelevel01; 7 : import app.game.level.gamelevel02; 8 : import app.game.level.gamelevel03; 9 : 10 : public class SceneGame extends Scene { 11 : 12 : private static SceneGame _MyObject = null; 13 : 14 : public SceneGame(GameControlGroup gamecontrolgroup) { 15 : super(gamecontrolgroup); 16 : 17 : _MyObject = this; 18 : 19 : gamecontrolgroup.addcontrol(this); 20 : } 21 : 22 : public static SceneGame getinstance() { 23 : return _MyObject; 24 : } 25 : 26 : private GameLevel _GameLevel = null; 27 : 28 : public void setgamelevel(int level) { 29 : if (_GameLevel!= null) { 30 : _GameLevel.delete(); 31 : _GameLevel = null; 32 : } 33 : 34 : switch (level) { 35 : case 1: _GameLevel = new
1. 슬라이딩퍼즐설계 슬라이딩퍼즐은이미여러종류가앱스토어에도공개되어있기때문에독자분들께서이미알고 있을것이라고생각합니다. 숫자또는이미지퍼즐조각을숚서대로맞춰서원래의모양으로되 돌리는것을목표로하는게임입니다. 이번연재에서는숫자로되어있는퍼즐조각을이용하도록하겠습니다. 이미지를넣어서처리
안드로이드개발 - 2 회 게임으로배우는안드로이드개발 이번연재에서는게쪽을이용하여슬라이딩퍼즐을만드는과정을설명하고자합니다. 처음에는간단하게, 게임엔진을이용하는방법에집중하여설명하는형식으로무작정따라하기가편한예제를만들어봤습니다. 하지만, 다소따라하기어렵더라도제대로된형식을갖춰야겠다고판단하여소스를다시다듬어서설명하기로했습니다. 부족하지만설계를통해서인터페이스를구축하고이를확장해나가는방식으로소스를작성하였습니다.
More information1. 테트리스퍼즐설계 [ 그림 1] 테스리스퍼즐실행화면 이번에만들테트리스퍼즐은 [ 그림 1] 과같이조각난퍼즐을다시하나로합치는게임입니다. 이동중이거나퍼즐이겹쳐져있을때는이것을알수있도록퍼즐색상을어둡게 ( 투명 ) 처리하였습니다. 우선기능요구사항을정리하면다음과같습니다. 정사각
안드로이드개발 - 3 회 게임으로배우는안드로이드개발 이번연재에서는게쪽을이용하여테트리스퍼즐을만드는과정을설명하고자합니다. 테트리스블럭모양의퍼즐을모두맞춰서사각형을완성하면프로그램이종료되는게임입니다. 지난연재에서는시스템을객체로조각낸이후에각객체끼리의의존성을제거하기위해서인터페이스를활용하였습니다. 이번연재에서는이벤트리스너를통해서의존성을제거하는방식으로예제를구성해보았습니다.
More information1. 화면전환 [ 그림 1] 화면전홖에대한상태도 [ 그림 1] 은게임전반적이화면전홖에대한상태도입니다. 이에대한설명은아래와같습니다. Intro: 게임이시작될때보여주는화면. 화면이보여지고난뒤 2초후면 Main으로이동합니다. 실제게임에서는필요한데이터등을로딩하는동안보여주는형식
안드로이드개발 - 4 회 게임으로배우는안드로이드개발 지금까지게임의핵심부분을구현하는것에집중하였다면, 이번연재에서는게임을포장하는단계라고볼수있습니다. 게임이시작할때인트로를보여주고, 옵션설정이나게임결과를표시하는화면등의전환에대해서다뤄볼것입니다. 글류종택 ryujt658@hanmail.net http://ryulib.tistory.com/ ( 트위터 : @RyuJongTaek)
More information1. 게임관련패키지추가 이번연재의소스에는아래와같이, 두개의패키지가추가되었습니다. 이패키지에있는소스들은 에서 Jet Boy 따라하기 라는제목으로설명되어있으니참고하시기바랍니다. app.game.resource 게임에서필요한이
안드로이드개발 - 5 회 게임으로배우는안드로이드개발 이제연재의마무리를하게되었습니다. 이번연재에서는지난연재에서구축한슈팅게임의플랫폼에실제게임모듈을얹어서슈팅게임을완성하도록하겠습니다. 이번연재에서는소리를다루는방법과방향센서를이용하여우주선을움직이는방법을다뤄보도록하겠습니다. 글류종택 ryujt658@hanmail.net http://ryulib.tistory.com/ (
More information03장
CHAPTER3 ( ) Gallery 67 68 CHAPTER 3 Intent ACTION_PICK URI android provier MediaStore Images Media EXTERNAL_CONTENT_URI URI SD MediaStore Intent choosepictureintent = new Intent(Intent.ACTION_PICK, ë
More information( )부록
A ppendix 1 2010 5 21 SDK 2.2. 2.1 SDK. DevGuide SDK. 2.2 Frozen Yoghurt Froyo. Donut, Cupcake, Eclair 1. Froyo (Ginger Bread) 2010. Froyo Eclair 0.1.. 2.2. UI,... 2.2. PC 850 CPU Froyo......... 2. 2.1.
More information[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme
8 차시메뉴와대화상자 1 학습목표 안드로이드에서메뉴를작성하고사용하는방법을배운다. 안드로이드에서대화상자를만들고사용하는방법을배운다. 2 확인해볼까? 3 메뉴 1) 학습하기 [ 그림 8-1] XML 을이용한옵션메뉴설정방법 public boolean
More information[ 그림 7-1] 프로젝트 res 폴더 이미지뷰 [ 예제 7-1] 이미지뷰 1 <LinearLayout 2 ~~~~ 중간생략 ~~~~ 3 android:orientation="vertical" > 4 <ImageView
7 차시이미지처리 1 학습목표 이미지뷰를사용하는방법을배운다. 비트맵을사용하는방법을배운다. 2 확인해볼까? 3 이미지뷰와이미지버튼 1) 학습하기 [ 그림 7-1] 프로젝트 res 폴더 이미지뷰 [ 예제 7-1] 이미지뷰 1 4
More informationPowerPoint 프레젠테이션
실습 1 배효철 th1g@nate.com 1 목차 조건문 반복문 System.out 구구단 모양만들기 Up & Down 2 조건문 조건문의종류 If, switch If 문 조건식결과따라중괄호 { 블록을실행할지여부결정할때사용 조건식 true 또는 false값을산출할수있는연산식 boolean 변수 조건식이 true이면블록실행하고 false 이면블록실행하지않음 3
More information안드로이드기본 11 차시어댑터뷰 1 학습목표 어댑터뷰가무엇인지알수있다. 리스트뷰와스피너를사용하여데이터를출력할수있다. 2 확인해볼까? 3 어댑터뷰 1) 학습하기 어댑터뷰 - 1 -
11 차시어댑터뷰 1 학습목표 어댑터뷰가무엇인지알수있다. 리스트뷰와스피너를사용하여데이터를출력할수있다. 2 확인해볼까? 3 어댑터뷰 1) 학습하기 어댑터뷰 - 1 - ArrayAdapter ArrayAdapter adapter = new ArrayAdapter(this, android.r.layout.simple_list_item_1,
More information제8장 자바 GUI 프로그래밍 II
제8장 MVC Model 8.1 MVC 모델 (1/7) MVC (Model, View, Controller) 모델 스윙은 MVC 모델에기초를두고있다. MVC란 Xerox의연구소에서 Smalltalk 언어를바탕으로사용자인터페이스를개발하기위한방법 MVC는 3개의구성요소로구성 Model : 응용프로그램의자료를표현하기위한모델 View : 자료를시각적으로 (GUI 방식으로
More informationPowerPoint 프레젠테이션
@ Lesson 2... ( ). ( ). @ vs. logic data method variable behavior attribute method field Flow (Type), ( ) member @ () : C program Method A ( ) Method B ( ) Method C () program : Java, C++, C# data @ Program
More informationMicrosoft PowerPoint - chap02-C프로그램시작하기.pptx
#include int main(void) { int num; printf( Please enter an integer "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; } 1 학습목표 을 작성하면서 C 프로그램의
More informationMicrosoft PowerPoint - 14주차 강의자료
Java 로만드는 Monster 잡기게임예제이해 2014. 12. 2 게임화면및게임방법 기사초기위치 : (0,0) 아이템 10 개랜덤생성 몬스터 10 놈랜덤생성 Frame 하단에기사위치와기사파워출력방향키로기사이동아이템과몬스터는고정종료버튼클릭하면종료 Project 구성 GameMain.java GUI 환경설정, Main Method 게임객체램덤위치에생성 Event
More informationPowerPoint Presentation
객체지향프로그래밍 클래스, 객체, 메소드 ( 실습 ) 손시운 ssw5176@kangwon.ac.kr 예제 1. 필드만있는클래스 텔레비젼 2 예제 1. 필드만있는클래스 3 예제 2. 여러개의객체생성하기 4 5 예제 3. 메소드가추가된클래스 public class Television { int channel; // 채널번호 int volume; // 볼륨 boolean
More informationJAVA PROGRAMMING 실습 08.다형성
2015 학년도 2 학기 1. 추상메소드 선언은되어있으나코드구현되어있지않은메소드 abstract 키워드사용 메소드타입, 이름, 매개변수리스트만선언 public abstract String getname(); public abstract void setname(string s); 2. 추상클래스 abstract 키워드로선언한클래스 종류 추상메소드를포함하는클래스
More information어댑터뷰
04 커스텀어댑터뷰 (Custom Adapter View) 커스텀어댑터뷰 (Custom Adapter View) 커스텀어댑터뷰 (Custom Adatper View) 란? u 어댑터뷰의항목하나는단순한문자열이나이미지뿐만아니라, 임의의뷰가될수 있음 이미지뷰 u 커스텀어댑터뷰설정절차 1 2 항목을위한 XML 레이아웃정의 어댑터정의 3 어댑터를생성하고어댑터뷰객체에연결
More information3. 저장위치를 바탕화면으로 설정하고, 저장을 하고, 실행을 합니다. 4. 바탕화면에 아이콘이 생성되고 아이콘을 더블 클릭합니다. 5. 실행을 클릭하여 프로그램을 설치합니다. 다음버튼을 클릭하고, 사용권 계약에서는 예를 클릭합 니다. 6. 암호 입력창이 뜨면 기본 암호
쉽고 간단한 스마트폰 앱 제작하기 우리가 읷반적으로 사용하고 있는 용어 응용 소프트웨어(application software)는 넓은 의미에서는 운영 체제 위에서 실행되는 모든 소프트웨어를 뜻합니다. 앱(APP) 이라고 줄여서 말하기도 하고, 어플, 어플리케이션 이라고도 합니다. 해당 앱만 설치하면 갂편하게 읶터넷 뱅킹도 이용하고 버스나 지하철 노선이나 차량
More informationMicrosoft Word - windows server 2003 수동설치_non pro support_.doc
Windows Server 2003 수동 설치 가이드 INDEX 운영체제 설치 준비과정 1 드라이버를 위한 플로피 디스크 작성 2 드라이버를 위한 USB 메모리 작성 7 운영체제 설치 과정 14 Boot Sequence 변경 14 컨트롤러 드라이버 수동 설치 15 운영체제 설치 17 운영체제 설치 준비 과정 Windows Server 2003 에는 기본적으로
More information쉽게 풀어쓴 C 프로그래밍
제 5 장생성자와접근제어 1. 객체지향기법을이해한다. 2. 클래스를작성할수있다. 3. 클래스에서객체를생성할수있다. 4. 생성자를이용하여객체를초기화할수 있다. 5. 접근자와설정자를사용할수있다. 이번장에서만들어볼프로그램 생성자 생성자 (constructor) 는초기화를담당하는함수 생성자가필요한이유 #include using namespace
More informationPowerPoint Presentation
Class - Property Jo, Heeseung 목차 section 1 클래스의일반구조 section 2 클래스선언 section 3 객체의생성 section 4 멤버변수 4-1 객체변수 4-2 클래스변수 4-3 종단 (final) 변수 4-4 멤버변수접근방법 section 5 멤버변수접근한정자 5-1 public 5-2 private 5-3 한정자없음
More informationPowerPoint Presentation
객체지향프로그래밍 인터페이스, 람다식, 패키지 ( 실습 ) 손시운 ssw5176@kangwon.ac.kr 예제 1. 홈네트워킹 public interface RemoteControl { public void turnon(); // 가전제품을켠다. public void turnoff(); // 가전제품을끈다. 인터페이스를구현 public class Television
More information슬라이드 1
프로세싱 광운대학교로봇학부박광현 프로세싱실행 2 C:\processing-3.2.1 폴더 창나타내기 실행 정지 3 폭 높이 600 400 도형그리기 배경칠하기 5 background(255, 255, 255); R G B background(255, 0, 0); background(255, 122, 0); 선그리기 6 background(255, 122, 0);
More information2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.
10 차시파일처리 1 학습목표 내장메모리의파일을처리하는방법을배운다. SD 카드의파일을처리하는방법을배운다. 2 확인해볼까? 3 내장메모리파일처리 1) 학습하기 [ 그림 10-1] 내장메모리를사용한파일처리 2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1
More informationJAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각
JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( http://java.sun.com/javase/6/docs/api ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각선의길이를계산하는메소드들을작성하라. 직사각형의가로와세로의길이는주어진다. 대각선의길이는 Math클래스의적절한메소드를이용하여구하라.
More informationView Licenses and Services (customer)
빠른 빠른 시작: 시작: 라이선스, 라이선스, 서비스 서비스 및 주문 주문 이력 이력 보기 보기 고객 가이드 Microsoft 비즈니스 센터의 라이선스, 서비스 및 혜택 섹션을 통해 라이선스, 온라인 서비스, 구매 기록 (주문 기록)을 볼 수 있습니다. 시작하려면, 비즈니스 센터에 로그인하여 상단 메뉴에서 재고를 선택한 후 내 재고 관리를 선택하십시오. 목차
More informationMicrosoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx
2018 학년도 1 학기 JAVA 프로그래밍 II 514760-1 2018 년봄학기 5/10/2018 박경신 Lab#1 (ImageTest) Lab#1 은영상파일 (Image) 을읽어서정보를출력 Java Tutorials Lesson: Working with Images https://docs.oracle.com/javase/tutorial/2d/images/index.html
More information9 차시고급위젯다루기 1 학습목표 날짜 / 시간과관련된위젯을배운다. 웹뷰를사용하여간단한웹브라우저기능을구현한다. 매니패스트파일의설정법을배운다. 2 확인해볼까? 3 날짜 / 시간위젯 1) 활동하기 활동개요
9 차시고급위젯다루기 1 학습목표 날짜 / 시간과관련된위젯을배운다. 웹뷰를사용하여간단한웹브라우저기능을구현한다. 매니패스트파일의설정법을배운다. 2 확인해볼까? 3 날짜 / 시간위젯 1) 활동하기 활동개요 [ 그림 9-1] 시간예약앱 활동과정 - 2 - [ 그림 9-2] 안드로이드 SDK Manager [ 예제 9-1]main.xml 1
More information쓰리 핸드(삼침) 요일 및 2405 요일 시간, 및 요일 설정 1. 용두를 2의 위치로 당기고 반시계방향으로 돌려 전날로 를 설정합니다. 2. 용두를 시계방향으로 돌려 전날로 요일을 설정합니다. 3. 용두를 3의 위치로 당기고 오늘 와 요일이 표시될 때까지 시계방향으로
한국어 표준 설정안내 서브 초침 시간 및 설정 1. 용두를 2의 위치로 뽑아냅니다. 2. 용두를 시계방향 또는 반시계방향으로 돌려(모델에 따라 다름) 를 전날로 설정합니다. 3. 용두를 3의 위치로 당기고 현재 가 표시될 때까지 시계방향으로 돌립니다. 4. 용두를 계속 돌려 정확한 오전/오후 시간을 설정합니다. 5. 용두를 1의 위치로 되돌립니다. 169 쓰리
More informationgnu-lee-oop-kor-lec10-1-chap10
어서와 Java 는처음이지! 제 10 장이벤트처리 이벤트분류 액션이벤트 키이벤트 마우스이동이벤트 어댑터클래스 스윙컴포넌트에의하여지원되는이벤트는크게두가지의카테고리로나누어진다. 사용자가버튼을클릭하는경우 사용자가메뉴항목을선택하는경우 사용자가텍스트필드에서엔터키를누르는경우 두개의버튼을만들어서패널의배경색을변경하는프로그램을작성하여보자. 이벤트리스너는하나만생성한다. class
More information제11장 프로세스와 쓰레드
제9장자바쓰레드 9.1 Thread 기초 (1/5) 프로그램 명령어들의연속 (a sequence of instruction) 프로세스 / Thread 실행중인프로그램 (program in execution) 프로세스생성과실행을위한함수들 자바 Thread 2 9.1 Thread 기초 (2/5) 프로세스단위작업의문제점 프로세스생성시오버헤드 컨텍스트스위치오버헤드
More informationgnu-lee-oop-kor-lec06-3-chap7
어서와 Java 는처음이지! 제 7 장상속 Super 키워드 상속과생성자 상속과다형성 서브클래스의객체가생성될때, 서브클래스의생성자만호출될까? 아니면수퍼클래스의생성자도호출되는가? class Base{ public Base(String msg) { System.out.println("Base() 생성자 "); ; class Derived extends Base
More informationPowerPoint Presentation
Package Class 3 Heeseung Jo 목차 section 1 패키지개요와패키지의사용 section 2 java.lang 패키지의개요 section 3 Object 클래스 section 4 포장 (Wrapper) 클래스 section 5 문자열의개요 section 6 String 클래스 section 7 StringBuffer 클래스 section
More informationSBR-100S User Manual
( 1 / 13 ) SBR-100S 모델에 대한 사용자 펌웨어 업그레이드 방법을 안내해 드립니다. SBR-100S 는 신규 펌웨어가 있을시 FOTA(자동업데이트) 기능을 통하여 자동 업그레이드가 되며, 필요시 사용자가 신규 펌웨어를 다운받아 수동으로 업그레이드 할 수 있습니다. 1. 준비하기 1.1 연결 장치 준비 펌웨어 업그레이드를 위해서는 SBR-100S
More informationPowerPoint Presentation
public class SumTest { public static void main(string a1[]) { int a, b, sum; a = Integer.parseInt(a1[0]); b = Integer.parseInt(a1[1]); sum = a + b ; // 두수를더하는부분입니다 System.out.println(" 두수의합은 " + sum +
More informationPathEye 공식 블로그 다운로드 받으세요!! 지속적으로 업그래이드 됩니다. 여러분의 의견을 주시면 개발에 반영하겠 습니다.
PathEye Mobile Ver. 0.71b 2009. 3. 17 By PathEye 공식 블로그 다운로드 받으세요!! http://blog.patheye.com 지속적으로 업그래이드 됩니다. 여러분의 의견을 주시면 개발에 반영하겠 습니다. PathEye 설치 1/3 최종 배포 버전을 다 운로드 받습니다. 다운로드된 파일은 CAB 파일입니다. CAB 파일에는
More information(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public
Chapter 9 Lab 문제정답 1. public class Circle private double radius; static final double PI=3.141592; // PI 이름으로 3.141592 로초기화된정적상수 (1) public Circle(double r) radius = r; (2) public double getradius() return
More informationq 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2
객체지향프로그래밍 IT CookBook, 자바로배우는쉬운자료구조 q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2 q 객체지향프로그래밍의이해 v 프로그래밍기법의발달 A 군의사업발전 1 단계 구조적프로그래밍방식 3 q 객체지향프로그래밍의이해 A 군의사업발전 2 단계 객체지향프로그래밍방식 4 q 객체지향프로그래밍의이해 v 객체란무엇인가
More informationMicrosoft PowerPoint - 04-UDP Programming.ppt
Chapter 4. UDP Dongwon Jeong djeong@kunsan.ac.kr http://ist.kunsan.ac.kr/ Dept. of Informatics & Statistics 목차 UDP 1 1 UDP 개념 자바 UDP 프로그램작성 클라이언트와서버모두 DatagramSocket 클래스로생성 상호간통신은 DatagramPacket 클래스를이용하여
More information슬라이드 1
한국산업기술대학교 제 4 강프레임리스너 (Frame Listener) 이대현교수 학습안내 학습목표 프레임리스너를이용하여게임루프를구현하는방법을이해한다. 오우거엔짂의키입력처리방식을이해한다. 학습내용 프레임리스너의개념프레임리스너를이용한게임캐릭터의이동캐릭터의이동속도조절 OIS 입력시스템을이용한키보드입력의처리 기본게임루프 Initialization Game Logic
More information슬라이드 1
2007 년 2 학기윈도우게임프로그래밍 제 7 강프레임속도의조절 이대현 핚국산업기술대학교 학습내용 프레임속도의조절 30fps 맞추기 스프라이트프레임속도의조절 프레임속도 (Frame Rate) 프레임속도란? 얼마나빨리프레임 ( 일반적으로하나의완성된화면 ) 을만들어낼수있는지를나타내는척도 일반적으로초당프레임출력횟수를많이사용핚다. FPS(Frame Per Sec)
More informationMicrosoft PowerPoint - 2강
컴퓨터과학과 김희천교수 학습개요 Java 언어문법의기본사항, 자료형, 변수와상수선언및사용법, 각종연산자사용법, if/switch 등과같은제어문사용법등에대해설명한다. 또한 C++ 언어와선언 / 사용방법이다른 Java의배열선언및사용법에대해서설명한다. Java 언어의효과적인활용을위해서는기본문법을이해하는것이중요하다. 객체지향의기본개념에대해알아보고 Java에서어떻게객체지향적요소를적용하고있는지살펴본다.
More informationIRISCard Anywhere 5
이 빠른 사용자 가이드는 IRISCard Anywhere 5 및 IRISCard Corporate 5 스캐너의 설치와 시작을 도와 드립니다. 이 스캐너와 함께 제공되는 소프트웨어는: - Cardiris Pro 5 및 Cardiris Corporate 5 for CRM (Windows 용) - Cardiris Pro 4 (Mac OS 용) Cardiris 의
More informationMicrosoft PowerPoint - chap05-제어문.pptx
int num; printf( Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); 1 학습목표 제어문인,, 분기문에 대해 알아본다. 인 if와 switch의 사용 방법과 사용시 주의사항에 대해 알아본다.
More information오버라이딩 (Overriding)
WindowEvent WindowEvent 윈도우가열리거나 (opened) 닫힐때 (closed) 활성화되거나 (activated) 비활성화될때 (deactivated) 최소화되거나 (iconified) 복귀될때 (deiconified) 윈도우닫힘버튼을누를때 (closing) WindowEvent 수신자 abstract class WindowListener
More informationPowerPoint Presentation
자바프로그래밍 1 클래스와메소드심층연구 ( 실습 ) 손시운 ssw5176@kangwon.ac.kr 예제 1. 접근제어 class A { private int a; int b; public int c; // 전용 // 디폴트 // 공용 public class Test { public static void main(string args[]) { A obj = new
More information쉽게 풀어쓴 C 프로그래밍
Power Java 제 11 장상속 이번장에서학습할내용 상속이란? 상속의사용 메소드재정의 접근지정자 상속과생성자 Object 클래스 종단클래스 상속을코드를재사용하기위한중요한기법입니다. 상속이란? 상속의개념은현실세계에도존재한다. 상속의장점 상속의장점 상속을통하여기존클래스의필드와메소드를재사용 기존클래스의일부변경도가능 상속을이용하게되면복잡한 GUI 프로그램을순식간에작성
More information<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>
Power Java 제 8 장클래스와객체 I 이번장에서학습할내용 클래스와객체 객체의일생직접 메소드클래스를 필드작성해 UML 봅시다. QUIZ 1. 객체는 속성과 동작을가지고있다. 2. 자동차가객체라면클래스는 설계도이다. 먼저앞장에서학습한클래스와객체의개념을복습해봅시다. 클래스의구성 클래스 (class) 는객체의설계도라할수있다. 클래스는필드와메소드로이루어진다.
More informationSpring Data JPA Many To Many 양방향 관계 예제
Spring Data JPA Many To Many 양방향관계예제 오라클자바커뮤니티 (ojc.asia, ojcedu.com) 엔티티매핑 (Entity Mapping) M : N 연관관계 사원 (Sawon), 취미 (Hobby) 는다 : 다관계이다. 사원은여러취미를가질수있고, 하나의취미역시여러사원에할당될수있기때문이다. 보통관계형 DB 에서는다 : 다관계는 1
More information5장.key
JAVA Programming 1 (inheritance) 2!,!! 4 3 4!!!! 5 public class Person {... public class Student extends Person { // Person Student... public class StudentWorker extends Student { // Student StudentWorker...!
More informationMicrosoft PowerPoint 자바-기본문법(Ch2).pptx
자바기본문법 1. 기본사항 2. 자료형 3. 변수와상수 4. 연산자 1 주석 (Comments) 이해를돕기위한설명문 종류 // /* */ /** */ 활용예 javadoc HelloApplication.java 2 주석 (Comments) /* File name: HelloApplication.java Created by: Jung Created on: March
More informationchap 5: Trees
5. Threaded Binary Tree 기본개념 n 개의노드를갖는이진트리에는 2n 개의링크가존재 2n 개의링크중에 n + 1 개의링크값은 null Null 링크를다른노드에대한포인터로대체 Threads Thread 의이용 ptr left_child = NULL 일경우, ptr left_child 를 ptr 의 inorder predecessor 를가리키도록변경
More information지도상 유의점 m 학생들이 어려워하는 낱말이 있으므로 자세히 설명해주도록 한다. m 버튼을 무리하게 조작하면 고장이 날 위험이 있으므로 수업 시작 부분에서 주의를 준다. m 활동지를 보고 어려워하는 학생에게는 영상자료를 접속하도록 안내한다. 평가 평가 유형 자기 평가
수업주제 경찰 출동! (버튼, LED, 버저 사용하기) 9 / 12 차시 수업의 주제와 목표 본 수업에서는 이전 차시에 배웠던 블록들의 기능을 복합적으로 활용한다. 스위치 기능을 가진 버튼을 활용하여 LED와 버저를 동시에 작동시키도록 한다. 각 블록들을 함께 사용하는 프로젝트를 통해 각각의 기능을 익히고 보다 다양한 활용 방법을 구상할 수 있다. 교수 학습
More informationJUNIT 실습및발표
JUNIT 실습및발표 JUNIT 접속 www.junit.org DownLoad JUnit JavaDoc API Document 를참조 JUNIT 4.8.1 다운로드 설치파일 (jar 파일 ) 을다운로드 CLASSPATH 를설정 환경변수에서설정 실행할클래스에서 import JUnit 설치하기 테스트실행주석 @Test Test 를실행할 method 앞에붙임 expected
More information2 Application Name: Day10_yhg <LinearLayout android:layout_weight="3" > /> an
1 Application Name: Day10_yhg 예제 10-9 activity_main.xml
More information윈도우시스템프로그래밍
데이터베이스및설계 MySQL 을위한 MFC 를사용한 ODBC 프로그래밍 2012.05.10. 오병우 컴퓨터공학과금오공과대학교 http://www.apmsetup.com 또는 http://www.mysql.com APM Setup 설치발표자료참조 Department of Computer Engineering 2 DB 에속한테이블보기 show tables; 에러발생
More information01장
CHAPTER1 Camera (MediaStore) EXIF 1 2 CHAPTER 1 SDK (intent) Camera Camera Camera Android Manifest xml Camera Camera
More informationK&R2 Reference Manual 번역본
typewriter structunion struct union if-else if if else if if else if if if if else else ; auto register static extern typedef void char short int long float double signed unsigned const volatile { } struct
More informationContents. 1. PMD ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 2. Metrics ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 3. FindBugs ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 4. ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ
정적분석서 - 영단어수집왕 - Team.# 3 과목명 소프트웨어모델링및분석 담당교수 유준범교수님 201011320 김용현 팀원 201111360 손준익 201111347 김태호 제출일자 2015-06-09 1 Contents. 1. PMD ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 2. Metrics
More informationPowerPoint 프레젠테이션
인터페이스 배효철 th1g@nate.com 1 목차 인터페이스의역할 인터페이스선언 인터페이스구현 인터페이스사용 타입변환과다형성 인터페이스상속 디폴트메소드와인터페이스확장 2 인터페이스의역할 인터페이스란? 개발코드와객체가서로통신하는접점 개발코드는인터페이스의메소드만알고있으면 OK 인터페이스의역할 개발코드가객체에종속되지않게 -> 객체교체할수있도록하는역할 개발코드변경없이리턴값또는실행내용이다양해질수있음
More information학습목표 메뉴를추가하는방법을이해하고실습할수있다. 프로그램의기본설정 (settings) 을정의하는방법을알고실습할수있다. 대화상자를여는방법을알고실습할수있다. 로그메시지로디버깅하는방법을이해한다. 디버거로디버깅하는방법을이해한다.
헬로, 안드로이드 4 주차 사용자인터페이스디자인하기 (2) 강대기동서대학교컴퓨터정보공학부 학습목표 메뉴를추가하는방법을이해하고실습할수있다. 프로그램의기본설정 (settings) 을정의하는방법을알고실습할수있다. 대화상자를여는방법을알고실습할수있다. 로그메시지로디버깅하는방법을이해한다. 디버거로디버깅하는방법을이해한다. 차례 메뉴추가하기 Settings 추가하기 새게임시작하기
More information학습목표 선언하여디자인을하는방법을이해하고, 실행할수있다. 시작화면을만드는방법과대체리소스를사용하는방법을이해하고실행할수있다. About 과같은상자를구현하고, 테마를적용하는법을이해하고실행할수있다.
헬로, 안드로이드 3 주차 사용자인터페이스디자인하기 (1) 강대기동서대학교컴퓨터정보공학부 학습목표 선언하여디자인을하는방법을이해하고, 실행할수있다. 시작화면을만드는방법과대체리소스를사용하는방법을이해하고실행할수있다. About 과같은상자를구현하고, 테마를적용하는법을이해하고실행할수있다. 차례 스도쿠예제소개하기 선언하여디자인하기 시작화면만들기 대체리소스사용하기 About
More informationWindows 8에서 BioStar 1 설치하기
/ 콘텐츠 테이블... PC에 BioStar 1 설치 방법... Microsoft SQL Server 2012 Express 설치하기... Running SQL 2012 Express Studio... DBSetup.exe 설정하기... BioStar 서버와 클라이언트 시작하기... 1 1 2 2 6 7 1/11 BioStar 1, Windows 8 BioStar
More information슬라이드 1
모바일소프트웨어프로젝트 지도 API 1 조 20070216 김성수 20070383 김혜준 20070965 이윤상 20071335 최진 1 매시업? 공개 API? 2 매시업 웹으로제공하고있는정보와서비스를융합하여새로운소프트웨어나서비스, 데이터베이스등을만드는것 < 최초의매시업 > 3 공개 API 누구나사용할수있도록공개된 API 지도, 검색등다양한서비스들에서제공 대표적인예
More information<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>
게임엔진 제 4 강프레임리스너와 OIS 입력시스템 이대현교수 한국산업기술대학교게임공학과 학습내용 프레임리스너의개념 프레임리스너를이용한엔터티의이동 OIS 입력시스템을이용한키보드입력의처리 게임루프 Initialization Game Logic Drawing N Exit? Y Finish 실제게임루프 오우거엔진의메인렌더링루프 Root::startRendering()
More information신림프로그래머_클린코드.key
CLEAN CODE 6 11st Front Dev. Team 6 1. 2. 3. checked exception 4. 5. 6. 11 : 2 4 : java (50%), javascript (35%), SQL/PL-SQL (15%) : Spring, ibatis, Oracle, jquery ? , (, ) ( ) 클린코드를 무시한다면 . 6 1. ,,,!
More informationUI TASK & KEY EVENT
2007. 2. 5 PLATFORM TEAM 정용학 차례 CONTAINER & WIDGET SPECIAL WIDGET 질의응답및토의 2 Container LCD에보여지는화면한개 1개이상의 Widget을가짐 3 Container 초기화과정 ui_init UMP_F_CONTAINERMGR_Initialize UMP_H_CONTAINERMGR_Initialize
More informationMicrosoft PowerPoint - chap11-포인터의활용.pptx
#include int main(void) int num; printf( Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; 1 학습목표 포인터를 사용하는 다양한 방법에
More informationMicrosoft PowerPoint - 06-Chapter09-Event.ppt
AWT 이벤트처리하기 1. 이벤트처리방식 2. 이벤트클래스와리스너 3. 이벤트어댑터 4. 이벤트의종류 이벤트 (Event) 이벤트 사용자가 UI 컴포넌트에대해취하는행위로인한사건이벤트기반프로그래밍 무한루프를돌면서사용자의행위로인한이벤트를청취하여응답하는형태로작동하는프로그래밍 java.awt.event 이벤트처리 AWT 컴포넌트에서발생하는다양한이벤트를처리하기위한인터페이스와클래스제공
More informationPowerPoint 프레젠테이션
Lab 4 ADT Design 클래스로정의됨. 모든객체들은힙영역에할당됨. 캡슐화 (Encapsulation) : Data representation + Operation 정보은닉 (Information Hiding) : Opertion부분은가려져있고, 사용자가 operation으로만사용가능해야함. 클래스정의의형태 public class Person { private
More information09-interface.key
9 Database insert(record r): boolean find(key k): Record 1 Record getkey(): Key * Record Key Database.? Key equals(key y): boolean Database insert(record r): boolean find(key k): Record * Database OK 1
More informationAPI - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어
메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어서가장중요한부분이라고도할수있기때문입니다. 1. 새로운메크로생성 새메크로만들기버튺을클릭하여파일을생성합니다. 2. 메크로저장 -
More informationSpring Boot/JDBC JdbcTemplate/CRUD 예제
Spring Boot/JDBC JdbcTemplate/CRUD 예제 오라클자바커뮤니티 (ojc.asia, ojcedu.com) Spring Boot, Gradle 과오픈소스인 MariaDB 를이용해서 EMP 테이블을만들고 JdbcTemplate, SimpleJdbcTemplate 을이용하여 CRUD 기능을구현해보자. 마리아 DB 설치는다음 URL 에서확인하자.
More informationSKT UCC DRM
Version 2.3 서울특별시중구을지로 2 가 11 번지 SK T-Tower 목차 1. ARM 적용절차설명... 3 2. ARM Plugin 적용절차... 4 STEP 1. 프로젝트생성준비... 5 STEP 2. 이클립스프로젝트생성... 6 STEP 3. ARM Plugin(AIDL) 파일설치... 7 STEP 4. ARM Plugin(AIDL) 연동...
More information작성자 : 김성박\(삼성 SDS 멀티캠퍼스 전임강사\)
Session 을이용한현재로그인한사용자의 숫자구하기 작성자 : 김성박 ( 삼성 SDS 멀티캠퍼스전임강사 ) email : urstory@nownuri.net homepage : http://sunny.sarang.net - 본문서는http://sunny.sarang.net JAVA강좌란 혹은 http://www.javastudy.co.kr 의 칼럼 란에서만배포합니다.
More information<4D F736F F F696E74202D20C1A63233C0E520B1D7B7A1C7C820C7C1B7CEB1D7B7A1B9D628B0ADC0C729205BC8A3C8AF20B8F0B5E55D>
Power Java 제 23 장그래픽프로그래밍 이번장에서학습할내용 자바에서의그래픽 기초사항 기초도형그리기 색상 폰트 Java 2D Java 2D를이용한그리기 Java 2D 를이용한채우기 도형회전과평행이동 자바를이용하여서화면에그림을그려봅시다. 자바그래픽데모 자바그래픽의두가지방법 자바그래픽 AWT Java 2D AWT를사용하면기본적인도형들을쉽게그릴수있다. 어디서나잘실행된다.
More information<4D F736F F F696E74202D B3E22032C7D0B1E220C0A9B5B5BFECB0D4C0D3C7C1B7CEB1D7B7A1B9D620C1A638B0AD202D20C7C1B7B9C0D320BCD3B5B5C0C720C1B6C0FD>
2006 년 2 학기윈도우게임프로그래밍 제 8 강프레임속도의조절 이대현 한국산업기술대학교 오늘의학습내용 프레임속도의조절 30fps 맞추기 스프라이트프레임속도의조절 프레임속도 (Frame Rate) 프레임속도란? 얼마나빨리프레임 ( 일반적으로하나의완성된화면 ) 을만들어낼수있는지를나타내는척도 일반적으로초당프레임출력횟수를많이사용한다. FPS(Frame Per Sec)
More information리니어레이아웃 - 2 -
4 차시레이아웃 1 학습목표 레이아웃의개념을이해한다. 중복리니어레이아웃의개념이해한다. 2 확인해볼까? 3 레이아웃개념익히기 1) 학습하기 [ 그림 4-1] ViewGroup 클래스계층도 리니어레이아웃 - 2 - [ 예제 4-1]orientation 속성-horizontal 1
More informationRVC Robot Vaccum Cleaner
RVC Robot Vacuum 200810048 정재근 200811445 이성현 200811414 김연준 200812423 김준식 Statement of purpose Robot Vacuum (RVC) - An RVC automatically cleans and mops household surface. - It goes straight forward while
More informationMicrosoft PowerPoint 장강의노트.ppt
클래스와객체 클래스와객체 객체 : 우리주변의어떤대상의모델 - 예 : 사람, 차, TV, 개 객체 = 상태 (state) + 행동 (behavior) - 예 : 개의상태 - 종자, 이름, 색개의행동 - 짖다, 가져오다 상태는변수로행동은메소드로나타냄 객체는클래스에의해정의된다. 클래스는객체가생성되는틀혹은청사진이다. 2 예 : 클래스와객체 질문 : 클래스와객체의다른예는?
More information예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A
제 10 장상속 예제 1) ConstructorTest.java class Parent public Parent() super - default"); public Parent(int i) this("hello"); super(int) constructor" + i); public Parent(char c) this(); super(char) constructor
More informationDesign Issues
11 COMPUTER PROGRAMMING INHERIATANCE CONTENTS OVERVIEW OF INHERITANCE INHERITANCE OF MEMBER VARIABLE RESERVED WORD SUPER METHOD INHERITANCE and OVERRIDING INHERITANCE and CONSTRUCTOR 2 Overview of Inheritance
More information쉽게 풀어쓴 C 프로그래밍
제 11 장상속 1. 상속의개념을이해한다. 2. 상속을이용하여자식클래스를작성할수있다. 3. 상속과접근지정자와의관계를이해한다. 4. 상속시생성자와소멸자가호출되는순서를이해한다. 이번장에서만들어볼프로그램 class Circle { int x, y; int radius;... class Rect { int x, y; int width, height;... 중복 상속의개요
More informationMicrosoft PowerPoint - chap13-입출력라이브러리.pptx
#include int main(void) int num; printf( Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; 1 학습목표 스트림의 기본 개념을 알아보고,
More informationPowerPoint Presentation
Package Class 1 Heeseung Jo 목차 section 1 패키지개요와패키지의사용 section 2 java.lang 패키지의개요 section 3 Object 클래스 section 4 포장 (Wrapper) 클래스 section 5 문자열의개요 section 6 String 클래스 section 7 StringBuffer 클래스 section
More information@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a
1 대 1 단방향, 주테이블에외래키실습 http://ojcedu.com, http://ojc.asia STS -> Spring Stater Project name : onetoone-1 SQL : JPA, MySQL 선택 http://ojc.asia/bbs/board.php?bo_table=lecspring&wr_id=524 ( 마리아 DB 설치는위 URL
More information1
2/33 3/33 4/33 5/33 6/33 7/33 8/33 9/33 10/33 11/33 12/33 13/33 14/33 15/33 16/33 17/33 5) 입력을 다 했으면 확인 버튼을 클릭합니다. 6) 시작 페이지가 제대로 설정이 되었는지 살펴볼까요. 익스플로러를 종료하고 다시 실행시켜 보세요. 시작화면에 야후! 코리아 화면이 뜬다면 설정 완료..^^
More informationclass Sale void makelineitem(productspecification* spec, int qty) SalesLineItem* sl = new SalesLineItem(spec, qty); ; 2. 아래의액티비티다이어그램을보고 Java 또는 C ++,
Level 1은객관식사지선다형으로출제예정 1. 다음은 POST(Post of Sales Terminal) 시스템의한콜레보레이션다이어그램이다. POST 객체의 enteritem(upc, qty) 와 Sale 객체의 makellineitem(spec,qty) 를 Java 또는 C ++, C # 언어로구현하시오. 각메소드구현과관련하여각객체내에필요한선언이있으면선언하시오.
More informationrmi_박준용_final.PDF
(RMI) - JSTORM http://wwwjstormpekr (RMI)- Document title: Document file name: Revision number: Issued by: Document Information (RMI)- rmi finaldoc Issue Date: Status:
More informationPowerPoint 프레젠테이션
@ Lesson 3 if, if else, if else if, switch case for, while, do while break, continue : System.in, args, JOptionPane for (,, ) @ vs. logic data method variable Data Data Flow (Type), ( ) @ Member field
More information슬라이드 1
UNIT 6 배열 로봇 SW 교육원 3 기 학습목표 2 배열을사용핛수있다. 배열 3 배열 (Array) 이란? 같은타입 ( 자료형 ) 의여러변수를하나의묶음으로다루는것을배열이라고함 같은타입의많은양의데이터를다룰때효과적임 // 학생 30 명의점수를저장하기위해.. int student_score1; int student_score2; int student_score3;...
More information아이콘의 정의 본 사용자 설명서에서는 다음 아이콘을 사용합니다. 참고 참고는 발생할 수 있는 상황에 대처하는 방법을 알려 주거나 다른 기능과 함께 작동하는 방법에 대한 요령을 제공합니다. 상표 Brother 로고는 Brother Industries, Ltd.의 등록 상
Android 용 Brother Image Viewer 설명서 버전 0 KOR 아이콘의 정의 본 사용자 설명서에서는 다음 아이콘을 사용합니다. 참고 참고는 발생할 수 있는 상황에 대처하는 방법을 알려 주거나 다른 기능과 함께 작동하는 방법에 대한 요령을 제공합니다. 상표 Brother 로고는 Brother Industries, Ltd.의 등록 상표입니다. Android는
More information<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>
#include "stdafx.h" #include "Huffman.h" 1 /* 비트의부분을뽑아내는함수 */ unsigned HF::bits(unsigned x, int k, int j) return (x >> k) & ~(~0
More information. 스레드 (Thread) 란? 스레드를설명하기전에이글에서언급되는용어들에대하여알아보도록하겠습니다. - 응용프로그램 ( Application ) 사용자에게특정서비스를제공할목적으로구현된응용프로그램을말합니다. - 컴포넌트 ( component ) 어플리케이션을구성하는기능별요
. 스레드 (Thread) 란? 스레드를설명하기전에이글에서언급되는용어들에대하여알아보도록하겠습니다. - 응용프로그램 ( Application ) 사용자에게특정서비스를제공할목적으로구현된응용프로그램을말합니다. - 컴포넌트 ( component ) 어플리케이션을구성하는기능별요소로써안드로이드시스템에서는 Activities, Services, Content Providers,
More informationMicrosoft PowerPoint PythonGUI-sprite
(Sprite) 순천향대학교컴퓨터공학과 이상정 순천향대학교컴퓨터공학과 1 학습내용 소개 클래스 그룹클래스 충돌 블록수집게임예 게임레벨증가및점수표시 이동 순천향대학교컴퓨터공학과 2 소개 (sprite) 큰그래픽장면의부분으로사용되는단일 2차원이미지 => 쪽화면 게임의장면에서서로상호작용 ( 충돌등 ) 하는물체 => 캐릭터, 아바타 파이게임에서는일반적으로클래스로구현된객체
More informationMicrosoft PowerPoint - Java7.pptx
HPC & OT Lab. 1 HPC & OT Lab. 2 실습 7 주차 Jin-Ho, Jang M.S. Hanyang Univ. HPC&OT Lab. jinhoyo@nate.com HPC & OT Lab. 3 Component Structure 객체 (object) 생성개념을이해한다. 외부클래스에대한접근방법을이해한다. 접근제어자 (public & private)
More information이것은리스트뷰의 setadapter 메소드에잘표현되어있습니다. setadapter 는리스트뷰에사용할데이터객체를넘겨주는메소드입니다. 일반적으로생각한다면 ArrayAdapter 객체를생성하여사용할데이터를저장할것이고데이터가저장된 ArrayAdapter 객체를 setadapt
1. 리스트뷰의구조 리스트뷰는어떤데이터그룹에대한각각의정보들을항목별로출력시키고사용자에게원하는항목을검색하거나선택할수있도록해주는컨트롤객체입니다. 그래서다른컨트롤처럼정해진형태의정보를저장하는것이아니기때문에리스트뷰가데이터를직접관리하기는힘들었을것입니다. 그래서효과적인데이터관리를위해 "ArrayAdapter" 라는클래스가추가되었고리스트뷰는이클래스를이용해서사용자가지정한데이터에접근하도록구현되어있습니다.
More informationA Hierarchical Approach to Interactive Motion Editing for Human-like Figures
단일연결리스트 (Singly Linked List) 신찬수 연결리스트 (linked list)? tail 서울부산수원용인 null item next 구조체복습 struct name_card { char name[20]; int date; } struct name_card a; // 구조체변수 a 선언 a.name 또는 a.date // 구조체 a의멤버접근 struct
More information메뉴얼41페이지-2
데이터 기반 맞춤형 성장관리 솔루션 스마트빌 플러스 은행계좌등록 은행계좌를 조회하여 등록합니다. 신용카드등록 신용카드를 조회하여 등록합니다. 금융정보 자동수집을 위하여 인증서이름, 아이디, 비밀번호를 등록합니다. 통합 자동 수집 금융정보 통합 자동수집을 실행합니다 은행계좌등록 은행계좌를 조회하여 등록합니다. 신용카드등록 신용카드를 조회하여
More information