본문 바로가기
IT/Android

안드로이드 - 간단한 주사위 게임 앱 만들기

by sgoho01 2019. 11. 24.

안드로이드

주사위 게임 앱

코틀린 프로젝트로 간단한 주사위 게임 앱을 만들어보자.

해당 내용은 양재동 코드랩의 '안드로이드앱 완성' 코드랩을 듣고 내용 정리한 글이다.

  • 코틀린 프로젝트 생성은 이전 포스트에서 만든 코틀린 프로젝트를 이용하여 프로젝트를 만든다.

화면 레이아웃 변경

  • 화면 레이아웃을 LinearLayout으로 변경한다.
  • 레이아웃을 ConstraintLayout 에서 LinearLayout으로 변경한뒤 android:orientation="vertical"을 추가해준다. 해당 옵션은 레이아웃 안에서 세로로 배치하겠다는 옵션이다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

처음 생성된 기본 레이아웃은 androidx.constraintlayout.widget.ConstraintLayout인데 해당 레이아웃은 위치를 잡아줘야 하는데 이번 프로젝트는 간단한 테스트용이기 때문에 레이아웃을 LinearLayout으로 변경하여 진행하였다.

화면에 뷰 추가

  • 메인 화면에 버튼 한개를 추가하여 주사위 굴리기 버튼을 한개 생성한다.
<TextView
    ../>
<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="onRollClick"
    android:text="굴려라" />
  • android:id 는 해당 뷰의 아이디를 지정할수 있고, android:onClick 은 해당 버튼을 클릭했을때 실행 할 동작을 추가할 수 있다.추가한 버튼의 클릭이벤트 생성
  • 버튼의 onClick의 이벤트를 생성하려면 해당 화면 클래스로 와서 onRollClick 이벤트를 생성해 준다.
  • 해당 이벤트는 1~6의 랜덤 숫자를 가져와 Toast로 나온 숫자를 출력해 주는 기능을 한다.
    class MainActivity : AppCompatActivity() {

        ..

        fun onRollClick(v: View) {
            // Random은 kotlin에 있는 라이브러리를 임포트
            var diceNumber = Random.nextInt(1, 7)   
            // Toast는 핸드폰의 하단에 안내메시지 창이 잠깐 올라왔다가 없어지는 창이다.
            // 입력한 인수는 띄워질 액티비티, 메시지, Toast창 띄워지는 길이 순 이다.
            Toast.makeText(this, "$diceNumber", Toast.LENGTH_SHORT).show()
        }   

    }

주사위 이미지 저장 & 이미지 뷰 추가

    • 주사위 이미지 XML을 res/drawable로 복사한다. drawable
    • 해당 주사위 이미지를 보여줄 이미지 뷰를 추가한다. 기존의 TextView에 주사위 번호를 표현해주기 위해 id를 추가한다.
<TextView
        android:id="@+id/tvDiceNumber"
        ../>
<Button
      ../>
<ImageView
         android:id="@+id/imageView"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:srcCompat="@drawable/empty_dice" />
      • app:srcCompat는 이미지 경로를 지정하는데 기본 이미지로 빈 주사위 이미지인 drawable/empty_dice를 지정한다.
    • 이미지뷰를 추가했으면 코드에서도 해당 이미지뷰를 등록하고 아까 랜덤으로 생성한 숫자로 해당 번호 맞는 이미지를 이미지뷰에 보여지도록 수정해보자. 추가로 나온 번호를 기존에 있던 TextView에 출력해보자.
  class MainActivity : AppCompatActivity() {

      private lateinit var diceTextView: TextView
      private lateinit var diceImageView: ImageView

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)

          diceTextView = findViewById(R.id.tvDiceNumber)
          diceImageView = findViewById(R.id.imageView)
      }

      fun onRollClick(v: View) {
          var diceNumber = Random.nextInt(1, 7)

          diceTextView.setText("주사위 번호 : $diceNumber")

          when (diceNumber) {        // java의 switch 구문
              1 -> diceImageView.setImageResource(R.drawable.dice_1)
              2 -> diceImageView.setImageResource(R.drawable.dice_2)
              3 -> diceImageView.setImageResource(R.drawable.dice_3)
              4 -> diceImageView.setImageResource(R.drawable.dice_4)
              5 -> diceImageView.setImageResource(R.drawable.dice_5)
              6 -> diceImageView.setImageResource(R.drawable.dice_6)
          }
      }
  }
    • onRollClick 이벤트에서 이미지를 불러 올때에는 이미지뷰의 setImageResource로 저장한 이미지 경로의 이미지를 불러오면 되는데 불러올땐 기존 뷰를 불러오는 R.id가 아니라 drawable폴더의 파일을 가져오므로 R.drawable의 이미지 파일을 불러오면 된다.

  • 굴려라 버튼을 클릭하면 위 TextView의 주사위 번호가 찍히고 주사위 번호에 해당하는 이미지를 불러와 ImageVIew에 이미지를 보여준다.

