今からはじめるプログラミング59(シューティングその4)

レーザーを追加したけど、なんかこう、爽快感がないですね。

本当はあたり判定とかとかも細かくいじるといいと重いますが、

難しいことは解析能力が不足していて、考えるだけでパンクするので、

とりあえず敵の種類を追加したいと思います。

下にむかってくる敵しかいないので、縦幅の長いレーザーの利点がいかせていない?気がしました。というか、本来は味方の移動に追従するようにレーザーを改造すれば、画面を掃除するような感覚が味わえるのでは?と思ったのですが、さらに難しそうなので、横に移動する敵がいれば、縦の攻撃での判定が大きくなる、という考えのもと、改造することにしました。

とはいえ、Enemyを継承してEnemyH(holizontal)というクラスを新規作成して、ちょっとjavaオブジェクト指向(というほどのことはない)プログラミングしています。

・・・コンストラクタて継承できないんでしたっけ?(忘れました)

というわけで、今回は2つクラスを追加修正。

EnemyHクラス

-------------------------------------------

package sample20;

 

public class EnemyH extends Enemy {

 

public EnemyH(int x, int y)

{

        this.x = x;

        this.y = y;

    }

 

}

-------------------------------------------

 

ま、こんなもんです。

そしてShootingクラスはコメントでどこをどうしたというのを記載しました。

Shootingクラス

-------------------------------------------

 

package sample20;

 

import java.awt.Color;

import java.awt.Font;

import java.awt.FontMetrics;

import java.awt.Graphics;

import java.awt.event.KeyEvent;

import java.util.ArrayList;

import java.util.Random;

 

/**

* @author user

* @modify histories 2022/7/30 レーザー風に 2022/7/31 横に動く敵の追加

*/

