Java游戏:射击子弹

时间:2015-02-22 10:27:20

标签: java

我对使用Java创建游戏有点新意。我之前创建了一些简单的游戏,就像一个收集游戏的包,但现在我想制作一个自上而下的僵尸射击游戏。我已经有一个可以移动的玩家,但现在我想实现射击。 问题在于我不确定如何制作一个从玩家向右/向上/向下/向左射到屏幕末端的新子弹,具体取决于玩家所面对的屏幕部分。 /强> 我已粘贴下面的所有代码(4个类):

package me.mateo226.main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import me.mateo226.entities.Player;
import me.mateo226.guns.Bullet;

public class GamePanel extends JPanel implements Runnable {
    private static final long serialVersionUID = 1L;
    private static final int PWIDTH = 720;
    private static final int PHEIGHT = 480;
    private static Thread game;
    private static volatile boolean running = false;
    public static volatile boolean gameOver = false;
    public static volatile boolean paused = false;
    public static Graphics g;
    public static Image gImage;
    public static long lastLoopTime = System.currentTimeMillis();
    public static long delta;
    public static volatile boolean upPressed = false;
    public static volatile boolean downPressed = false;
    public static volatile boolean leftPressed = false;
    public static volatile boolean rightPressed = false;
    public BufferedImage backgroundImage;
    public Player player;
    Bullet bullet;

    public GamePanel() {

        setPreferredSize(new Dimension(PWIDTH, PHEIGHT));
        setBackground(Color.white);

        setFocusable(true);
        requestFocus();
        waitForTermination();

    }

    public void addNotify() {
        super.addNotify();
        startGame();
    }

