<BDC7C0FCBEDBB0B3B9DF5FC3D6C1BE5FC7CAC0DA2E687770>

Save this PDF as:
 WORD  PNG  TXT  JPG

Size: px
Start display at page:

Download "<BDC7C0FCBEDBB0B3B9DF5FC3D6C1BE5FC7CAC0DA2E687770>"

Transcription

1 :: 학습목표 :: 이클립스에서새로운 Project를만들수있다 View를디자인하고프로그램에연결할수있다 버튼의 Listener를작성할수있다 작성한 Listener를여러개의버튼이공유하게할수있다 일정한범위의난수를만들수있다 난수의발생빈도를조절할수있다 프로그램에서 ImageView의비트맵을바꿀수있다

2 1.1 에앞서 프로그램의기본흐름은입력, 처리, 출력으로단순화할수있다. 일반적인업무용프로그램은입력과출력이중요하므로그처리과정은전혀문제가되지않는경우가많다. 예를들어 1~100 까지의합계를구한다고하자. 이때 for( ) 문을사용하든, while( ) 문을사용하든, 심지어 으로구하든그결과만정확하면된다. 그러나게임은프로그램의실행결과가아니라실행과정에목적이있는프로그램이다. 게임의결과는뻔하다. 주인공이죽었다. 게임끝! 게임프로그램은업무용프로그램과달리비주얼한그래픽과사운드, 시스템의하드웨어, 메모리요구량, 처리속도등자잘한부분까지신경을써야하는복잡한분야이다. 게임의스토리보드가있어야하고, 자신이생각한아이디어를구현할수있는능력이있어야할뿐아니라전체적인흐름을체계화해서표현하는등기술적으로많은노하우가필요하다. 굳이비교한다면연극이나영화와같은종합예술에속한다. 그렇기때문에게임은비주얼하고동적인표현도중요하지만, 사용자의인터페이스를잘설계해서보기좋고재미있는프로그램을만들어야하는것이다. 안드로이드에서게임을개발하려고하면다음과같은기본적인것을잘알고있어야한다. Java 언어에대한기초적인지식 - 기본문법, 자료형, 반복문, Class와메서드 안드로이드의 Activity와 View에대한이해 - View와 Viewport, 화면해상도, 사용자 View. SurfaceView, Activity 사이의자료전달 Thread와 Handler - Thread와 Handler를이용한반복처리 키보드와 Touch 이벤트핸들러구현 - 키보드읽기, Touch 읽기 이미지처리 - Canvas, Bitmap, Matrix, Paint 자료구조 - 배열, ArrayList, Hash Map 2

3 수학적인기초지식 - 삼각함수, 행렬, Vector, 가속도 MediaPlayer 및 SoundPool - 배경음악및효과음 파일입출력및 Database 관리능력 - 최근점수, 최고득점순위표시 웹서버와의통신방법 - 다른사용자와의커뮤니케이션 캐릭터및배경화면디자인 - 포토샵, 일러스트레이터, 아이콘에디터등이책은어느정도 Java 프로그램에대한기초지식이있는사람을대상으로하고있다. 그러므로 Java 언어에대한기본문법이나안드로이드개발환경구축등에관한내용은다루지않는다. Java 언어에대한기초지식이부족하신분이나개발환경구축을하지못한분들은인터넷강좌등으로기초지식을함께학습하길바란다. 이책이여러분들에게고난도의 Java 프로그램수준은요구하지는않지만, 적어도이클립스에서간단한프로젝트정도는만들줄알아야한다. 제1 장은기본적인위젯을사용한단순한프로그램을작성해감으로써앞으로만들어갈복잡한게임에필요한기본적인지식과알고리즘을익히도록구성되어있다. 1.2 스무고개 스무고개라는놀이가있다. 진행자가어떤단어를정해두면, 다른사람이진행자에게질문을하여정답이나올범위를차츰좁혀가면서정답을찾아가는놀이이다. 진행자에게최대 20번까지만질문을할수있다고하여스무고개라고한다. 이게임은단말기가 500~1,000 사이의난수를만들어제시하면사용자는자신이추측한숫자를입력한후, 단말기가제시한값과의대소여부를판단하여주어진숫자가나올범위를차츰좁혀가면서정답을찾아가는게임이다 ( 제1장 /project_1). 1.2 스무고개 3