public class Shooting {

public static ShootingFrame shootingFrame;

public static boolean loop;

 

public static void main(String[] args) {

shootingFrame = new ShootingFrame();

loop = true;

 

Graphics gra = shootingFrame.panel.image.getGraphics();

 

// FPS

long startTime;

long fpsTime = 0;

int fps = 30;

int FPS = 0;

int FPSCount = 0;

 

EnumShootingScreen screen = EnumShootingScreen.START;

 

// GAME

int playerX = 0, playerY = 0;

int bulletInterval = 0;

int score = 0;

int level = 0;

long levelTimer = 0;

int playerHp = 0;// プレイヤーのHPをついか

ArrayList<Bullet> bullets_player = new ArrayList<>();

ArrayList<Bullet> bullets_enemy = new ArrayList<>();

ArrayList<Enemy> enemies = new ArrayList<>();

// add start 2022/7/31 1 ma2

// 横に移動する敵の追加

ArrayList<EnemyH> enemiesH = new ArrayList<>();

// add end 2022/7/31 1

ArrayList<Ally> allies = new ArrayList<>();

 

Random random = new Random();

 

while (loop) {

if *1 {

screen = EnumShootingScreen.GAME;

bullets_player = new ArrayList<>();

bullets_enemy = new ArrayList<>();

enemies = new ArrayList<>();

allies = new ArrayList<>();

playerX = 235;

playerY = 430;

score = 0;

level = 0;

// スタート時のHP値

playerHp = 5;

}

break;

case GAME:

if (System.currentTimeMillis() - levelTimer > 10 * 1000) {

levelTimer = System.currentTimeMillis();

level++;

}

// Player描画

gra.setColor(Color.BLUE);

gra.fillRect(playerX + 10, playerY, 10, 10);

gra.fillRect(playerX, playerY + 10, 30, 10);

// 玉の削除

 

for (int i = 0; i < bullets_player.size(); i++) {

Bullet bullet = bullets_player.get(i);

// mod start 2022/7/30 1 ma2

// たなのびょうが レーザー風雨に

// gra.fillRect(bullet.x, bullet.y, 5, 5);

gra.fillRect(bullet.x, bullet.y, 4, 20);

// mod end 2022/7/30 1

bullet.y -= 10;

if (bullet.y < 0) {

bullets_player.remove(i);

i--;

}

// 敵の削除=得点追加

for (int l = 0; l < enemies.size(); l++) {

Enemy enemy = enemies.get(l);

// mod start 2022/7/30 2 ma2

// あたり判定 レーザーのあたり判定が爽快感がないので

// if (bullet.x >= enemy.x && bullet.x <= enemy.x + 30

// && bullet.y >= enemy.y

// && bullet.y <= enemy.y + 20) {

if (bullet.x >= enemy.x && bullet.x <= enemy.x + 30 && bullet.y >= enemy.y

&& bullet.y <= enemy.y + 50) {

// mod end 2022/7/30 2

// 敵を削除

enemies.remove(l);

// 点数加算

score += 10;

}

}

// add start 2022/7/31 2 ma2

for (int l = 0; l < enemiesH.size(); l++) {

EnemyH enemyH = enemiesH.get(l);

// あたり判定 TODO

 

if (bullet.x >= enemyH.x && bullet.x <= enemyH.x + 30 && bullet.y >= enemyH.y

&& bullet.y <= enemyH.y + 30) {

// 敵を削除

enemiesH.remove(l);

// 点数加算

score += 10;

}

}

// add end 2022/7/31 2

 

// 味方の削除=HP追加

for (int j = 0; j < allies.size(); j++) {

Ally ally = allies.get(j);

// 玉と味方の判定

if (bullet.x >= ally.x && bullet.x <= ally.x + 10 && bullet.y >= ally.y

&& bullet.y <= ally.y + 10) {

allies.remove(j);

if (playerHp < 10) {

playerHp += 1;

}

 

}

}

 

}

// てき

gra.setColor(Color.RED);

for (int i = 0; i < enemies.size(); i++) {

Enemy enemy = enemies.get(i);

gra.fillRect(enemy.x, enemy.y, 30, 10);

gra.fillRect(enemy.x + 10, enemy.y + 10, 10, 10);

enemy.y += 3;

if (enemy.y > 500) {

enemies.remove(i);

i--;

}

if (random.nextInt(level < 50 ? 80 - level : 30) == 1)

bullets_enemy.add(new Bullet(enemy.x + 12, enemy.y));

if *2 {

// 敵と自分が命中

playerHp--;

if (playerHp <= 0) {

screen = EnumShootingScreen.GAME_OVER;

score += (level - 1) * 100;

} else {

// ぶつかった敵はけす

enemies.remove(i);

}

 

}

}

if (random.nextInt(level < 10 ? 30 - level : 10) == 1)

enemies.add(new Enemy(random.nextInt(470), 0));

// add S 2022/7/31 3 ma2

for (int i = 0; i < enemiesH.size(); i++) {

EnemyH enemyH = enemiesH.get(i);

gra.fillRect(enemyH.x, enemyH.y, 30, 10);

gra.fillOval(enemyH.x + 10, enemyH.y + 10, 10, 10);

 

enemyH.y += 2;// 下に移動するのは少し遅く

enemyH.x += 3;// 横に移動を追加(とりあえずみぎのみ)

 

if (enemyH.y > 500) {

enemiesH.remove(i);

i--;

}

if (random.nextInt(level < 50 ? 80 - level : 30) == 1)

bullets_enemy.add(new Bullet(enemyH.x + 12, enemyH.y));

if *3 {

// 敵と自分が命中

playerHp--;

if (playerHp <= 0) {

screen = EnumShootingScreen.GAME_OVER;

score += (level - 1) * 100;

} else {

// ぶつかった敵はけす

enemiesH.remove(i);

}

 

}

}

// 敵の生成

if (random.nextInt(level < 10 ? 30 - level : 10) == 1)

enemiesH.add(new EnemyH(random.nextInt(470), 0));

 

// add E 2022/7/31 3 ma2

 

// てきのたまのうごき

for (int i = 0; i < bullets_enemy.size(); i++) {

Bullet bullet = bullets_enemy.get(i);

gra.fillRect(bullet.x, bullet.y, 5, 5);

bullet.y += 10;

if (bullet.y > 500) {

bullets_enemy.remove(i);

i--;

}

if (bullet.x >= playerX && bullet.x <= playerX + 30 && bullet.y >= playerY

&& bullet.y <= playerY + 20) {

// 敵の玉と自分が命中

playerHp--;

if (playerHp <= 0) {

screen = EnumShootingScreen.GAME_OVER;

score += (level - 1) * 100;

} else {

// ぶつかったたまはけす

bullets_enemy.remove(i);

}

}

}

// 味方の動き

gra.setColor(Color.GREEN);

for (int i = 0; i < allies.size(); i++) {

Ally ally = allies.get(i);

gra.fillOval(ally.x, ally.y, 10, 10);

ally.y += 3;

if (ally.y > 500) {

allies.remove(i);

i--;

}

if *4 {

// みかたと自分が命中

if (playerHp < 10) {

playerHp += 1;

}

allies.remove(i);

i--;

 

}

}

// 味方の出現

if (random.nextInt(level < 10 ? 30 - level : 10) == 1)

allies.add(new Ally(random.nextInt(470), 0));

 

// キーボードの判定

 

if (Keyboard.isKeyPressed(KeyEvent.VK_LEFT) && playerX > 0)

playerX -= 8;

if (Keyboard.isKeyPressed(KeyEvent.VK_RIGHT) && playerX < 470)

playerX += 8;

if (Keyboard.isKeyPressed(KeyEvent.VK_UP) && playerY > 30)

playerY -= 8;

if (Keyboard.isKeyPressed(KeyEvent.VK_DOWN) && playerY < 450)

playerY += 8;

 

if (Keyboard.isKeyPressed(KeyEvent.VK_SPACE) && bulletInterval == 0) {

bullets_player.add(new Bullet(playerX + 12, playerY));

bulletInterval = 8;

}

if (bulletInterval > 0)

bulletInterval--;

 

gra.setColor(Color.BLACK);

font = new Font("SansSerif", Font.PLAIN, 20);

metrics = gra.getFontMetrics(font);

gra.setFont(font);

gra.drawString("SCORE:" + score, 470 - metrics.stringWidth("SCORE:" + score), 430);

gra.drawString("LEVEL:" + level, 470 - metrics.stringWidth("LEVEL:" + level), 450);

gra.drawString("HP:" + playerHp, 470 - metrics.stringWidth("HP:" + playerHp), 470);

 

break;

case GAME_OVER:

gra.setColor(Color.BLACK);

font = new Font("SansSerif", Font.PLAIN, 50);

gra.setFont(font);

metrics = gra.getFontMetrics(font);

gra.drawString("Game Over", 250 - (metrics.stringWidth("Game Over") / 2), 100);

font = new Font("SansSerif", Font.PLAIN, 20);

gra.setFont(font);

metrics = gra.getFontMetrics(font);

gra.drawString("Score:" + score, 250 - (metrics.stringWidth("Score:" + score) / 2), 150);

gra.drawString("Press ESC to Return Start Screen",

250 - (metrics.stringWidth("Press ESC to Return Start Screen") / 2), 200);

if (Keyboard.isKeyPressed(KeyEvent.VK_ESCAPE)) {

screen = EnumShootingScreen.START;

}

break;

}

 

gra.setColor(Color.BLACK);

gra.setFont(new Font("SansSerif", Font.PLAIN, 10));

gra.drawString(FPS + "FPS", 0, 470);

 

shootingFrame.panel.draw();

 

try {

long runTime = System.currentTimeMillis() - startTime;

if (runTime < (1000 / fps)) {

Thread.sleep*5;

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

-------------------------------------------

 

 

今までの修正と違う修正のしかたするから、統一感が。。。ねぇ?

とても昔の修正履歴の残し方なので、現在ではGitなどではコミットコメントとして記述するのが正しいかな?

アマゾンでパロディウス検索したらいろいろ出てきた。

 

https://amzn.to/3zJqDkQ

 

よろしくです。

遊んでるところ、だいぶ遊べてる?(頭が丸い敵がよこ・・・みぎしたにいどうしている。。。わかるか!って感じですいません。)

横に動く敵を追加

 

*1:System.currentTimeMillis() - fpsTime) >= 1000) {

fpsTime = System.currentTimeMillis();

FPS = FPSCount;

FPSCount = 0;

}

FPSCount++;

startTime = System.currentTimeMillis();

 

gra.setColor(Color.WHITE);

gra.fillRect(0, 0, 500, 500);

 

switch (screen) {

case START:

gra.setColor(Color.BLACK);

Font font = new Font("SansSerif", Font.PLAIN, 50);

gra.setFont(font);

FontMetrics metrics = gra.getFontMetrics(font);

gra.drawString("Shooting", 250 - (metrics.stringWidth("Shooting") / 2), 100);

font = new Font("SansSerif", Font.PLAIN, 20);

gra.setFont(font);

metrics = gra.getFontMetrics(font);

gra.drawString("Press SPACE to Start", 250 - (metrics.stringWidth("Press SPACE to Start") / 2), 160);

if (Keyboard.isKeyPressed(KeyEvent.VK_SPACE

*2:enemy.x >= playerX && enemy.x <= playerX + 30 && enemy.y >= playerY && enemy.y <= playerY + 20)

|| (enemy.x + 30 >= playerX && enemy.x + 30 <= playerX + 30 && enemy.y + 20 >= playerY

&& enemy.y + 20 <= playerY + 20

*3:enemyH.x >= playerX && enemyH.x <= playerX + 30 && enemyH.y >= playerY

&& enemyH.y <= playerY + 20)

|| (enemyH.x + 30 >= playerX && enemyH.x + 30 <= playerX + 30 && enemyH.y + 20 >= playerY

&& enemyH.y + 20 <= playerY + 20

*4:ally.x >= playerX && ally.x <= playerX + 10 && ally.y >= playerY && ally.y <= playerY + 10

*5:1000 / fps) - (runTime