前提・実現したいこと
今、学校の課題でAndroidStudio/JAVAでの簡単なゲームを作成しなければならず、
シューティングゲームのようなものを作成しようとしています。
まだプログラミング自体も初心者で、サンプルのプログラムから作成しようとしていて
https://blog.goo.ne.jp/marunomarunogoo/e/f3d3ebc180046b2c5bf238fb5ed72c8c
のサイトのものが動作的にも分かりやすく、参考にさせていただいていて、これ自体では、正常に動いたのですが、ここに画面遷移を導入したく、まずスタート画面(MainActivity)を表示してそこにボタンを配置し、クリックされたら、ゲームの動作画面(CanvasView)に遷移する、というようなものを作成しようとしてます。
プログラムのコードにはエラー表示もないのですが、エミュレーターに表示させようとすると落ちて、-keeps stoppingと出てしまいます。
分かる方がいらっしゃれば、回答お願いします。
私自身プログラミング自体、初心者なので、細かく教えていただければ幸いです。
目標としては、敵が横移動していて、自機をタップすると球が出て、当たれば、あたり判定が行われる。というような単純なもので、もしほかにおススメのサンプルコードなどありましたら、そちらも教えていただければ幸いです。
よろしくお願いします。
発生している問題・エラーメッセージ
エラーメッセージ
該当のソースコード
MainActivity
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageView;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
class MainActivity extends AppCompatActivity{
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onButton(View view){ Intent intent = new Intent(this,CanvasView.class); startActivity(intent); }
}
画面遷移先↓
CanvasView
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageView;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.TextView;
public class CanvasView extends AppCompatImageView {
public CanvasView(Context context) { super(context); } public static final int BLOCK_SIZE = 20; public static final int NOT_VISIBLE = -1; public static final int DRAWING_INTERVAL = 50; public static final int[][] INVADER_IMAGE = { { 0, 0, 0, 1, 0, 1, 0, 0, 0 }, { 1, 0, 1, 1, 1, 1, 1, 0, 1 }, { 1, 1, 1, 0, 1, 0, 1, 1, 1 }, { 0, 0, 1, 1, 1, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0, 0, 1, 0, 0 }, }; public static final int INVADER_WIDTH = INVADER_IMAGE[0].length * BLOCK_SIZE; public static final int INVADER_HEIGHT = INVADER_IMAGE.length * BLOCK_SIZE; public static final int INVADER_COLOR = Color.GREEN; public static final int INVADER_HITL_COLOR = Color.RED; public static final int INVADER_MOVING_UNIT = 1; public static final int DIRECTION_LEFT = -1; public static final int DIRECTION_RIGHT = 1; public static final int[][] GUN_IMAGE = { { 0, 0, 1, 1, 0, 0 }, { 1, 1, 1, 1, 1, 1 }, }; public static final int GUN_WIDTH = GUN_IMAGE[0].length * BLOCK_SIZE; public static final int GUN_HEIGHT = GUN_IMAGE.length * BLOCK_SIZE; public static final int GUN_MOVING_UNIT = 5; public static final int GUN_COLOR = Color.BLUE; public static final int[][] BULLET_IMAGE = { { 1 }, }; public static final int BULLET_WIDTH = BULLET_IMAGE[0].length * BLOCK_SIZE; public static final int BULLET_HEIGHT = BULLET_IMAGE.length * BLOCK_SIZE; public static final int BULLET_MOVING_UNIT = 50; public static final int BULLET_COLOR = Color.GREEN; private int score = 0; private int invaderPointX = 0; private int invaderPointY = 0; private int invaderMovingUnit = DIRECTION_RIGHT * INVADER_MOVING_UNIT; // (5) private int invaderColor = INVADER_COLOR; private int gunPointX; private int gunPointY; private int bulletPointX = NOT_VISIBLE; // 弾は最初は非表示 private int bulletPointY = NOT_VISIBLE; // 弾は最初は非表示 private TextView scoreView; public CanvasView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } pubuic CanvasView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { score = 0; invaderPointX = 0; invaderPointY = 0; invaderMovingUnit = DIRECTION_RIGHT * INVADER_MOVING_UNIT; invaderColor = INVADER_COLOR; bulletPointX = NOT_VISIBLE; bulletPointY = NOT_VISIBLE; System.out.printf("Canvas: (%d, %d)%n", getWidth(), getHeight()); System.out.printf("Invader: (%d, %d)%n", invaderPointX, invaderPointY); System.out.printf("Gun: (%d, %d)%n", gunPointX, gunPointY); System.out.printf("Bullet: (%d, %d)%n", bulletPointX, bulletPointY); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); System.out.printf("onSizeChanged: (%d, %d)%n", w, h); gunPointX = (w - GUN_WIDTH) / 2; gunPointY = h - GUN_HEIGHT; System.out.printf("Gun: (%d, %d)%n", gunPointX, gunPointY); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); clearScreen(canvas); drawInvader(canvas, invaderPointX, invaderPointY, invaderColor); invaderColor = INVADER_COLOR; drawBullet(canvas, bulletPointX, bulletPointY, BULLET_COLOR); drawGun(canvas, gunPointX, gunPointY, GUN_COLOR); invaderPointX = invaderPointX + invaderMovingUnit; if (isBorder(invaderPointX, INVADER_WIDTH)) { invaderMovingUnit = -invaderMovingUnit; } bulletPointY = bulletPointY - BULLET_MOVING_UNIT; if (isHit()) { score++; invaderColor = INVADER_HITL_COLOR; bulletPointX = NOT_VISIBLE; bulletPointY = NOT_VISIBLE; drawScore(score); } try { Thread.sleep(DRAWING_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: assert true; break; case MotionEvent.ACTION_MOVE: moveGun((int) event.getX()); break; case MotionEvent.ACTION_UP: shot(); break; default: assert true; break; } invalidate(); return true; } private boolean isHit() { return bulletPointY >= 0 && (bulletPointY + BULLET_HEIGHT < invaderPointY + INVADER_HEIGHT) && (invaderPointX < bulletPointX) && (bulletPointX + BULLET_WIDTH < invaderPointX + INVADER_WIDTH); } private boolean isBorder(int x, int width) { return (x < 0) || (x > getWidth() - width); } private void clearScreen(Canvas canvas) { invalidate(); } private void drawInvader(Canvas canvas, int x, int y, int color) { Paint paint = new Paint(); paint.setColor(color); drawImage(canvas, paint, x, y, INVADER_IMAGE); } private void drawBullet(Canvas canvas, int x, int y, int color) { Paint paint = new Paint(); paint.setColor(color); drawImage(canvas, paint, x, y, BULLET_IMAGE); } private void drawGun(Canvas canvas, int x, int y, int color) { Paint paint = new Paint(); paint.setColor(color); drawImage(canvas, paint, x, y, GUN_IMAGE); } private void drawImage(Canvas canvas, Paint paint, int x, int y, int[][] image) { if (x == NOT_VISIBLE || y == NOT_VISIBLE) { return; } for (int i = 0; i < image.length; i++) { for (int j = 0; j < image[0].length; j++) { if (image[i][j] == 1) { canvas.drawRect(x + j * BLOCK_SIZE, y + i * BLOCK_SIZE, x + j * BLOCK_SIZE + BLOCK_SIZE, y + i * BLOCK_SIZE + BLOCK_SIZE, paint); // (11) } } } } private void drawScore(int score) { assert scoreView != null; scoreView.setText(Integer.toString(score)); } public void shot() { bulletPointX = gunPointX + (GUN_WIDTH - BULLET_WIDTH) / 2; bulletPointY = gunPointY; } private void moveGun(int x) { gunPointX = Math.max(Math.min(x, getWidth() - GUN_WIDTH), 0); } public TextView getScoreView() { return scoreView; } public void setScoreView(TextView scoreView) { this.scoreView = scoreView; }
}
試したこと
補足情報(FW/ツールのバージョンなど)
API16:Android 4.1(Jelly Bean)でやってます。
エミュレーター:Nexus6 API29