4 1.2.1 프로그램요구사항 단말기는 500~1000 사이의난수를제공한다. 사용자는 EditText에예상하는값을입력한다. 사용자가값을입력한후 Button을누르면결과를판정한다. 단말기가제공하는숫자와입력된숫자가다르면다시입력한다. 4의과정은정답을맞힐때까지반복하며, 최종적으로맞춘횟수를구한다 프로그램의구현에필요한요소 500~1000 사이의난수 Button의리스너 (Listener) 처리 EditText에입력된값읽기 전체입력횟수계산 새로운프로젝트시작 이클립스에서새로운프로젝트를시작하고 [New Android Project] 창에서다음과같이입력한다. 표 1-1 프로젝트창에입력할내용과의미 입력할내용 표기예 설명 Project name Project_1 프로젝트이름 Build Target Google APIs 2.2 프로젝트 API 버전 (2.2는버전 8) Application name Random Number 프로그램제목 Package name com.random 패키지이름 Create Activity MainActivity 액티비티이름 Min SDK Version 7 최저 SDK 버전 4

5 그림 1-1 새프로젝트시작 (1) Project name 프로젝트이름은영문자와숫자, 언더바 ( _ ), 공백을사용해서작성한다. 프로젝트이름으로새로운폴더가만들어진다. 프로젝트는소스프로그램과안드로이드 API, 각종리소스등을묶는기본단위로, 프로그램은프로젝트단위로컴파일된다. (2) Build Target 이프로그램에서필요한안드로이드 API 버전을지정한다. 되도록최신버전을사용하는것이유리하다. (3) Application name 프로그램이실행될때단말기맨위에표시되는프로그램이름으로한글을사용할수있다. (4) Package name 패키지는소스프로그램을묶는작은단위이다. 소스프로그램은사용자가작성하는프로그램으로.java 확장자가부여된다. 패키지이름은. 로구분되는 2개이상의문자열로구성된다. 일반적으로 com.study.myproject 와같이 com 을접두어로사용한다. 1.2 스무고개 5

6 (5) Create Activity Activity는프로그램의작은단위이다. 하나의프로그램은여러개의 Activity로구성될수있으며, Activity는하나이상의 View로구성된다. Activity 이름은영문자와숫자, 언더바 ( _ ) 를사용해서작성한다. (6) Min SDK Version 이프로그램을사용할최소의 API 버전을지정한다. 프로그램은이버전을기준으로컴파일되므로 (2) 에서높은버전을지정하더라도이버전이낮으면 (2) 의설정은무시된다 View 디자인 이프로그램은안드로이드가기본으로제공하는위젯만사용한다. 이클립스의 [res/layout/main.xml] 을열고 [layout] 탭에 TextView, EditText, Button 등을추가하고, 속성을다음과같이설정한다. 표 1-2 위젯의속성 위젯 ID 속성설정할내용 TextView01 EditText01 Button01 TextView02 Text 500~1,000 사이의값을입력하세요 Text size 20sp Text Text size 20sp Width 120dip Text 확인 Text size 20sp Text 판정결과 : Text size 20sp 다음은위의설정대로만들어진 xml 소스이다. 6

7 main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_height="fill_parent"> <TextView android:layout_width="wrap_content" android:text="500~1,000 사이의값을입력하세요 " android:textsize="20sp"/> <EditText android:layout_width="wrap_content" android:textsize="20sp" android:width="120dip"/> <Button android:layout_width="wrap_content" android:text=" 확인 " android:textsize="20sp"/> <TextView android:layout_width="wrap_content" android:text=" 판정결과 : " android:textsize="20sp"/> </LinearLayout> 그림 1-2 완성된 View 1.2 스무고개 7

