ショットを複数のキャラに打たせたい。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アズカバンの囚人

ショットを複数のキャラに打たせたい。

#1

投稿記事 by アズカバンの囚人 » 12年前

C言語のところにJavaの質問をするのは、場違いなのかなとも思ったのですが。
アルゴリズムなど考え方的なものは、さほど大きい違いはないと思い、質問させていただきました。
現在、マリオのような横スクロールアクションゲームを作成しているのですが。

キー入力や、ジャンプなどの実装も出来て、マリオ(プレイヤー)にショットを打たせる事も出来たのですが
敵キャラにショットを打たせることができません。
というのも、敵キャラとブロック(壁)の描画方法が、テキストファイル内に「B」ならば、ブロック「A]ならば、クリボー(敵)といった方法で描画しているため
マリオと全く一緒の方法では、出来なくなっていて、躓いてます^^;

一応、自分がサンプルを基に、作成したソースを、張っておきますので、よろしければ、どなたか分かるかた
教えていただけると、ありがたいです。

コード:

----------------------(MainPanelクラス)----------------------------

package Start;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Iterator;
import java.util.LinkedList;

import javax.swing.JPanel;

import Map.Map;
import Enemy.*;
import Player.*;
import Bullet.AllCharShot;;

public class  MainPanel extends JPanel implements Runnable, KeyListener {

	// パネルサイズ
    public static  int WIDTH = 690;
    public static  int HEIGHT = 490;

    private boolean DEBUG_MODE = true;

    private Map    map;
    private Player player;

    protected ActionKey 左;
    protected ActionKey 右;
    protected ActionKey 上;
    protected ActionKey スペース;

	//クリボーショットステータス

	private Kuribo kuribo;
//	private Kshot[] Ks;
	private Atock atock;

    // ゲームループ用スレッド
    protected Thread gameLoop;

    /*パネルの推奨サイズを設定pack()する時に必要
     * setPreferredSize(new Dimension(幅,高))
     *
     * パネルがキー入力を受け付けるようにする
     * setFocusable(true)
     *
     * ActionKeyクラスを作成
     * Mapクラスを作成(最初に読み込むマップ名)
     * Playerクラスを作成(x座標,y座標,読み込む画像,参照先)
     *
     * パネルにキーイベントリスナーを登録
     * ゲームループを開始
     *
     * */

    public MainPanel() {

    	setFocusable(true);
        setPreferredSize(new Dimension(WIDTH, HEIGHT));

        左 = new ActionKey();
        右 = new ActionKey();
        上 = new ActionKey(ActionKey.DETECT_INITIAL_PRESS_ONLY);

        スペース = new ActionKey();

        map = new Map("map.dat");
        player = new Player(32, 1088, "Player.png", map);
        kuribo = new Kuribo(map.tilesToPixels(getX()), map.tilesToPixels(getY()), "Kuribo.gif", map);

        addKeyListener(this);
        setLayout(null);

        gameLoop = new Thread(this);
        gameLoop.start();
//        atock.start();

    }

    public void ゲームオーバー() {

        map = new Map("map.dat");
        player = new Player(32, 1088, "Playert", map);

    }

    /*
     * キーによってのアクション設定
     * ジャンプだけ別にif文を作成しているのは
     * 一緒にしてしまうと、ジャンプ中(上が押されてるとき)に左右移動が出来なくなってしまうため
     *
     * player.isCollsionこのメソッドから下(}まで)はプレイヤーとキャラクター(敵)との
     * 当たり判定処理内容を記述している。
     * if ((int)player.getY() < (int)kuribo.getY())これにより、上から敵を踏んだ場合
     * 敵は、消えるというようにしている。
     *
     * 正確には、敵よりも、Y座標が高ければいいので真上からでなくてもいい
     * 左右と下から、当たった場合は、プレイヤーが死んで、ゲームオーバーという処理になっている。
     * */