    public void waitForTermination() {
        addKeyListener(new KeyListener() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                if (keyCode == KeyEvent.VK_ESCAPE) {
                    GamePanel.stopGame();
                }
                if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {
                    upPressed = true;
                }
                if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
                    downPressed = true;
                }
                if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
                    leftPressed = true;
                }
                if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
                    rightPressed = true;
                }

                if (keyCode == KeyEvent.VK_ESCAPE) {
                    System.exit(0);
                }

            }

            @Override
            public void keyReleased(KeyEvent e) {
                int keyCode = e.getKeyCode();
                if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {
                    upPressed = false;
                }
                if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
                    downPressed = false;
                }
                if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
                    leftPressed = false;
                }
                if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
                    rightPressed = false;
                }

            }

            @Override
            public void keyTyped(KeyEvent e) {

            }

        });

    }

    @Override
    public void run() {
        running = true;
        while (running) {
            delta = System.currentTimeMillis() - lastLoopTime;
            lastLoopTime = System.currentTimeMillis();

            gameUpdate();
            gameRender();
            checkMovement();
            paintpauseScreen();

            try {
                Thread.sleep(5);
            } catch (Exception e) {
                System.out.println("The thread couldn't sleep! Error info: "
                        + e);
            }

        }
        System.exit(0);

    }

    private void checkMovement() {
        if (!paused && !gameOver) {

        }
    }

    private void paintpauseScreen() {
        Graphics g;
        try {
            g = this.getGraphics();
            if ((g != null) && (gImage != null))
                g.drawImage(gImage, 0, 0, null);
            g.dispose();
        } catch (Exception e) {
            System.out.println("Graphics context error: " + e);
        }
    }

    private void gameRender() {
        if (gImage == null) {
            gImage = createImage(PWIDTH, PHEIGHT);
            if (gImage == null) {
                System.out
                        .println("image null after creating it??? Please check the code for any errors!");
            } else {
                g = gImage.getGraphics();
            }
        }
        if (!paused) {
            g.setColor(Color.white);
            g.fillRect(0, 0, PWIDTH, PHEIGHT);
            g.setColor(Color.blue);
        }
        try {
            backgroundImage = ImageIO.read(new File("res\\background.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        g.drawImage(backgroundImage, 0, 0, Color.white, null);

        if (player != null) {
            player.drawPlayer(g);
        }
        if (bullet != null) {
            bullet.drawBullet(g);
        }

    }

    private void gameUpdate() {
        if (!paused && !gameOver) {
            movePlayer();
            if (bullet != null){
                bullet.shootBullet(g, "right");
            }
        }
    }

    public void startGame() {
        if (game == null) {
            game = new Thread(this);
            if (game == null) {
                System.out.println("Couldn't create the thread!");
            } else {
                System.out.println("Thread created!");
                game.start();
            }
        }
        if (g == null) {
            g = this.getGraphics();
            if (g == null) {
                System.out.println("The graphics were not created!");
            } else {
                System.out.println("The graphics are successfully created!");
            }
        }

        player = new Player(32, 32, "res\\player.png");
        bullet = new Bullet("res\\grassTile.png", "right", player.x + 32,
                player.y);
        running = true;

    }

    public void movePlayer() {
        if (upPressed) {
            player.y -= player.moveSpeed * delta;
        }
        if (downPressed) {
            player.y += player.moveSpeed * delta;
        }
        if (leftPressed) {
            player.x -= player.moveSpeed * delta;
        }
        if (rightPressed) {
            player.x += player.moveSpeed * delta;
        }

    }

    public static void stopGame() {
        running = false;
    }

}

这是我的GamePanel课程。 这是我的主要课程:

package me.mateo226.main;

import java.awt.Container;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Main extends JFrame implements WindowListener {
    private static final long serialVersionUID = 1L;
    private static GamePanel panel;
    public static boolean DEBUGGING = false;

    public Main(){
        super("The Gun Reactor");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addWindowListener(this);
        Container c = getContentPane();
        panel = new GamePanel();
        c.add(panel, "Center");
        setResizable(false);
        pack();
        setLocationRelativeTo(null);
        if(JOptionPane.showConfirmDialog(null, "Enable debugging?") == 1){
            DEBUGGING = true;
        } else {
            DEBUGGING = false;
        }
        setVisible(true);

    }

    @Override
    public void windowActivated(WindowEvent arg0) {


    }

    @Override
    public void windowClosed(WindowEvent arg0) {

    }

    @Override
    public void windowClosing(WindowEvent arg0) {

    }

    @Override
    public void windowDeactivated(WindowEvent arg0) {

    }

    @Override
    public void windowDeiconified(WindowEvent arg0) {

    }

    @Override
    public void windowIconified(WindowEvent arg0) {

    }

    @Override
    public void windowOpened(WindowEvent arg0) {

    }

    public static void main(String args[]){
        new Main();
    }


}

这是我的Player类:

package me.mateo226.entities;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Player {

    public int x, y;
    public float moveSpeed = 0.1f;
    private BufferedImage playerTexture;;

    public Player(int x, int y, String texturePath){
        this.x = x;
        this.y = y;
        try {
        playerTexture = ImageIO.read(new File(texturePath));
        } catch (IOException e){
            e.printStackTrace();
        }
    }

    public void drawPlayer(Graphics g){

        g.setColor(Color.white);
        g.drawImage(playerTexture, x, y, null);

    }



}

最后这是我的子弹课程,我真的不知道如何使用甚至正确使用它:

package me.mateo226.guns;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import me.mateo226.main.GamePanel;

public class Bullet {

    private int x, y;
    private BufferedImage bulletTexture;
    private float bulletSpeed = 0.1f;

    public Bullet(String bulletTexturePath, String dir, int x, int y) {
        this.x = x;
        this.y = y;
        try {
            bulletTexture = ImageIO.read(new File(bulletTexturePath));
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public void drawBullet(Graphics g) {
        g.setColor(Color.white);
        g.drawImage(bulletTexture, x, y, null);
    }

    public void shootBullet(Graphics g, String dir) {
        switch (dir) {
        case "left":
            while (x > -32) {
                x -= bulletSpeed * GamePanel.delta;
                drawBullet(g);
            }
            break;
        case "right":
            while (x < 700) {
                x += bulletSpeed * GamePanel.delta;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            }
            break;
        case "up":
            while (y > -32) {
                y -= bulletSpeed * GamePanel.delta;
                drawBullet(g);
            }
            break;
        case "down":
            while (y < 480) {
                y += bulletSpeed * GamePanel.delta;
                drawBullet(g);
            }
            break;
        }
    }

}

任何帮助都会很棒!非常感谢你!

1 个答案:

答案 0 :(得分:2)

修改 我刚看到你只有四个方向。在这种情况下,您不需要方向向量。只需设置方向一次。 好的代码示例。

首先是游戏循环。在gameloop中添加要更新的firedBullets。每个被射击的子弹都会在方向向量上移动。

private void gameUpdate() {
    if (!paused && !gameOver) {
        movePlayer();
        foreach(Bullet bullet : player.getFiredBullets(){
             bullet.moveInDirection();
        }
    }
}

你的子弹课程:

public class Bullet {
    private Direction direction;
    private float speed = 1.2f;
    private int x;
    private int y;

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

    public void launchBullet(Direction direction){
        this.direction=direction;
    }

    public void moveInDirection() {
        //move the bullet with speed in the set direction. Same as you already have but without the while loop.
    }
}

所以玩家应该有一个方法火。 这会创建具有玩家位置的子弹。子弹的方向与玩家面对的方向相同。子弹被添加到列表中,因此每个游戏循环都会更新。

public class Player {
   private List<Bullet> firedBullets = new ArrayList<Bullet>();

   public void fire(){
       Bullet bullet = new Bullet(playerX, playerY);
       firedbullets.add(bullet);
       bullet.launch(direction); //this should be calculated by which direction the player is facing.
   }
}

所以当子弹射击时,方向会被设置一次。每个游戏更新子弹都按子弹的速度向这个方向移动。此逻辑可用于必须在游戏中移动的所有内容。例如,如果您想要一个在空中改变方向的子弹,您只需在半空中改变方向。