8 1.2.5 Main Activity 영역의구분 이클립스에서 [Project_1/src/com.Random/MainActivity.java] 를열면이클립스가기본으로만들어준 Java 프로그램이나타난다. 처음부터 Activity를다음과같이구분하여각각의용도에맞춰사용하면프로그램작성하고수정하는데많은도움이된다. 1 전역변수선언영역 2 프로그램초기화영역 3 프로그램에서반복적으로사용할영역 그림 1-3 Activity 의영역구분 (1) 전역변수선언영역프로젝트레벨이나 Activity 레벨의전역변수를선언한다. 전역변수는프로그램어디에서나통용되는변수이다. (2) 프로그램초기화영역 oncreate( ) 메서드는프로그램이실행될때한번실행된다. 이영역은변수에초깃값을할당하고버튼등의컨트롤에리스너 (Listener) 를연결하는용도로사용한다. (3) 프로그램에서반복적으로사용할영역실제로작성할프로그램의본체이다. 반복적으로실행될수있으므로각종연산과정을기술하거나지정한처리결과를화면에표시하는등의용도로사용한다. 8

9 프로그램이간단하면전체를묶어서 (2) 의영역에서모든것을처리할수도있지만, 이렇게되면나중에알아보기힘든스파게티소스가되어서프로그램을수정하고업그레이드하는데아주큰장애가될수있다. 특히게임같이덩치가큰프로젝트를작성하려면처음부터원칙을정해두고작업을하는것이나중을위해서도큰도움이된다. 이책에서는아주간단한예제라도위의원칙을지키도록했다 난수발생하기 난수는 random( ) 함수나 Random Class를이용해서만든다. random( ) 함수를사용할경우에는별도의선언이필요치않지만, Random Class는 import 영역에 java.util Class를 import해두어야한다 ( 에디터에서 [Ctrl+Shift+O] 키를누르면이클립스가필요한 Class를알아서 import해준다 ). random( ) 함수와 Random Class는다음과같은형식으로사용한다. double d = Math.random(); // 0 < d < 1 사이의실수 Random rnd = new Random(); // Random Class 생성 int k = rnd.nextint(); // < k < int p = rnd.nextint(500); // 0 <= p < 500 대부분의난수는정수형태로사용한다. 그러므로 random( ) 함수로만든실수형의난수는별도의절차를거쳐서정수형태로변환해야할것이다. Random Class의난수는곧바로정수형의난수를구해주므로 random( ) 함수에비해더간편하다. 위에서예로든 rnd.nextint(n) 의형식으로만든난수는 0~n 1 사이의값이다 (n은난수에포함되지않는다 ). 우리의프로그램에서요구하는것과같은일정한범위의난수는다음의식을이용한다. int r = Random.nextInt(< 큰수 > - < 작은수 > + 1) + 작은수 예를들어 30과 40 사이의난수 (30과 40 모두가포함됨 ) 는 40 30=10이므로다음의식으로구할수있다. int r = Random.nextInt(10 + 1) + 30; // 30~40 사이의난수 마찬가지로 500~1000 사이의난수는 =500 이므로아래와같이됨을알수있다. 1.2 스무고개 9

10 int r = Random.nextInt(501) + 500; 버튼의리스너작성 이제사용자가값을입력한후버튼을누르면입력한값과발생된난수를비교해서처리하는부분을작성할차례이다. 사용자가버튼을누르는등의동작을처리하는부분을리스너 (Listener) 또는이벤트핸들러 (Event Handler) 라고한다. 안드로이드는리스너를처리하는방식을세가지형태로제공한다. 이들중두가지는이벤트처리부분을 [ 그림 1-3] 의프로그램초기화영역에합쳐버리는것이고, 다른한가지는프로그램영역에별도의리스너를작성하는방식이다. 앞에서언급한바와같이이벤트핸들러등은프로그램의영역에별도로작성하는것이알아보기쉬운코드가되므로이책에서는모두세번째방식으로작성한다 ( 두가지방법은이책에서는사용하지않으므로별도로언급하지않는다 ). 버튼에리스너를할당하고버튼이눌렸을때처리하는부분은 [ 그림 1-4] 와같이작성할수있다. 이부분은직접입력해야한다. 리스너할당 리스너본체 그림 1-4 Button 의 OnClickListener 10