    public void run() {
        while (true) {

          if (スペース.isPressed())player.Pショット();
          if (上.isPressed())   player.ジャンプ();
          if (左.isPressed()) { player.左へ(); }
     else if (右.isPressed()) { player.右へ(); }
     else {                     player.停止(); }

            player.update();


            LinkedList sprites = map.getSprites();
            Iterator iterator = sprites.iterator();
            while (iterator.hasNext()) {
                CharObject sprite = (CharObject)iterator.next();
                sprite.update();

                /*
                 * プレイヤーのショットに敵が当たった時の判定処理
                 * */

//                for (int i = 0; i < NUM_SHOT; i++) {
//                    if(pshot[i].isCollision(sprite)){
//
//                        if (sprite instanceof Kuribo) {  // クリボー
//                            Kuribo kuribo = (Kuribo)sprite;
//                            kuribo.ショットダメージ();
//                            ShotCount ++;
//                            if(0 >= kuribo.現在のHP()){
//                            iterator.remove();
//                            }
//                            pshot[i].store();
//                            break;
//                            }
//                    }
//                }

                /*
                 * プレイヤーと衝突した時の判定
                 * */
                if (player.isCollision(sprite)) {
                    if (sprite instanceof Kuribo) {
                    	Kuribo kuribo = (Kuribo)sprite;

                    	if ((int)player.getY() < (int)kuribo.getY()) {
                        	sprites.remove(kuribo);
                            player.setForceJump(true);
                            player.ジャンプ();
                            break;
                        } else {
                          ゲームオーバー();
                        }
                    }
                }
            }

            // 再描画
            repaint();

            // 休止
            try { Thread.sleep(20);}
            catch (InterruptedException e) {e.printStackTrace();}
        }
    }

    /*
     * 描画処理内容
     *
     * 背景を黒で塗りつぶす
     *
     * x,y方向へのオフセットを設定している
     * これを、やる事により、マップの端では、スクロールしないようにする
     *
     * マップの描画
     * プレイヤーの描画
     * キャラオブジェクトを継承したクラスの描画.取得
     *
     * デバックモードの登録
     * */
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.BLACK);
        g.fillRect(0, 0, getWidth(), getHeight());

        int offsetX = MainPanel.WIDTH / 2 - (int)player.getX();
        offsetX = Math.min(offsetX, 0);
        offsetX = Math.max(offsetX, MainPanel.WIDTH - map.getWidth());

        int offsetY = MainPanel.HEIGHT / 2 - (int)player.getY();
        offsetY = Math.min(offsetY, 0);
        offsetY = Math.max(offsetY, MainPanel.HEIGHT - map.getHeight());

        map.draw(g, offsetX, offsetY);
        player.draw(g, offsetX, offsetY);
        kuribo.draw(g, map.tilesToPixels((offsetX)),map.tilesToPixels(offsetY));

         if (DEBUG_MODE) {
         Font font = new Font("SansSerif", Font.BOLD, 16);
         g.setFont(font);
         g.setColor(Color.YELLOW);
         g.drawString("プレイヤー座標"+"(" + player.getX() + "," + player.getY() + ")", 32, 15);
         g.drawString("HP"+map.tilesToPixels(getX()), 32, 45);
         }

         LinkedList sprites = map.getSprites();
         Iterator iterator = sprites.iterator();
         while (iterator.hasNext()) {
            CharObject sprite = (CharObject)iterator.next();
            sprite.draw(g, offsetX, offsetY);
        }
    }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT)  左.press();
        if (key == KeyEvent.VK_RIGHT) 右.press();
        if (key == KeyEvent.VK_UP)    上.press();
        if (key == KeyEvent.VK_SPACE) スペース.press();
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT)  左.release();
        if (key == KeyEvent.VK_RIGHT) 右.release();
        if (key == KeyEvent.VK_UP)    上.release();
        if (key == KeyEvent.VK_SPACE) スペース.release();
    }

    public void keyTyped(KeyEvent e) {
    }
 }

---------------------------------(Mapクラス)----------------------------

package Map;


import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;

import javax.swing.ImageIcon;

import Enemy.CharObject;
import Enemy.Kuribo;
import Start.MainPanel;

public class Map {
    // タイルサイズ
    public static final int TILE_SIZE = 32;
    // 重力
    public static final double GRAVITY = 0.6;

    // マップ
    private char[][] map;

    // 行数
    private int row;
    // 列数
    private int col;
    // 幅
    private int width;
    // 高さ
    private int height;

    // ブロックの画像
    private Image blockImage;

    // スプライトリスト
    private LinkedList sprites;

    public Map(String filename) {
        sprites = new LinkedList();

        // マップをロードする
        load(filename);

        width = TILE_SIZE * col;
        height = TILE_SIZE * row;

        // イメージをロードする
        loadImage();
    }

