Android Studio: Develop Rock Paper Scissors game

계속해서 을 보며 가위바위보 게임을 만들어 봄.(도서 링크: https://amzn.to/2R8Wg07)

가위바위보 이미지 삽입

clip_image001

먼저 구글 검색으로 가위바위보 게임에 사용할 이미지를 구함. 캐릭터 이미지는 이전에 종윤이가 만들어준 것을 활용.

clip_image002

새 프로젝트 만들기

clip_image003

API 16(Android 4.1 Jelly Bean)에 맞춰서 진행

clip_image004

Empty Activity

clip_image005

초기값대로 진행

clip_image006

이미지를 복사하여

clip_image007

이전 글과 동일하게 res\drawable에 붙여넣습니다.

clip_image008

팔레트 -> Images -> ImageButton을 삽입한 뒤, 좌측의 조절점을 잡아 제약 조건 삭제(Delete Constraint).

clip_image009

참고로 이미지 속성은 이러함

clip_image010

일단 3개의 가위바위보 이미지를 한땀한땀 넣고…(ID는 각각 rock, scissors, paper로 지정)

clip_image011

좌측/우측의 연결고리를 만들어준다.

clip_image012

이번에는 우측의 연결점을 서로 연결.

clip_image013

그리고 위쪽 마진을 0으로 설정(위를 맞춰 정렬)

clip_image014

위와 같이 설정. 서로 간 폭은 8, 중간 이미지는 가운데 정렬.

clip_image015

가위바위보 유도 텍스트 삽입.

clip_image016

속성에서 textAppearance를 AppCompat.Large로 설정. 크게 만듦. 그리고 text 속성의 …(Pick a Resource)를 클릭.

clip_image017

New string Value…

clip_image018

  • Resource name: gameText
  • Resource Value: 가위바위보!!

결과 화면 작성

clip_image019

Project 창의 app 에서 New -> Activity -> Empty Activity로 액티비티 추가

clip_image020

액티비티 이름을 적절히 입력. 여기서는 GameOverActivity로 지정.

clip_image021

GameOverActivity.java와 activity_game_over.xml 이 생성됨.

clip_image022

activity_game_over.xml 파일을 열어 TextView 추가

clip_image023

ID와 textApperance 설정

clip_image024

ImageView를 넣고, 자신이 낸 손가락 모양을 표시할 ImageView 팔레트 추가. 크기는 160dp x 160dp 정도로 하자. ID를 적절히 입력.

clip_image025

이번에는 컴퓨터의 손 모양을 보여줄 ImageView. 300dp x 200dp 정도로 하자. ID도 넣어야 한다.

clip_image026

버튼 추가. Widgets -> Button을 드래그.

clip_image027

버튼의 text 속성의 …(Pick a Resource) 클릭

clip_image028

New string Value…

clip_image029

  • Resource name: back_txt
  • Resource value: 뒤로가기 (이후에 ‘뒤로’로 고침)

팁: 텍스트 고칠 때는 Language -> Edit Translations 기능을 활용하자. 이전 글 참고.

clip_image030

뒤로 단추는 작게 만들었다.

ConstraintLayout 편집 기능

clip_image031

편집기의 위쪽을 보면 현재 ConstraintLayout 편집에 필요한 버튼들이 나열되어 있다.

  1. Show: Constraint 레이아웃 및 Margins 표시/비표시
  2. Turn on/off Autoconnect: 오브젝트(위젯)를 배치할 때 제약, 관계(Constraint)을 자동 추가. 자동으로 이웃한 위젯이나 화면 경계간 관계를 지정
  3. Clear all Constraint: 모든 관계, 제약(Constraint)을 삭제. 현재 설정되어 있는 관계들을 모두 제거
  4. Infer Constraint: 화면의 전체 위젯들의 상태를 기반으로 관계, 제약 지정
  5. Default Margins: 기본 Margins 설정
  6. Pack: 여러 위젯의 복수의 뷰를 가로세로로 정렬하거나, 사이즈를 변경
  7. Align: 정렬 설정
  8. 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를 참고.

참고로

clip_image032

가이드라인을 추가해 이동시켜 활용 가능.

참고로…

clip_image033

삐쭉삐쭉한 선은 컨텐츠 사이즈에 맞추는(Wrap Content) 부분이며,

clip_image034

직선은 고정 크기(Fixed).

Intent를 통한 화면 이동

clip_image035

팁: 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);
    }

clip_image036

activity_main.xml의 가위바위보를 모두 선택(Shift + 클릭 클릭)하고, 속성창의 View all attributes를 눌러 onClick에 onRockPaperScissorsTapped 메소드를 연결해준다.(이러면 한 번에 3개의 위젯에 속성이 적용됨)

실행

clip_image037

실행~

clip_image038

가위바위보 중에 아무 것이나 누르면 화면 전환! 전환 효과가 조금 어색하지만, 성공적이다.

이동 화면에 데이터 전달

clip_image039

onRockPaperScissorsTapped 메소드에 코드 추가.

        // putExtra 메소드로 탭한 버튼의 ID를 intent에 저장
        intent.putExtra("MY_HAND", view.getId());

clip_image040

이번에는 GameOverActivity.java에 소스 코드 추가

        // getIntent를 사용하여 intent를 얻는다.
        Intent intent = getIntent();
        // intent에 저장된 정보를 get~Extra를 통해 얻는다.
        int id = intent.getIntExtra("MY_HAND", 0);

Live Template을 사용해 입력

clip_image041

아래에 ImageView myHandImgView = 를 입력 후, Ctrl + J를 눌러 Live Template를 삽입. 코드 자동완성 기능이라고 보면 된다.

clip_image042

int형 my_hand_img를 선택.

clip_image043

Language -> Edit Translations 에서 텍스트 편집

clip_image044

Add Key

clip_image045

Key: resWin

Default Value: 승리했습니다!

clip_image046

  • resWin / 승리했습니다!
  • resLose / CPU가 이겼습니다…
  • resDraw / 비겼습니다~

clip_image047

계속해서 소스 코드 입력. 전체 소스 코드는 아래와 같다.

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;
        }
    }
}

clip_image048

이제 다시 실행해보면 가위바위보 게임이 제대로 동작한다.

뒤로 가기 버튼

clip_image049

GameOverActivity.java에서 뒤로 가기 메소드를 만들어,

clip_image050

onClick 이벤트로 연결.

clip_image051

이제 ‘뒤로’를 누르면 첫 화면으로 돌아온다. 오늘은 여기까지.

이것도 살펴보세요!

Vue3: 프로젝트 폴더/파일 구성, ESLint

새로 만든 Vue 프로젝트의 폴더/파일 구성 폴더/파일내용.vscodeVisual Studio용 설정 파일dist배포용 파일 세트를 저장node_modules라이브러리를 저장public웹으로 공개할 …

2 댓글

  1. 제발..가위바위보 게임 새로 하나만 만들어서 파일로보내주세요..진짜제발요…

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다