11 [ 그림 1-4] 와같이별도로리스너를만들어두면버튼이여러개인경우에도동일한리스너를사용할수있으므로프로그램이매우깔끔해진다. 여러개의버튼이동일한리스너를공유하는방법은다음에나올예제에서설명할것이다 프로그램작성 위의내용을기초로해서프로그램을작성하자. 아직설명하지못한부분은프로그램내부에주석형태로표시하였다. mainactivity.java package com.random; import java.util.*; import android.app.*; import android.os.*; import android.view.*; import android.widget.*; public class MainActivity extends Activity { // 전역변수선언 int Counter; int n; EditText edit; TextView tresult; // 사용자가입력한횟수 // 난수발생용 // 사용자가입력하는컨트롤 // public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); // 변수초기화 Counter = 0; n = new Random().nextInt(501) + 500;... 1 edit = (EditText) findviewbyid(r.id.edittext01); tresult = (TextView) findviewbyid(r.id.textview02); findviewbyid(r.id.button01).setonclicklistener(mybuttonclick); } // oncreate 끝 1.2 스무고개 11

12 // // Button OnClickListener // Button.OnClickListener mybuttonclick = new Button.OnClickListener() { public void onclick(view v) { String s; Counter++; int p = Integer.parseInt(edit.getText().toString());... 2 }; } if (p < 500 p > 1000) s = " 입력한값이 500~1000 을벗어났습니다 "; else if (p == n) s = Counter + " 번째에맞추셨습니다 "; else if (p > n) s = p + " 보다작은값입니다 "; else s = p + " 보다큰값입니다 "; tresult.settext(s); } // Activity 의끝 다음의두문장을한개로줄인것이다. Random rnd = new Random(); n = rnd.nextint(501) + 500; EditText에숫자를입력하더라도내부에서는문자열로취급하므로 parseint( ) 함수로숫자로변환해서처리한다. 12

13 그림 1-5 프로그램실행결과 Note 이진검색정렬 (sort) 되어있는자료를검색하는방법으로이진검색 (Binary Search) 라는알고리즘이있다. 위와같은조건에서정답을가장빨리찾는방법은먼저주어진범위의중앙값을찾은후, 대소여부에따라왼쪽이나오른쪽의중앙값을다시찾는방법으로범위를계속해서절반으로줄여가는것이다. 이진검색은최악의경우에도 log 2N번이내에값을찾을수있는대단히우수한알고리즘이다. 위게임의경우에는 500~1000 의중간값인 750 을제시한후에대소여부에따라 750 과 1000 또는 750 과 500 사이의중간값인 875 와 625 를제시함으로써정답이있을부분을차츰좁혀가면 log 이므로최대 9회안에정답을찾을수있다. 1.2 스무고개 13

14 1.3 제비뽑기 아주오래전인필자의중학교시절에학교정문앞에서카드를가지고야바위를하는아저씨들이있었다. 3장의카드를임의로섞어놓고그중에서동그라미가그려진카드를고르는것이다. 이게임은 4장의카드중에서동그라미가그려진 1장의카드를맞추는것으로, 단말기가야바위아저씨역할을한다 ( 제1장 /project_2) 프로그램요구사항 단말기는 1~4 사이의난수로동그라미가그려진카드를정한다. 사용자는 1~4에해당하는버튼으로해당카드를고른다. 사용자가버튼을누르면당첨여부를판정한다 프로그램구현에필요한요소 이벤트핸들러의공유 Tag 속성활용 View 디자인 14 그림 1-6 완성된 View 의모습

15 main.xml [main.xm <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_height="fill_parent"> <TextView android:text=" 행운의주인공이되세요..." android:textsize="20sp" android:layout_height="120dip" android:gravity="center"/> <LinearLayout android:orientation="horizontal" > <Button android:text=" 당첨 " android:layout_width="wrap_content" android:textsize="18sp" android:layout_marginleft="10dip" android:layout_marginright="5dip" android:tag="1" android:layout_weight="1"/> <Button android:text=" 당첨 " android:layout_width="wrap_content" android:textsize="18sp" android:layout_marginleft="5dip" android:layout_marginright="5dip" android:tag="2" android:layout_weight="1"/> <Button android:text=" 당첨 " android:layout_width="wrap_content" android:textsize="18sp" android:layout_marginleft="5dip" android:layout_marginright="5dip" 1.3 제비뽑기 15

16 android:tag="3" android:layout_weight="1"/> <Button android:text=" 당첨 " android:layout_width="wrap_content" android:textsize="18sp" android:layout_marginleft="5dip" android:layout_marginright="10dip" android:tag="4" android:layout_weight="1"/> </LinearLayout> <TextView android:text=" 추첨결과 :" android:textsize="18sp" android:gravity="center" android:layout_height="100dip"/> </LinearLayout> 버튼의리스너공유 이프로젝트에는 4개의버튼이있으며, 각각의버튼은모두같은용도로사용한다. 그러므로프로그램을단순하게만들기위해 4개의버튼이같은리스너를사용하도록할것이다. 리스너를공유하려면모든버튼에같은리스너를할당한다. findviewbyid(r.id.button01).setonclicklistener(mybuttonclick); findviewbyid(r.id.button02).setonclicklistener(mybuttonclick); findviewbyid(r.id.button03).setonclicklistener(mybuttonclick); findviewbyid(r.id.button04).setonclicklistener(mybuttonclick); 이벤트리스너에 onclick(view v) 와같은형식으로눌려진버튼이매개변수로전달되므로 v.getid( ) 로리스너를호출한버튼을식별할수있다. 비교적간단한부분이므로소스를보면금방이해할수있을것이다. 16

17 MainActivity.java package com.sample; import java.util.*; import android.app.*; import android.os.*; import android.view.*; import android.widget.*; public class MainActivity extends Activity public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); // 버튼의리스너할당 findviewbyid(r.id.button01).setonclicklistener(mybuttonclick); findviewbyid(r.id.button02).setonclicklistener(mybuttonclick); findviewbyid(r.id.button03).setonclicklistener(mybuttonclick); findviewbyid(r.id.button04).setonclicklistener(mybuttonclick); } // End of oncreate // // Button OnClickListener // Button.OnClickListener mybuttonclick = new Button.OnClickListener() { public void onclick(view v) { int n = 0; String s; int r = new Random().nextInt(4) + 1; // 1~4 사이의난수 switch (v.getid()) { // 버튼의 id 구하기 case R.id.Button01 : n = 1; break; case R.id.Button02 : n = 2; break; case R.id.Button03 : n = 3; break; case R.id.Button04 : n = 4; } 1.3 제비뽑기 17

18 if (n == r) s = " 축하합니다. 당첨되셨습니다!"; else s = " 안타깝습니다.\n 다음기회에다시도전하세요 ~";... 1 }; } ((TextView) findviewbyid(r.id.textview01)).settext(s); } // End of Activity 문자열내부의 \n 은행을가르는용도로사용한다 ( \n 은개행문자 ). 그림 1-7 프로그램실행결과 버튼의 Tag 속성활용 이프로젝트에서버튼은 1~4의값을설정하는용도로만사용된다. 버튼에 1~4의값을미리할당해두고버튼의리스너에서이값으로판단하면, 프로그램을좀더짧게만들수있다. main.xml 의 Layout 페이지에서버튼의속성으로보면 Tag 라는항목이보인다. 18

