Since the other day, I have been creating a metronome to create a music game on android. The rough composition of the metronome is ・ You can set the BPM yourself ・ Movement is fixed at 4 beats ・ The lamp that corresponds to the sound lights up one beat at a time. And so on.
I created an app GUI based on the above configuration.
mainactivity.xml
<ImageView
android:id="@+id/image1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="67dp"
android:layout_marginLeft="67dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
app:layout_constraintEnd_toStartOf="@+id/image2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/en" />
<ImageView
android:id="@+id/image2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
app:layout_constraintEnd_toStartOf="@+id/image3"
app:layout_constraintStart_toEndOf="@+id/image1"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/en" />
<ImageView
android:id="@+id/image3"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
app:layout_constraintEnd_toStartOf="@+id/image4"
app:layout_constraintStart_toEndOf="@+id/image2"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/en" />
<ImageView
android:id="@+id/image4"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="67dp"
android:layout_marginRight="67dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/image3"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/en" />
<EditText
android:id="@+id/BpM"
android:layout_width="192dp"
android:layout_height="50dp"
android:layout_marginTop="95dp"
android:layout_marginEnd="54dp"
android:layout_marginRight="54dp"
android:ems="10"
android:inputType="textPersonName"
android:text="120"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="BPM:"
android:textSize="26sp"
app:layout_constraintEnd_toStartOf="@+id/BpM"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/strat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="67dp"
android:layout_marginLeft="67dp"
android:layout_marginBottom="102dp"
android:text="Start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/End"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="68dp"
android:layout_marginRight="68dp"
android:layout_marginBottom="102dp"
android:text="END"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
The program created next is described below.
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.InputType;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
ImageView Image1,Image2,Image3,Image4;
int i,Delay;
float X_Data,Y_Data,Z_Data;
TextView text1;
private Timer timer;
private CountUpTimerTask timerTask;
private Handler handler = new Handler();
SoundPool soundPool;
int mp3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
Image1 = findViewById(R.id.image1);
Image2 = findViewById(R.id.image2);
Image3 = findViewById(R.id.image3);
Image4 = findViewById(R.id.image4);
Button startButton = findViewById(R.id.strat);
Button endButton = findViewById(R.id.End);
EditText et = findViewById(R.id.BpM);
Image1.setImageResource(R.drawable.en);
Image2.setImageResource(R.drawable.en);
Image3.setImageResource(R.drawable.en);
Image4.setImageResource(R.drawable.en);
//Allow only numbers to be entered in EditText
et.setInputType(InputType.TYPE_CLASS_NUMBER);
//Convert input value to int type
String bpm = ((EditText)findViewById(R.id.BpM)).getText().toString();
int BPM = Integer.parseInt((bpm));
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
} else {
AudioAttributes attr = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(attr)
.setMaxStreams(5)
.build();
}
mp3 = soundPool.load(this,R.raw.pop,1);
//STARTButton
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
i=0;
String bpm = ((EditText)findViewById(R.id.BpM)).getText().toString();
int BPM = Integer.parseInt((bpm));
Delay = 60000/BPM;
Image1.setImageResource(R.drawable.en);
Image2.setImageResource(R.drawable.en);
Image3.setImageResource(R.drawable.en);
Image4.setImageResource(R.drawable.en);
if(null != timer){
timer.cancel();
timer = null;
}
timer = new Timer();
timerTask = new CountUpTimerTask();
timer.schedule(timerTask,0,Delay);
}
});
//ENDButton
endButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(null != timer){
timer.cancel();
timer=null;
}
Image1.setImageResource(R.drawable.en);
Image2.setImageResource(R.drawable.en);
Image3.setImageResource(R.drawable.en);
Image4.setImageResource(R.drawable.en);
}
});
}
class CountUpTimerTask extends TimerTask{
@Override
public void run(){
handler.post(new Runnable() {
@Override
public void run() {
if (i == 0) {
Image1.setImageResource(R.drawable.eng);
Image4.setImageResource(R.drawable.en);
soundPool.play(mp3,2 , 2, 0, 0, 1f);
i++;
}
else if (i == 1) {
Image1.setImageResource(R.drawable.en);
Image2.setImageResource(R.drawable.eng);
soundPool.play(mp3,2 , 2, 0, 0, 1f);
i++;
}
else if (i == 2) {
Image2.setImageResource(R.drawable.en);
Image3.setImageResource(R.drawable.eng);
soundPool.play(mp3,2 , 2, 0, 0, 1f);
i++;
}
else {
Image3.setImageResource(R.drawable.en);
Image4.setImageResource(R.drawable.eng);
soundPool.play(mp3,2 , 2, 0, 0, 1f);
i = 0;
}
}
});
}
}
}
In this program, I don't know if it's due to android or the program, but there is a slight lag during operation. I would like to improve that. The next thing to add is that I want to make a sound every time I shake android in various directions, and I am currently trying to incorporate changes in the accelerometer into the metronome.
Recommended Posts