    //マップを描画する  g 描画オブジェクト   offsetX X方向オフセット   offsetY Y方向オフセット
    public void draw(Graphics g, int offsetX, int offsetY) {
        // オフセットを元に描画範囲を求める
        int firstTileX = pixelsToTiles(-offsetX);
        int lastTileX = firstTileX + pixelsToTiles(MainPanel.WIDTH) + 1;
        // 描画範囲がマップの大きさより大きくならないように調整
        lastTileX = Math.min(lastTileX, col);

        int firstTileY = pixelsToTiles(-offsetY);
        int lastTileY = firstTileY + pixelsToTiles(MainPanel.HEIGHT) + 1;
        // 描画範囲がマップの大きさより大きくならないように調整
        lastTileY = Math.min(lastTileY, row);

        for (int i = firstTileY; i < lastTileY; i++) {
            for (int j = firstTileX; j < lastTileX; j++) {
                // mapの値に応じて画像を描く
                switch (map[i][j]) {
                    case 'B' : // ブロック
                        g.drawImage(blockImage, tilesToPixels(j) + offsetX, tilesToPixels(i) + offsetY, null);
                        break;
                }
            }
        }
    }

    //(newX, newY)で衝突するブロックの座標を返す   スプライトへの参照  newX X座標   newY Y座標   衝突するブロックの座標
    public Point getTileCollision(CharObject sprite, double newX, double newY) {
        // 小数点以下切り上げ
        // 浮動小数点の関係で切り上げしないと衝突してないと判定される場合がある
        newX = Math.ceil(newX);
        newY = Math.ceil(newY);

        double fromX = Math.min(sprite.getX(), newX);
        double fromY = Math.min(sprite.getY(), newY);
        double toX = Math.max(sprite.getX(), newX);
        double toY = Math.max(sprite.getY(), newY);

        int fromTileX = pixelsToTiles(fromX);
        int fromTileY = pixelsToTiles(fromY);
        int toTileX = pixelsToTiles(toX + sprite.getWidth() - 1);
        int toTileY = pixelsToTiles(toY + sprite.getHeight() - 1);

        // 衝突しているか調べる
        for (int x = fromTileX; x <= toTileX; x++) {
            for (int y = fromTileY; y <= toTileY; y++) {
                // 画面外は衝突
                if (x < 0 || x >= col) return new Point(x, y);
                if (y < 0 || y >= row) return new Point(x, y);
                // ブロックがあったら衝突
                if (map[y][x] == 'B')  return new Point(x, y);
            }
        }
        return null;
    }

    //コインブロックがあるか  x X座標 y Y座標   コインブロックがあったらtrue
    public boolean isCoinBlock(int x, int y) {
        if (map[y][x] == 'C') {
            return true;
        }
        return false;
    }

    //アイテムブロックがあるか  x X座標 y Y座標  アイテムブロックがあったらtrue
    public boolean isItemBlock(int x, int y) {
        if (map[y][x] == 'I') {
            return true;
        }
        return false;
    }

    //コインブロックを叩かれた状態にする   x X座標      y Y座標
    public void knockCoinBlock(int x, int y) {
        // コインの音を鳴らす
        // 叩かれた後のブロックに変化
        map[y][x] = 'c';
    }


    //ピクセル単位をタイル単位に変更する  pixels ピクセル単位  タイル単位
    public static int pixelsToTiles(double pixels) {
        return (int)Math.floor(pixels / TILE_SIZE);
    }

    //タイル単位をピクセル単位に変更する   tiles タイル単位   retun ピクセル単位
    public static int tilesToPixels(int tiles) {
        return tiles * TILE_SIZE;
    }

    //イメージをロードする
    private void loadImage() {
        ImageIcon icon = new ImageIcon(getClass().getResource("/ブロック画像/block.gif"));
        blockImage = icon.getImage();
    }

    //マップをロードする
    private void load(String filename) {
        try {
            // ファイルを開く
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    getClass().getResourceAsStream("/マップデータ/" + filename)));

