계속해서 책을 보며 가위바위보 게임을 만들어 봄.(도서 링크: https://amzn.to/2R8Wg07)
가위바위보 이미지 삽입
먼저 구글 검색으로 가위바위보 게임에 사용할 이미지를 구함. 캐릭터 이미지는 이전에 종윤이가 만들어준 것을 활용.
새 프로젝트 만들기
API 16(Android 4.1 Jelly Bean)에 맞춰서 진행
Empty Activity
초기값대로 진행
이미지를 복사하여
이전 글과 동일하게 res\drawable에 붙여넣습니다.
팔레트 -> Images -> ImageButton을 삽입한 뒤, 좌측의 조절점을 잡아 제약 조건 삭제(Delete Constraint).
참고로 이미지 속성은 이러함
일단 3개의 가위바위보 이미지를 한땀한땀 넣고…(ID는 각각 rock, scissors, paper로 지정)
좌측/우측의 연결고리를 만들어준다.
이번에는 우측의 연결점을 서로 연결.
그리고 위쪽 마진을 0으로 설정(위를 맞춰 정렬)
위와 같이 설정. 서로 간 폭은 8, 중간 이미지는 가운데 정렬.
가위바위보 유도 텍스트 삽입.
속성에서 textAppearance를 AppCompat.Large로 설정. 크게 만듦. 그리고 text 속성의 …(Pick a Resource)를 클릭.
New string Value…
- Resource name: gameText
- Resource Value: 가위바위보!!
결과 화면 작성
Project 창의 app 에서 New -> Activity -> Empty Activity로 액티비티 추가
액티비티 이름을 적절히 입력. 여기서는 GameOverActivity로 지정.
GameOverActivity.java와 activity_game_over.xml 이 생성됨.
activity_game_over.xml 파일을 열어 TextView 추가
ID와 textApperance 설정
ImageView를 넣고, 자신이 낸 손가락 모양을 표시할 ImageView 팔레트 추가. 크기는 160dp x 160dp 정도로 하자. ID를 적절히 입력.
이번에는 컴퓨터의 손 모양을 보여줄 ImageView. 300dp x 200dp 정도로 하자. ID도 넣어야 한다.
버튼 추가. Widgets -> Button을 드래그.
버튼의 text 속성의 …(Pick a Resource) 클릭
New string Value…
- Resource name: back_txt
- Resource value: 뒤로가기 (이후에 ‘뒤로’로 고침)
팁: 텍스트 고칠 때는 Language -> Edit Translations 기능을 활용하자. 이전 글 참고.
뒤로 단추는 작게 만들었다.
ConstraintLayout 편집 기능
편집기의 위쪽을 보면 현재 ConstraintLayout 편집에 필요한 버튼들이 나열되어 있다.
- Show: Constraint 레이아웃 및 Margins 표시/비표시
- Turn on/off Autoconnect: 오브젝트(위젯)를 배치할 때 제약, 관계(Constraint)을 자동 추가. 자동으로 이웃한 위젯이나 화면 경계간 관계를 지정
- Clear all Constraint: 모든 관계, 제약(Constraint)을 삭제. 현재 설정되어 있는 관계들을 모두 제거
- Infer Constraint: 화면의 전체 위젯들의 상태를 기반으로 관계, 제약 지정
- Default Margins: 기본 Margins 설정
- Pack: 여러 위젯의 복수의 뷰를 가로세로로 정렬하거나, 사이즈를 변경
- Align: 정렬 설정
- Guidelines: 가로세로 가이드라인 추가. 가이드라인에 뷰를 부착하고 제약 조건을 만든 이후에 가이드라인을 이동해서 부착된 모든 뷰의 위치를 변경 가능.
새로운 에디터를 개발하면서 저는 정말 강력하고 사용하기 쉬운 도구가 되길 바랬습니다. 이를 위해선 ID로 작업하기 쉽도록 좀 더 강력하고 유연한 뷰그룹이 필요했습니다. 그 결과 매우 유연한 ConstraintLayout를 만들 수 있었습니다. 특히, 단순한 계층 구조로 만들어낼 수 있다는 장점이 있습니다. 또한 ConstraintLayout이 번들되지 않는 라이브러리라는 점이 개발자와 라이브러리 제작자가 눈여겨봐야 할 점입니다. 개발자가 완전히 통제할 수 있다는 것이 장점이죠. 뭔가를 읽었다면 바로 이해하고 결정할 수 있습니다. 여러분에게 맞는 버전을 사용할 수도 있습니다. 저희가 다음 날 다른 버전을 내놓더라도 여러분에 코드에는 영향을 미치지 않죠. 이 이유가 저희 개발진에게도 장점이 됩니다. 새 버전을 내더라도 개발자들의 코드가 에러를 낼까봐 걱정하지 않아도 됩니다. 기존 API를 지우고 새로운 기능을 넣는 것도 문제 없습니다. 또한 번될되지 않기 때문에 어떤 기기에서도 사용이 가능합니다.
출처: <https://academy.realm.io/kr/posts/constraintlayout-it-can-do-what-now/>
realm.io에 기재된 위의 기사를 보면 ConstraintLayout 개발자의 이야기를 들을 수 있어서 도움이 된다.
Pack 버튼 등의 결과는 Stackoverflow의 How to add Chains feature of constraint layout with design in android studio를 참고.
참고로
가이드라인을 추가해 이동시켜 활용 가능.
참고로…
삐쭉삐쭉한 선은 컨텐츠 사이즈에 맞추는(Wrap Content) 부분이며,
직선은 고정 크기(Fixed).
Intent를 통한 화면 이동
팁: javadoc 주석을 빨리 넣으려면 /** (엔터) 또는 Shift + Ctrl + A 를 누른 후, ‘Fix doc comment’를 검색해 실행하면 된다. (관련 링크)
MainActivity.java의 onCreate 메소드 아래에 아래 소스 코드 추가
/** * onClick 프로퍼티 설정으로 불러들이는 메소드. 인수 view를 받아들임. * @param view */ public void onRockPaperScissorsTapped(View view) { // 액티비티를 열기 위해, 열고 싶은 액티비티를 지정, Intent 클래스의 인스턴스를 생성해서... Intent intent = new Intent(this, GameOverActivity.class); // 위 intent 인스턴스를 startActivity 메소드의 인수로 전달. startActivity(intent); }activity_main.xml의 가위바위보를 모두 선택(Shift + 클릭 클릭)하고, 속성창의 View all attributes를 눌러 onClick에 onRockPaperScissorsTapped 메소드를 연결해준다.(이러면 한 번에 3개의 위젯에 속성이 적용됨)
실행
실행~
가위바위보 중에 아무 것이나 누르면 화면 전환! 전환 효과가 조금 어색하지만, 성공적이다.
이동 화면에 데이터 전달
onRockPaperScissorsTapped 메소드에 코드 추가.
// putExtra 메소드로 탭한 버튼의 ID를 intent에 저장 intent.putExtra("MY_HAND", view.getId());이번에는 GameOverActivity.java에 소스 코드 추가
// getIntent를 사용하여 intent를 얻는다. Intent intent = getIntent(); // intent에 저장된 정보를 get~Extra를 통해 얻는다. int id = intent.getIntExtra("MY_HAND", 0);Live Template을 사용해 입력
아래에 ImageView myHandImgView = 를 입력 후, Ctrl + J를 눌러 Live Template를 삽입. 코드 자동완성 기능이라고 보면 된다.
int형 my_hand_img를 선택.
Language -> Edit Translations 에서 텍스트 편집
Add Key
Key: resWin
Default Value: 승리했습니다!
- resWin / 승리했습니다!
- resLose / CPU가 이겼습니다…
- resDraw / 비겼습니다~
계속해서 소스 코드 입력. 전체 소스 코드는 아래와 같다.
public class GameOverActivity extends AppCompatActivity { // 가위바위보에 대한 기본값을 설정 final int gameRock = 0; final int gamePaper = 1; final int gameScissors = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_game_over); // 임시 변수를 만들어 화면에 입력받은 가위바위보 선택을 저장 int myHand = 0; // getIntent를 사용하여 intent를 얻는다. Intent intent = getIntent(); // intent에 저장된 정보를 get~Extra를 통해 얻는다. int id = intent.getIntExtra("MY_HAND", 0); ImageView myHandImgView = (ImageView) findViewById(R.id.my_hand_img); switch (id) { case R.id.rock: myHandImgView.setImageResource(R.drawable.rock0); myHand = gameRock; break; case R.id.paper: myHandImgView.setImageResource(R.drawable.paper0); myHand = gamePaper; break; case R.id.scissors: myHandImgView.setImageResource(R.drawable.scissors0); myHand = gameScissors; break; default: break; } int cpuHand = (int)(Math.random() * 3); ImageView cpuHandImgView = (ImageView) findViewById(R.id.cpu_hand_img); // 랜덤값에 해당되는 컴퓨터 가위바위보 이미지 생성 switch (cpuHand) { case gameRock: cpuHandImgView.setImageResource(R.drawable.rock); break; case gamePaper: cpuHandImgView.setImageResource(R.drawable.paper); break; case gameScissors: cpuHandImgView.setImageResource(R.drawable.scissors); break; } // 승패를 정하기 TextView gameOverLabel = (TextView) findViewById(R.id.gameover_label); int gameOverResult = (cpuHand - myHand + 3) % 3; switch (gameOverResult) { case 0: // 비겼을 때 gameOverLabel.setText(R.string.resDraw); break; case 1: // CPU가 이겼을 때 gameOverLabel.setText(R.string.resLose); break; case 2: // 내가 이겼을 때 gameOverLabel.setText(R.string.resWin); break; } } }이제 다시 실행해보면 가위바위보 게임이 제대로 동작한다.
뒤로 가기 버튼
GameOverActivity.java에서 뒤로 가기 메소드를 만들어,
onClick 이벤트로 연결.
이제 ‘뒤로’를 누르면 첫 화면으로 돌아온다. 오늘은 여기까지.
제발..가위바위보 게임 새로 하나만 만들어서 파일로보내주세요..진짜제발요…
살려주세요…ㅋㅋ