今回はブロック崩しアプリを制作しました。
YouTubeに作っている動画をアップしています。
https://www.youtube.com/watch?v=LO1qsMSMY-4&list=PLhg2PHSq8bjjav93XL0ycJSu2g7rD7f80
Ball.java
package com.example.breakoutapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class Ball extends View {
public int x ,y ,radius;
Paint paint;
public Ball(Context context){
super(context);
radius = 20;
x = 0;
y = 0;
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
}
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawCircle(x , y , radius ,paint);
}
}
Block.java
package com.example.breakoutapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;
public class Block extends View {
public int left,top,right,bottom;
public Paint paint;
public Block(Context context) {
super(context);
left = 0;
top = 0;
right = 0;
bottom = 0;
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect(left,top,right,bottom);
canvas.drawRect(rect,paint);
}
}
MainActivity.java
package com.example.breakoutapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Block[][] block;
Ball ball;
Handler handler = new Handler();
Runnable runnable;
int width, height, dx = 10, dy = 10, tap, WC = ViewGroup.LayoutParams.WRAP_CONTENT, breakBlocks = 0;
int colSize = 8, rowSize = 6;//サイズ変更可能
Block bar;
RelativeLayout relativeLayout;
TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// レイアウト作成
relativeLayout = new RelativeLayout(this);
relativeLayout.setBackgroundColor(Color.LTGRAY);
setContentView(relativeLayout);
// 中心テキストをセット
text = new TextView(this);
text.setText("START");
text.setTextSize(36);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(WC, WC);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
relativeLayout.addView(text, params);
// スクリーンのサイズを取得
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
width = point.x;
height = point.y;
// Ballを生成
ball = new Ball(MainActivity.this);
ball.x = width / 2;
ball.y = height / 2;
relativeLayout.addView(ball);
// barを生成
bar = new Block(MainActivity.this);
bar.left = width / 3;
bar.right = width / 3 * 2;
bar.top = height / 5 * 4;
bar.bottom = height / 5 * 4 + 20;
relativeLayout.addView(bar);
// blockを生成
block = new Block[colSize][rowSize];
for (int row = 0; row < rowSize; row++) {
for (int col = 0; col < colSize; col++) {
block[col][row] = new Block(MainActivity.this);
switch (row) {
case 0:
block[col][row].paint.setColor(Color.rgb(251, 139, 255));
break;
case 1:
block[col][row].paint.setColor(Color.rgb(255, 77, 23));
break;
case 2:
block[col][row].paint.setColor(Color.rgb(255, 180, 139));
break;
case 3:
block[col][row].paint.setColor(Color.rgb(239, 253, 51));
break;
case 4:
block[col][row].paint.setColor(Color.rgb(148, 225, 47));
break;
case 5:
block[col][row].paint.setColor(Color.rgb(0, 180, 240));
break;
}
block[col][row].left = (width - (colSize - 1) * 2) / colSize * col + col * 2;
block[col][row].right = (width - (colSize - 1) * 2) / colSize * (col + 1) + col * 2;
block[col][row].top = height / 36 * (row + 3) + row * 2;
block[col][row].bottom = height / 36 * (row + 4) + row * 2;
relativeLayout.addView(block[col][row]);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// タッチされたときにテキストを隠す
text.setText("");
// 指のX座標を取得
tap = (int) event.getX();
// 繰り返し処理
runnable = new Runnable() {
@Override
public void run() {
// 指のX座標をもとにbarを動かす
bar.left = tap - (width / 6);
bar.right = tap + (width / 6);
// ballの位置を動かす
ball.x += dx;
ball.y += dy;
// 画面端、barにぶつかった時、跳ね返らす
if (ball.x <= ball.radius) {
dx = -dx;
} else if (ball.x >= width - ball.radius) {
dx = -dx;
}
if (ball.y <= ball.radius) {
dy = -dy;
} else if ((ball.y + ball.radius >= bar.top - 5) &&
(ball.y + ball.radius <= bar.top + 5) &&
(ball.x + ball.radius <= bar.right) &&
(ball.x - ball.radius >= bar.left)) {
dy = -dy;
} else if (ball.y >= height - ball.radius) {
// GAMEOVER処理、
dy = 0;
dx = 0;
text.setText("GAMEOVER");
text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
// ブロックの当たり判定と、ぶつかった時の処理はbreakBlockメソッドを実行
for (int row = 0; row < rowSize; row++) {
for (int col = 0; col < colSize; col++) {
if ((ball.x + ball.radius <= block[col][row].left + 5) &&
(ball.x + ball.radius >= block[col][row].left - 5) &&
(ball.y <= block[col][row].bottom) &&
(ball.y >= block[col][row].top)) {
dx = -dx;
breakBlock(col, row);
}
if ((ball.x - ball.radius <= block[col][row].right + 5) &&
(ball.x - ball.radius >= block[col][row].right - 5) &&
(ball.y - ball.radius < block[col][row].bottom) &&
(ball.y + ball.radius > block[col][row].top)) {
dx = -dx;
breakBlock(col, row);
}
if ((ball.y - ball.radius <= block[col][row].bottom + 5) &&
(ball.y - ball.radius >= block[col][row].bottom - 5) &&
(ball.x >= block[col][row].left) &&
(ball.x <= block[col][row].right)) {
dy = -dy;
breakBlock(col, row);
}
if ((ball.y + ball.radius <= block[col][row].top + 5) &&
(ball.y + ball.radius >= block[col][row].top - 5) &&
(ball.x >= block[col][row].left) &&
(ball.x <= block[col][row].right)) {
dy = -dy;
breakBlock(col, row);
}
double leftSpace = Math.pow(block[col][row].left - ball.x, 2);
double bottomSpace = Math.pow(block[col][row].bottom - ball.y, 2);
double rightSpace = Math.pow(block[col][row].right - ball.x, 2);
double topSpace = Math.pow(block[col][row].top - ball.y, 2);
if (leftSpace + bottomSpace <= Math.pow(ball.radius, 2)) {
dy = -dy;
dx = -dx;
breakBlock(col, row);
}
if (leftSpace + topSpace <= Math.pow(ball.radius, 2)) {
dy = -dy;
dx = -dx;
breakBlock(col, row);
}
if (rightSpace + bottomSpace <= Math.pow(ball.radius, 2)) {
dy = -dy;
dx = -dx;
breakBlock(col, row);
}
if (rightSpace + topSpace <= Math.pow(ball.radius, 2)) {
dy = -dy;
dx = -dx;
breakBlock(col, row);
}
}
}
handler.removeCallbacks(runnable);
relativeLayout.removeView(bar);
relativeLayout.removeView(ball);
relativeLayout.addView(ball);
relativeLayout.addView(bar);
handler.postDelayed(runnable, 10);
}
};
handler.postDelayed(runnable, 10);
return super.onTouchEvent(event);
}
public void breakBlock(int col, int row) {
// blockにballがぶつかった時の処理
block[col][row].top = -10;
block[col][row].bottom = -10;
block[col][row].setVisibility(View.GONE);
// GAMECLEARの処理
breakBlocks++;
if (breakBlocks == rowSize * colSize) {
dx = 0;
dy = 0;
text.setText("CLEAR!!");
}
}
}
YouTubeに作っている動画をアップしています。
https://www.youtube.com/watch?v=LO1qsMSMY-4&list=PLhg2PHSq8bjjav93XL0ycJSu2g7rD7f80
以上。