            // 行数を読み込む
            String line = br.readLine();
            row = Integer.parseInt(line);
            // 列数を読み込む
            line = br.readLine();
            col = Integer.parseInt(line);
            // マップを作成
            map = new char[row][col];
            for (int i = 0; i < row; i++) {
                line = br.readLine();
                for (int j = 0; j < col; j++) {
                    map[i][j] = line.charAt(j);
                    switch (map[i][j]) {
                            /*
                             * 敵一覧
                             * */
                        case 'b':
                            sprites.add(new Kuribo(tilesToPixels(j), tilesToPixels(i), "Kuribo.gif", this));
                            break;

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public LinkedList getSprites() {
        return sprites;
    }
}

---------------------------------------(CharObjectクラス)---------------------------

package Enemy;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;

import javax.swing.ImageIcon;

import Map.Map;
/*
 * キャラクターの共有クラス
 * */
public abstract class CharObject {
    // 位置
    protected double x,
                     y;
    //速度
    protected double speed,
                     jumpSpeed,
                     vx,
                     vy;

    // 幅 高さ 方向
	    protected int width,
	                  height,
	                  右,
	                  左,
	                  上,
	                  下,
	                  dir;

		protected static int HP,
		                     HpCounter;

    // 着地しているか
    protected boolean onGround,
                      forceJump;

    protected boolean jumperTwo;
    protected boolean canJumperTwo;
    protected boolean jumperTree;
    protected boolean canJumperTree;

    // Char画像
    protected Image image;

    // アニメーション用カウンタ
    protected int count;

    // マップへの参照
    protected Map map;

    public CharObject(double x, double y, String fileName, Map map) {
        this.x = x;
        this.y = y;
        this.map = map;

        loadImage(fileName);

        count = 0;
    }

    public abstract void update();

    public void draw(Graphics g, int offsetX, int offsetY) {
        g.drawImage(image,
                (int) x + offsetX, (int) y + offsetY,
                (int) x + offsetX + width, (int) y + offsetY + height,
                count * width, 0,
                count * width + width, height,
                null);
    }

    public boolean isCollision(CharObject sprite) {
        Rectangle playerRect = new Rectangle((int)x, (int)y, width, height);
        Rectangle spriteRect = new Rectangle((int)sprite.getX(), (int)sprite.getY(), sprite.getWidth(), sprite.getHeight());
        if (playerRect.intersects(spriteRect)) {return true;}
        return false;
    }

    private void loadImage(String filename) {
        ImageIcon icon = new ImageIcon(getClass().getResource("/キャラクター画像/" + filename));
        image = icon.getImage();
    }

    public class AnimationThread extends Thread {
    public void run() {
         while (true) {

                if (count == 0) {count = 1;}
           else if (count == 1) {count = 0;}

                try {Thread.sleep(300);}
                catch (InterruptedException e) {e.printStackTrace();}
            }
        }
    }
	public Point CharPoint(){return new Point((int)x,(int)y);}

    public double getX() {return x;}
    public double getY() {return y;}
    public int getWidth() {return width;}
    public int getHeight() {return height;}
}

---------------------------------(Playerクラス)----------------------------

package Player;

import java.awt.Graphics;
import java.awt.Point;

import Enemy.CharObject;
import Map.Map;

public class Player extends CharObject {

	private Pshot[]          pshot;
	private long             lastFire = 0;
	private static int       ShotCount;
	private static final int FIRE_INTERVAL = 200;
	private static final int NUM_SHOT = 999;

    public Player(double x, double y,String filename, Map map) {
        super(x, y, filename, map);
        this.x = x;
        this.y = y;
        width = 32;
        height = 32;
        vx = 0;
        vy = 0;
        speed = 16.0;
        jumpSpeed = 10.0;
        onGround = false;
        forceJump = false;
        jumperTwo = false;
        canJumperTwo = true;
        jumperTree = false;
        canJumperTree = true;
        右 = 2;
        左 = 1;
        dir = 右;

        pshot = new Pshot[NUM_SHOT];
        for (int i = 0; i < NUM_SHOT; i++) {pshot[i] = new Pshot(0, 0, "PlayerShot.gif", map);}

        ShotCount = NUM_SHOT;

        AnimationThread thread = new AnimationThread();
        thread.start();
    }

    public void 停止() { vx = 0; }

    public void 左へ() {
        vx = -speed;
        dir = 左;
    }

    public void 右へ() {
        vx = speed;
        dir = 右;
    }

    public void ジャンプ() {

        if (onGround || forceJump) {

            vy = -jumpSpeed;
            onGround = false;
            forceJump = false;

        } else if (jumperTwo && canJumperTwo) {

            vy = -jumpSpeed;
            canJumperTwo = false;

        } else if (jumperTwo && jumperTree && canJumperTree) {

        	vy = -jumpSpeed;
        	canJumperTree = false;

        }
    }

	public void Pショット() {

        if (System.currentTimeMillis() - lastFire < FIRE_INTERVAL) {return;}
        lastFire = System.currentTimeMillis();
        for (int i = 0; i < NUM_SHOT; i++) {
            if (pshot[i].isInStorage()) {
                Point pos = getPos();
                pshot[i].setPos(pos.x + getWidth() / 2, pos.y);
                ShotCount--;
                break;
            }
        }
    }

    public void update() {

        vy += Map.GRAVITY;
        for (int i = 0; i < NUM_SHOT; i++) {pshot[i].move();}

        double newX = x + vx;
        Point tile = map.getTileCollision(this, newX, y);
        if (tile == null) {
            x = newX;
        } else {
            if (vx > 0) {
                x = Map.tilesToPixels(tile.x) - width;
            } else if (vx < 0) {
                x = Map.tilesToPixels(tile.x + 1);
            }
            vx = 0;
        }

        double newY = y + vy;
        tile = map.getTileCollision(this, x, newY);
        if (tile == null) {
            y = newY;
            onGround = false;
        } else {
            if (vy > 0) {
                y = Map.tilesToPixels(tile.y) - height;
                vy = 0;
                onGround = true;
                canJumperTwo = true;
                canJumperTree = true;
            } else if (vy < 0) {
                y = Map.tilesToPixels(tile.y + 1);
                vy = 0;
                if (map.isCoinBlock(tile.x, tile.y)) {
                    map.knockCoinBlock(tile.x, tile.y);
                } else if (map.isCoinBlock(tile.x + 1, tile.y)) {
                    map.knockCoinBlock(tile.x + 1, tile.y);
                }
            }
        }
    }

    public void draw(Graphics g, int offsetX, int offsetY) {
        g.drawImage(image,
                (int) x + offsetX, (int) y + offsetY,
                (int) x + offsetX + width, (int) y + offsetY + height,
                count * width, dir * height,
                count * width + width, dir * height + height,
                null);
        for (int i = 0; i < NUM_SHOT; i++) {pshot[i].draw(g, offsetX, offsetY);}
    }

    public Point getPos()  { return new Point((int)x, (int)y); }

    public int getWidth()  { return width; }
    public int getHeight() { return height; }
    public double getX()   { return x; }
    public double getY()   { return y; }

    public double getSpeed() { return speed; }
    public void setSpeed(double speed) { this.speed = speed; }

    public void setForceJump(boolean forceJump)   { this.forceJump = forceJump; }
    public void setJumperTwo(boolean jumperTwo)   { this.jumperTwo = jumperTwo; }
    public void setJumperTree(boolean jumperTree) { this.jumperTree = jumperTree; }
}

---------------------------------------(ShotObjectクラス)-------------------------------------

package Bullet;

import java.awt.Point;

import Enemy.CharObject;
import Map.Map;

public abstract class ShotObject extends CharObject {

    // 弾の保管座標(画面に表示されない場所)
    protected static final Point STORAGE = new Point(0, 0);

    public ShotObject(double x, double y, String filename, Map map) {
        super(x, y, filename, map);

        x = STORAGE.x;
        y = STORAGE.y;

	}

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public Point getPos() {
        return new Point((int)x,(int) y);
    }

    public void setPos(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public void store() {
        x = STORAGE.x;
        y = STORAGE.y;
    }

    public boolean isInStorage() {
        if (x == STORAGE.x && y == STORAGE.x)
            return true;
        return false;
    }

	public int Shot左 (){
		return dir =左;
	}
	public int Shot右 (){
		return dir =右;
	}


}

(PShotクラス -プレイヤー用のショットクラス-)

package Player;

import Bullet.ShotObject;
import Map.Map;

public class Pshot extends ShotObject {

	public Pshot(double x, double y, String filename, Map map) {
		super(x, y, filename, map);

		width = 2;
		height = 20;
		vx = 0;
		vy = 0;
		speed = 10;
		dir = 右;

	}

    public void move() {
        // 保管庫に入っているなら何もしない
        if (isInStorage())
            return;
        x += speed;
    }

	@Override
	public void update() {

	}

}

--------------------------------(Kuribo(敵クラス))---------------------------

package Enemy;

import java.awt.Point;
import Map.Map;

public class Kuribo extends CharObject {

    public Kuribo(double x, double y, String filename, Map map) {
        super(x, y, filename, map);
        width = 32;
        height = 32;
        speed = 2.5;
        vx = -speed;
        vy = 0;
        HP = 15;
        HpCounter = 15;
    }

    public void update() {

        vy += Map.GRAVITY;

        double newX = x + vx;
        Point tile = map.getTileCollision(this, newX, y);
        if (tile == null) {x = newX;}

  else {if (vx > 0) {
            x = Map.tilesToPixels(tile.x) - width;}

   else if (vx < 0) {x = Map.tilesToPixels(tile.x + 1);}
            vx = -vx;
        }
    }

    //プレイヤーの位置を返す
    public Point getPos() {
        return new Point((int)x, (int)y);
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public int 現在のHP() {return HpCounter;}
    public int ショットダメージ() {return HpCounter  -= 6;}

}
長々と失礼しました。
よろしければ、ショットを敵キャラに打たせる方法をお教えください。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: ショットを複数のキャラに打たせたい。

#2

投稿記事 by ISLe » 12年前

ソースコードが見難いのでよく見てませんが、プレイヤークラスが弾の管理を抱えてる設計が良くないですね。
プレイヤーがいなくても、座標などの初期値を与えたら弾が出現し、動くようにしましょう。
そうしたら敵が弾を撃つようにする方法も分かりますよね。

アズカバンの囚人

Re: ショットを複数のキャラに打たせたい。

#3

投稿記事 by アズカバンの囚人 » 12年前

ISleさん、早速のお返事ありがとうございます。
まだ、学び始めで、綺麗なソースの書き方がわかっておらず、申し訳ない気持ちです。

それで、質問なのですが

プレイヤーがいなくても、座標などの初期値を与えたら弾が出現し、動くようにしましょう。

弾に初期座標を与えるというのは、x,y座標に0などの画面から見えない所などに一度描画しておき
敵がショット打つときに、初期座標から呼出すといった形ということでしょうか?
理解不足で頭があがらないのですが、よろしければ教えてください。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: ショットを複数のキャラに打たせたい。

#4

投稿記事 by ISLe » 12年前

アズカバンの囚人 さんが書きました:弾に初期座標を与えるというのは、x,y座標に0などの画面から見えない所などに一度描画しておき
敵がショット打つときに、初期座標から呼出すといった形ということでしょうか?
理解不足で頭があがらないのですが、よろしければ教えてください。
フラグで弾が生きているかどうか判断するという管理の仕方はそのままで良いです。
なので、見えないところに描くとかはしなくて良いです。

弾の配列がプレイヤークラスの中にあるので、弾がプレイヤーに依存しています。
やるべきことはプレイヤークラスの中にある弾配列をプレイヤークラスの外に出して独立させることです。

ショットを撃つときに、外に出した弾配列にどうやって情報を渡すかを考えてみてください。

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: ショットを複数のキャラに打たせたい。

#5

投稿記事 by bitter_fox » 12年前

アズカバンの囚人 さんが書きました: 長々と失礼しました。
よろしければ、ショットを敵キャラに打たせる方法をお教えください。
敵がショットを打つようにする方法は既にISLeさんが書かれてるので、細かいソースコードの改善点を書きます。

まず、パッケージ名の一般的な命名規則は小文字だけで書くことです。
この命名規則はソースコードを見たときにどれがパッケージでどれがクラスかを瞬時に判断することが出来るようにするためです。(他にも理由があるかもしれませんが自分はそうだと思っています。)
もしパッケージ名もパスカルケース(イニシャル大文字)で書くと次のソースコードは読む人によって二通りの解釈が出来てしまいます。

コード:

new A.B();
一つ目は、Aというパッケージで宣言されているBというクラスのインスタンス化で、
二つ目は、Aというクラスに宣言されているBというstaticネストクラスのインスタンス化です。

パッケージ名をすべて小文字と定めると一つ目は

コード:

new a.B();
となり、二つ目と区別することが出来ます。
オフトピック
ちなみに、今度はインナークラスのインスタンス化と被るように思われるかもしれませんが、インナークラスのインスタンス化は

コード:

a.new B();
なのでうまく被らないようになっています。
次に、メソッド名などに日本語を使われていますが、これはあんまり良い事とは言えないような気がします。
シンボルに日本語を使用することの是非よりも何よりもいちいち半/全キーを押すのは面倒くさくないですか?

最後に、Java5以降を使用するのであればジェネリクスを使用するべきです。
例えば、

コード:

// Map
    private LinkedList<CharObject> sprites;

    public Map(String filename) {
        sprites = new LinkedList<CharObject>(); // Java7ならダイアモンド演算子を用いてnew LinkedList<>()とも
    }

    public LinkedList<CharObject> getSprites() {
        return sprites;
    }
としておけばMainPanel#runなどはタイプセーフに書けます。

コード:

            LinkedList<CharObject> sprites = map.getSprites();
            Iterator<CharObject> iterator = sprites.iterator();
            while (iterator.hasNext()) {
                CharObject sprite = iterator.next();
                sprite.update();

                // ...
            }
さらに、for-each構文を使えばもっと簡潔に書けます。

コード:

            for (CharObject sprite : map.getSprites) {
                sprite.update();

                // ...
            }
あと、if (sprite instanceof Kuribo)以下はどういったことをしたいのでしょうか?
Kuribo kuribo = (Kuribo)sprite;とキャストしていますが、それ以降で使用しているのは既にCharObjectで定義されている物ですのでキャストする必要が無いと思います。
もしも、敵かどうかを判断したいということでinstanceofを使って分岐させているのであればお勧めできません。
なぜならば、もしも新しい敵を作った場合はどうなるでしょう?
この書き方だとさらにinstanceofを使った条件を追加しなければいけません。
ですが、CharObjectにisEnemyのようなメソッドを追加してそれで分岐させておけば、分岐をしている側の条件を変更することなく敵を追加することが出来ます。

アズカバンの囚人

Re: ショットを複数のキャラに打たせたい。

#6

投稿記事 by アズカバンの囚人 » 12年前

ISLeさん、ありがとうございます。
やるべきことがイマイチわかっていなかったので、まずは、一度自分なりにソースを改善させて
言ってもらえた、ショットクラスの独立などをさせてから、どうやって情報を与えるかをもう一度考えてみます。
その時に、もう一度質問させていただきたいと思いますので、よろしくお願いします。

アズカバンの囚人

Re: ショットを複数のキャラに打たせたい。

#7

投稿記事 by アズカバンの囚人 » 12年前

bitter_foxさん、丁寧に改善点を指摘してくださり、ありがとうございます。
パッケージ名とメソッド名は、すぐに半角文字に戻します。
いささか、面倒ではあったのですが、個人的に楽な部分があったのでそうしてしまっていました。

次に「ジェネリクス」っというのを、無知なため言葉すら知らなかったので、それも勉強してきたいと思います。

最後に、if文での当たり判定の処理は、おっしゃる通りキャラが増えるたびに
処理内容を記述して行く形になってしまってます。
そこも、1つにまとめられるよう努力をしてみます。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 13年前
住所: 東京

Re: ショットを複数のキャラに打たせたい。

#8

投稿記事 by MoNoQLoREATOR » 12年前

ISLeさんがおっしゃっていた「ソースコードが見難い」というのは、綺麗なソースコードの書き方でないといった意味ではなく、コードタグで囲っていないからではないかと思います。

[code=Java]ここにコードをコピペする[/code]

上記のように記述すれば、きれいに表示されます。
既に投稿した記事であっても編集することができますので、右上の編集ボタンを押してソースコードの部分をコードタグで囲ってみてください。

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: ショットを複数のキャラに打たせたい。

#9

投稿記事 by bitter_fox » 12年前

MoNoQLoREATOR さんが書きました: 既に投稿した記事であっても編集することができますので、右上の編集ボタンを押してソースコードの部分をコードタグで囲ってみてください。
編集できるのは登録ユーザだけじゃないですか?

アズカバンの囚人

Re: ショットを複数のキャラに打たせたい。

#10

投稿記事 by アズカバンの囚人 » 12年前

MoNoQLoREATORさん、どうやら登録ユーザー?以外ではできないようです。
登録するには、どうしたらいいのでしょうか?
フォーラムルールをよく見ていなかった自分が悪いのですが。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: ショットを複数のキャラに打たせたい。

#11

投稿記事 by softya(ソフト屋) » 12年前

このページの下の方に「ユーザー登録」があると思います。
ただ、未登録時の記事は編集できませんので私がcodeタグを設定しておきます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アズカバンの囚人

Re: ショットを複数のキャラに打たせたい。

#12

投稿記事 by アズカバンの囚人 » 12年前

ありがとうございます!

閉鎖

“C言語何でも質問掲示板” へ戻る