19 Tag는우리말로하자면 꼬리표 같은것으로서컨트롤을식별하는용도로사용한다. 각각의버튼에차례대로 1~4의 Tag를지정해두면프로그램이다음과같이단순해진다 ( 앞의 main.xml 에는미리버튼의 Tag 속성을설정해두었다 ). 앞에서 switch( ) 문을사용하는경우와비교해보면그차이를확실히알수있다. 그림 1-8 이클립스의 Properties 창 public void onclick(view v) { int n = Integer.parseInt(v.getTag().toString()); String s; int r = new Random().nextInt(4) + 1; // 버튼의 Tag 읽기 // 1~4 사이의난수 if (n == r) s = " 축하합니다. 당첨되셨습니다!"; else s = " 안타깝습니다.\n 다음기회에다시도전하세요 ~"; } ((TextView) findviewbyid(r.id.textview01)).settext(s); 1.3 제비뽑기 19

20 Tag 속성은 Object형이므로곧바로정수형변수에대입할수는없고, 일단 String형으로변환한다음에다시정수로바꾸는일련의과정이필요하다. 1.4 윷놀이 (1) 연말이나연초가되면시골에는동네사람들이모여서윷놀이를즐긴다. 윷놀이는 4개의윷으로 도, 개, 걸, 윷, 모 의 5가지경우가만들어진다. 단순하게생각하면각각의경우에 0~4 또는 1~5의난수를발생시켜처리할수도있다. 그런데이렇게하면아주현실감없는게임이되어버린다. 왜냐하면 0~4 또는 1~5의난수는각각의발생확률이 1/5로균등하지만, 실제의윷놀이에서는 개 와 걸 이가장많이나오기때문이다 ( 제1장 /project_3) 윷놀이경우의수와발생확률 1개의윷을던지면앞과뒤, 즉 2가지경우가생긴다. 2개를던지면 2 2를해서 4가지, 4개의윷을던지면전체경우의수는 =16가지이다. 는평평한쪽, 는둥근쪽이라고하면각각의확률과경우의수는다음과같다. 윷 1/16 모 1/16 도 4/16 개 6/16 걸 4/16 위의확률은수학적인것으로, 실제의윷은한쪽은평평하고다른한쪽은둥글게생겼으므로평평한쪽이바닥이될가능성이둥근쪽에비해 1.2~1.5배정도더높은편이다. 그러므로수학적으로개는 6/16, 걸은 4/16으로개가걸보다발생빈도가더높지만, 실제의윷놀이에서는개와걸이거의비슷하거나오히려걸이더자주나타난다. 마찬가지이유로같은확률의윷과모는모가윷보다더자주나타난다. 20

21 1.4.2 프로그램요구사항 버튼을누르면난수를발생시켜 4개의윷을바닥과등으로표시한다. 윷의평평한쪽 ( 바닥 ) 은, 둥근쪽 ( 등 ) 은 으로나타낸다. 1에서만들어진결과에따라 도, 개, 걸, 윷, 모 라는말을함께표시한다. 바닥과등은 4:6의비율로등쪽이더자주나타나도록한다 프로그램의구현에필요한알고리즘 위의요구사항을충족시키려면윷의바닥과등을결정하는난수를 4개발생시켜이들의조합을이용한다. 각각의난수는바닥 (0) 과등 (1) 을갖도록하면되는데, 0과 1의값이 4:6의비율로 1이더자주발생하도록한다. (1) 4:6의비율에맞는난수만들기위의발생빈도 4:6을확률의개념으로보면경우의수가 4+6=10이다. 그러므로 0~9 사이의난수를발생시켜 0~3까지는 0, 4~9까지는 1이되도록조절하면 0과 1의발생빈도가정확하게 4:6의비율이될것이다. n = Random().nextInt(10); 위의식에의해 n 은 0~9 사이의값이된다. 이제위의식을다음과같이확장해본다. n = Random().nextInt(10) / 4; 위의식은 0~9의난수를발생한후 4로나눈몫을구하는것이다. 그결과난수가 0~3일때는몫이 0, 4~9일때는몫이 1 또는 2가되는데, 2를 1로보면 0과 1이비율이 4:6이다. 그런데위의식은 4로나눈몫이 1 또는 2가된다는문제가있다. n = Random().nextInt(10) / 6; 위의결과 0~5 는 0, 6~9 는 1 이구해진다. 몫이 2 가되는경우는없어졌지만, 0 과 1 의발생 1.4 윷놀이 (1) 21

22 비율이 6:4로역전이되었다. 위에서구한몫인 0을 1로, 1을 0으로변환하기위해식을다음과같이변경하면 0과 1이비율이 4:6의확률로발생하는난수를얻을수있다. n = 1 - Random().nextInt(10) / 6; 위의난수를얻는다른방법도있다. 4:6=2:3이므로 1~5 사이의난수를발생시켜 2로나눈나머지를취하면 1~5에대해 1, 0, 1, 0, 1이되므로 0과 1의비율이 2:3(4:6) 이된다. n = (Random().nextInt(5) + 1) % 2; (2) 4 개의난수를 도, 개, 걸, 윷, 모 로표시하기 앞에서사용한식에의해 4 개의난수는각각 0 또는 1 이될것이므로 1 의개수를세어서처리한다. 각각의난수를 n1, n2, n3, n4 라고했을때, n = n1 + n2 + n3 + n4; 위와같이 1의개수를간단히구할수있다. 도, 개, 걸, 윷, 모 를미리배열에저장해두면처리조건에맞는결과는다음의식으로구한다. String Yut[] = {" 윷 ", " 도 ", " 개 ", " 걸 ", " 모 "}; n = n1 + n2 + n3 + n4; String p = yut[n]; 위의 String 배열은등 ( 위쪽 ) 의개수를순서대로나타낸것이므로등이하나도없는 윷 을 yut[0], yut[1] 은 도, yut[2] 는 개, 와같은순서로저장한것이다 View 디자인 main.xml [main.xm <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_height="fill_parent"> 22

23 <TextView android:textsize="18sp" android:layout_height="60dip" android:gravity="center" android:text=" 윷을던지세요 "/> <LinearLayout android:orientation="horizontal" > <TextView android:text=" " android:textsize="40sp" android:layout_weight="1" android:gravity="center" android:layout_height="40dip"/> <TextView android:text=" " android:textsize="40sp" android:layout_weight="1" android:gravity="center" android:layout_height="40dip"/> </LinearLayout> <LinearLayout android:orientation="horizontal" > <TextView android:text=" " android:textsize="40sp" android:layout_weight="1" android:gravity="center" android:layout_height="40dip"/> <TextView android:text=" " android:textsize="40sp" 1.4 윷놀이 (1) 23

24 android:layout_weight="1" android:gravity="center" android:layout_height="40dip"/> </LinearLayout> <TextView android:text=" 결과 : " android:textsize="18sp" android:layout_height="60dip" android:gravity="center"/> <Button android:text=" 확인 " android:layout_gravity="center" android:layout_width="120dip" android:textsize="16sp"/> </LinearLayout> 그림 1-9 완성된 View 의모습 24

25 1.4.5 프로그램작성 MainActivity.java package com.project3; import java.util.*; import android.app.activity; import android.os.bundle; import android.view.*; import android.widget.*; public class MainActivity extends Activity { String tyut[] = {" ", " "}; String Yut[] = {" 윷 ", " 도 ", " 개 ", " 걸 ", " 모 public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); findviewbyid(r.id.button01).setonclicklistener(mybuttonclick); } // // Button OnClickListener // Button.OnClickListener mybuttonclick = new Button.OnClickListener() { public void onclick(view v) { Random rnd = new Random(); int n1 = 1 - rnd.nextint(10) / 6; int n2 = 1 - rnd.nextint(10) / 6; int n3 = 1 - rnd.nextint(10) / 6; int n4 = 1 - rnd.nextint(10) / 6; int n = n1 + n2 + n3 + n4; } }; } ((TextView) findviewbyid(r.id.textview01)).settext(tyut[n1]); ((TextView) findviewbyid(r.id.textview02)).settext(tyut[n2]); ((TextView) findviewbyid(r.id.textview03)).settext(tyut[n3]); ((TextView) findviewbyid(r.id.textview04)).settext(tyut[n4]); ((TextView) findviewbyid(r.id.textview05)).settext(yut[n]); 1.4 윷놀이 (1) 25

26 그림 1-10 프로그램실행결과 위의프로그램을실행시키고 [ 확인 ] 버튼을계속해서눌러보면 개 와 걸 의발생빈도가비슷해짐을알수있다. 1.5 윷놀이 (2) 1.3 에서작성한윷놀이를윷의결과를 ImageView 에표시하도록한다 ( 제 1 장 /project_4) 처리조건 1.3 과같다. 다만윷의형태를 ImageView 에표시한다. 26

27 1.5.2 View 디자인 그림 1-11 완성된 View 의모습 View를디자인하기위해윷의앞면과뒷면에해당하는이미지가 2개필요하다. 이이미지는제1장 /images 폴더에 yut_0.png, yut_1.png로수록되어있다. 그림 1-12 View 의디자인에필요한이미지 main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_height="fill_parent" > <TextView 1.5 윷놀이 (2) 27

28 28 android:text=" 윷을던지세요 " android:layout_height="60dip" android:gravity="center" android:textsize="20sp"/> <LinearLayout android:layout_height="90dip"> <ImageView android:layout_width="wrap_content" android:layout_marginleft="20dip" android:layout_marginright="10dip"/> <ImageView android:layout_width="wrap_content" android:layout_marginleft="10dip"/> </LinearLayout> <LinearLayout android:layout_height="90dip"> <ImageView android:layout_width="wrap_content" android:layout_marginleft="20dip" android:layout_marginright="10dip"/> <ImageView android:layout_width="wrap_content" android:layout_marginleft="10dip"/> </LinearLayout> <TextView android:text=" 결과 : " android:textsize="18sp" android:layout_height="60dip" android:gravity="center"/>

29 <Button android:text=" 확인 " android:layout_gravity="center" android:layout_width="120dip" android:textsize="16sp"/> </LinearLayout> 프로그램작성 이프로젝트는 project_3 에서사용한알고리즘을그대로사용한다. 단지 TextView 대신 Image View를사용하는것이다를뿐이다. 그래픽이미지가 2장이있으므로이것을다음과같이배열에넣고시작한다. int imgyut[] = {R.drawable.yut_0, R.drawable.yut_1}; ImageView의그래픽이미지를바꿔주는부분은 setimageresource( ) 메서드를사용하여처리한다. ((ImageView) findviewbyid(r.id.imageview01)).setimageresource(imgyut[n1]); MainActivity.java package com.project4; import java.util.*; import android.app.activity; import android.os.bundle; import android.view.*; import android.widget.*; public class MainActivity extends Activity { int imgyut[] = {R.drawable.yut_0, R.drawable.yut_1}; String Yut[] = {" 윷 ", " 도 ", " 개 ", " 걸 ", " 모 public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); 1.5 윷놀이 (2) 29

30 } findviewbyid(r.id.button01).setonclicklistener(mybuttonclick); // // Button OnClickListener // Button.OnClickListener mybuttonclick = new Button.OnClickListener() { public void onclick(view v) { Random rnd = new Random(); int n1 = 1 - rnd.nextint(10) / 6; int n2 = 1 - rnd.nextint(10) / 6; int n3 = 1 - rnd.nextint(10) / 6; int n4 = 1 - rnd.nextint(10) / 6; int n = n1 + n2 + n3 + n4; } }; } ((ImageView) findviewbyid(r.id.imageview01)).setimageresource(imgyut[n1]); ((ImageView) findviewbyid(r.id.imageview02)).setimageresource(imgyut[n2]); ((ImageView) findviewbyid(r.id.imageview03)).setimageresource(imgyut[n3]); ((ImageView) findviewbyid(r.id.imageview04)).setimageresource(imgyut[n4]); ((TextView) findviewbyid(r.id.textview05)).settext(yut[n]); 그림 1-13 프로그램실행결과 30