주사위 번호 맞추기

    • 주사위를 굴리기전 번호를 입력하여 랜덤으로 나온 주사위 번호와 맞는지 체크하는걸 추가해보자.
    • 셀렉트 박스를 이용하여 번호를 입력해도 되지만 간단하게 숫자를 입력받는 방법으로 하였다.
<TextView
          ... />

<EditText
          android:id="@+id/editText"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:ems="10"
          android:inputType="numberDecimal"
          android:textSize="24sp" />

<Button
        ... />

<ImageView
           ... />
...
    private lateinit var diceEditText: EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        diceEditText = findViewById(R.id.editText)
    }

    fun onRollClick(v: View) {
        ...
        var inputValue = diceEditText.getText().toString()

        if(diceNumber === inputValue.toInt()){
            Toast.makeText(this, "정답입니다.", Toast.LENGTH_SHORT).show()
        }else{
            Toast.makeText(this, "틀렸습니다.", Toast.LENGTH_SHORT).show()
        }
    }

다른 액티비티 추가

    • 주사위 게임의 결과를 다른 액티비티를 생성하여 해당 액티비티에서 확인할 수 있도록 새로운 액티비티를 추가해보자. (새로운 액티비티를 열게되면 이전 액티비트는 닫히도록 한다)
    • 액티비티를 추가하는 방법은 프로젝트 패키지에서 마우스 오른쪽 클릭하여 new > Activity > Empty Activity를 클릭하면 화면 xml과 액티비티 코드파일이 자동으로 생성된다.
<TextView
          android:id="@+id/tvResult"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_margin="20dp"
          android:gravity="center"
          android:text="TextView"
          android:textColor="#FF0000"
          android:textSize="36sp" />
      • 결과 화면도 LinearLayout으로 변경 한뒤 뷰를 생성하자.
class ResultActivity : AppCompatActivity() {

    private lateinit var resultTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)

        resultTextView = findViewById(R.id.tvResult)
    }
}        
      • 결과를 출력할 뷰를 가져온다.
    • 이제 기존 액티비티에서 새로운 액티비티를 호출을 해보자
MainActivity.kt

fun onRollClick(v: View) {
    ...
    var inputValue = diceEditText.getText().toString()

    // 새로운 액티비티를 연결하는 Intent를 만든다.
    var resultIntent = Intent(this, ResultActivity::class.java)

    if(diceNumber === inputValue.toInt()){
        // 호출할 액티비티로 보낼 데이터를 저장한다.
        resultIntent.putExtra(ResultActivity.KEY_RESULT, "정답입니다.")
    }else{
        resultIntent.putExtra(ResultActivity.KEY_RESULT, "틀렸습니다.")
    }

    // 새로운 액티비티를 불러온다.
    startActivity(resultIntent)
    // 새로운 액티비티를 호출한뒤 이전 액티비티는 종료한다.
    finish()
}
ResultActivity.kt
class ResultActivity : AppCompatActivity() {
  ..

  override fun onCreate(savedInstanceState: Bundle?) {
      ..

      // 이전 액티비티에서 결과를 전달 받는다.
      var result = getIntent().getStringExtra(KEY_RESULT)

      resultTextView.setText(result)
  }

  // 자바의 상수와 같다.
  companion object {
      const val KEY_RESULT = "KEY_RESULT"
  }

}
  • 다른 액티비티를 호출하기 위해서는 Intent를 생성하여 불러올 액티비티 정보를 넣어주고 보낼 데이터를 putExtra(key, value형식)로 넣어 준뒤 새로운 액티비티에서 getInent().getIntExtra() 또는 getIntent().getStringExtra() 와 같이 타입에 맞춰서 데이터를 가져와 사용할 수 있다.
  • ResultActivity의 마지막 라인에 있는 companion object는 자바의 상수와 같은것인데 코틀린에서는 위와 같이 쓰인다. Intent로 넣고 뺄때 KEY값은 타입세이프하기위해 상수로 정의하여 사용하였다.
번호 입력할 때 번호 Validation 체크, 닉네임 추가 등 위 소스에서 추가된 내용은 Github에 올려놓았으니 추후 복습시 참고하자.

댓글