前回作った簡単なボールとブロックの落ちゲーアプリで、今回はintentという呪文を使って
別の画面を表示させるやり方について解説します。
Intentの書き方
val intent = Intent(this,遷移先::class.java)
startActivity(intent)
None of the following functions can be called with the arguments supplied
「提供された引数では次の関数のいずれも呼び出せません」
と表示された場合は「this@アクティビティ名」と書きます
val intent = Intent(this@アクティビティ名,遷移先::class.java)
startActivity(intent)
動画
コード
▼activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<Button
android:id="@+id/btnLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Left"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnStart"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btnRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnStart" />
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnRight"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnLeft" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/btnStart"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="1dp">
<ImageView
android:id="@+id/ivBall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ball" />
<ImageView
android:id="@+id/ivBlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/block" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
▼MainActivity.kt
package com.example.ballblockgame
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.animation.AccelerateInterpolator
import android.widget.Button
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
class MainActivity : AppCompatActivity() {
//5)制限回数
private var remainingFalls = 5
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//1)viewの取得+ボールを画面の外
val btnLeft:Button = findViewById(R.id.btnLeft)
val btnRight:Button = findViewById(R.id.btnRight)
val btnStart:Button = findViewById(R.id.btnStart)
val ivBall :ImageView = findViewById(R.id.ivBall)
val ivBlock :ImageView = findViewById(R.id.ivBlock)
ivBall.translationY = -200f //起動直後は画面の外
//2)左ボタンを押したら
btnLeft.setOnClickListener {
val params = ivBlock.layoutParams as ConstraintLayout.LayoutParams
params.leftMargin -=50 //左の余白を減らす
ivBlock.layoutParams = params
}
//3)右ボタンを押したら
btnRight.setOnClickListener {
val params = ivBlock.layoutParams as ConstraintLayout.LayoutParams
params.rightMargin -= 50 //右の余白を減らす
ivBlock.layoutParams = params
}
//8)スタートボタン
btnStart.setOnClickListener {
//4)アニメーション
val screenHeight =resources.displayMetrics.heightPixels.toFloat() //画面の高さ
val anim = fallingAnimator(ivBall,ivBlock,screenHeight)//中身は「5」へ
anim.start()
//btnStart.isEnabled = false
}
}
//5)「4」の中身
private fun fallingAnimator(ball:ImageView,block:ImageView,sHeight:Float):ValueAnimator{
// [5-1]X軸(ヨコ幅)の、ランダムな初期位置を設定
val screenWidth = resources.displayMetrics.widthPixels.toFloat()-ball.width //画面幅 -ボール幅
ball.translationX = (Math.random() * screenWidth).toFloat()
val animator = ValueAnimator.ofFloat(0f,sHeight)
animator.duration = 3000 // アニメーションの時間(ミリ秒)
animator.interpolator = AccelerateInterpolator() //アニメーションの加速度
//[5-2]フレームの更新
animator.addUpdateListener { valueAnimator ->
val value = valueAnimator.animatedValue as Float
ball.translationY = value
//6)衝突検出 ⇒条件の中身は「7」へ
if(isColliding(ball,block)){
//衝突したらアニメーションをキャンセル
animator.cancel()
//ボールを枠の外に出す
ball.translationY = -200f//画面の枠のもっと上
}
}
//[5-3]アニメーションの開始、終了、キャンセル、または繰り返しのイベント
animator.addListener(object :Animator.AnimatorListener{
override fun onAnimationStart(animation: Animator) {}
//[5-4]アニメーションが終わったら新しく生成(※回数に達したら終了)
override fun onAnimationEnd(animation: Animator) {
//制限回数を1減らす
remainingFalls--
//制限回数が残っている場合、新しいアニメーションを作成して再生
if(remainingFalls>0){
//アニメーションが終わったら、新しいアニメーションを作成して再生
val newAnimator = fallingAnimator(ball, block, sHeight)
newAnimator.start()
}else{
//9)制限回数が無くなったら終了画面へ
val intent = Intent(this@MainActivity,SecondActivity::class.java)
startActivity(intent)
finish()
}
}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(animation: Animator) {}
})
//[5-5]値を返す
return animator
}
//7)衝突の条件
private fun isColliding(ball:ImageView,block:ImageView):Boolean{
val ballX = ball.x
val ballY = ball.y
val ballWidth = ball.width
val ballHeight = ball.height
val blockX = block.x
val blockY = block.y
val blockWidth = block.width
//val blockHeight = block.height
return ballX<blockX+blockWidth &&
ballX + ballWidth>blockX &&
ballY+ballHeight > blockY
//ballY < blockY + blockHeight
}
}
▼activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:background="#FFEB3B"
tools:context=".SecondActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Game Over"
android:textSize="34sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnReplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Replay"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
▼SecondActivity.kt
package com.example.ballblockgame
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
//10)リプレイボタンを押したら、メイン画面を呼び出す
val btnReplay:Button = findViewById(R.id.btnReplay)
btnReplay.setOnClickListener {
val intent = Intent(this,MainActivity::class.java)
startActivity(intent)
finish()
}
}
}
Intentについて(9)制限回数が無くなったら終了画面へ)
ひとまずテンプレートを書いて行きますが。
val intent = Intent(this,SecondActivity::class.java)
これがテンプレートです
さて、これでOKかと思いきや、何やらIntentのところに、にょろにょろが出ています。なんでやと。
None of the following functions can be called with the arguments supplied
「提供された引数では次の関数のいずれも呼び出せません」
正解を言っておくと
this@MainActivity
と記述します。
そもそもこのthisっていうのは自分自身という意味なんですけど
厳密には「自身のクラス」という意味です。
てことで、今回の場合のthisは、このオブジェクトのクラスをさすので
画面全体を指定する場合には@(アットマーク)に続けて大枠の自身が所属するクラス、今回でいうと
MainActivityを書いてあげる必要がります。
ちなみに@っていれると、もう予測でMainActivityって出ますので、これを選択。
はい、これで赤いエラーが消えました。