简体   繁体   English

Java游戏:射击子弹

[英]Java Game: Shooting Bullets

I am (kind of) new to creating games with Java. 我不熟悉使用Java创建游戏。 I created some simple games before like a bag collecting game but now I want to make a top-down zombie shooting game. 我之前曾做过一些简单的游戏,例如行李收集游戏,但现在我想制作一个自上而下的僵尸射击游戏。 I already have a player that can move, but now I want to implement shooting. 我已经有一个可以移动的球员,但现在我想实施射击。 The problem is that I am not sure how to make a new bullet that shoots from the player to the right / up / down /left to the end of the screen depending on what part of the screen the player is facing. 问题是我不确定如何制作新的子弹,它会根据玩家所面对的屏幕部分从玩家向右/上/下/左射击到屏幕末端。 I have pasted all my of code below (4 classes): 我已将我的所有代码粘贴到下面(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;
    }

}

This was my GamePanel class. 这是我的GamePanel类。 This is my Main class: 这是我的主班:

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();
    }


}

This is my Player class: 这是我的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);

    }



}

And finally this is my bullet class which I don't really know how to use or even make it properly: 最后,这是我的子弹班,我真的不知道如何使用甚至正确地使它:

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;
        }
    }

}

Any help would be great! 任何帮助将是巨大的! Thank you very much! 非常感谢你!

EDIT I just read that you only have four directions. 编辑我刚刚读到你只有四个方向。 In that case you do not need a direction vector. 在这种情况下,您不需要方向向量。 Just set the direction once. 只需设置方向一次。 Ok so the code example. 好的,代码示例。

First the gameloop. 首先是游戏循环。 Add the firedBullets for update in the gameloop. 添加firedBullets在游戏循环中进行更新。 Every fired bullet gets moved on its direction vector. 每个发射的子弹都沿其方向向量移动。

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

And your Bullet class: 而你的子弹班:

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.
    }
}

So the player should have a method fire. 所以玩家应该有一个方法射击。 This creates the bullet with position of the player. 这将创建具有子弹位置的子弹。 The bullet gets the same direction as where the player is facing. 子弹的方向与玩家面对的方向相同。 And the bullet get added to the list so it will be updated every gameloop. 并且项目符号会添加到列表中,因此将在每个游戏循环中进行更新。

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.
   }
}

So the direction gets set once when the bullet is fired. 因此,子弹发射后方向会被设置一次。 Every game update the bullet is moved in this direction by the speed of the bullet. 每次游戏更新时,子弹都会以子弹的速度朝这个方向移动。 This logic can be used for everything that has to be moved in the game. 此逻辑可用于游戏中必须移动的所有内容。 For example if you want a bullet that changes direction in mid-air you would just change its direction in mid-air. 例如,如果您希望子弹在空中改变方向,则只需在空中改变其方向即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM