在简单空间入侵者中检测碰撞

时间:2014-12-08 14:07:00

标签: java

我使用java创建一个太空入侵者游戏,但我似乎无法检测到碰撞,这里是我的游戏面板,我们给了一些我添加的示例代码。我为每个从敌人阶级扩展的敌人创建了不同的类。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class GamePanel extends JPanel implements ActionListener, KeyListener
{
    private Player player;
    private Enemy enemy;
    private Enemy mothership;
    private Enemy destroyer;
    private Enemy meteor;
    private int enemyNumber = 0;
    private int totalscore = 0;
    private boolean destroyerspawn = false;
    private boolean meteorspawn = false;
    private boolean mothershipstop = false;
    private boolean meteorstop = false;
    private boolean destroyerstop = false;
    private Random random = new Random();
    private ArrayList<Enemy> enemyList;
    Timer redrawTimer;

    public GamePanel()
    {
        // As above commented out until enemy classes have been made
        enemyList = new ArrayList<Enemy>();

        // This starts the time that controls how often the screen is redrawn 
        redrawTimer = new Timer(10, this);
    }

    // Method to start the game
    public void startGame(int width, int height)
    {
        // Create player
        player = new Player(width, height);
        // Create mothership
        mothership = new Mothership(width, height, 0, 0);
        // Create destroyer
        destroyer = new Destroyers(width, height, 0, 0);
        // Create meteor
        meteor = new Meteor(width, height, 0, 0);

        // Loop to create multiple enemies
        // Goes through y axis changing the enemy type at each increment
        for (int y = 0; y < 3; y++)
        {
            // Goes through x axis making 6 of each enemy type
            for (int x = 0; x < 6; x++)
            {
                if(y == 0 || y == 3)
                {
                    enemy = new Martians(width, height, (x * 70), (y * 70));
                    enemyList.add(enemy);
                    enemyNumber++;
                }
                else if(y == 1 || y == 4)
                {
                    enemy = new Mercurians(width, height, (x * 70), (y * 70));
                    enemyList.add(enemy);
                    enemyNumber++;
                }
                else if(y == 2 || y == 5)
                {
                    enemy = new Venusians(width, height, (x * 70), (y * 70));
                    enemyList.add(enemy);
                    enemyNumber++;
                }
            }
        }

        // Starts draw timer
        redrawTimer.start();
    }

    // Method to pause the game
    public void pauseGame()
    {
        redrawTimer.restart();
    }

    // Handles the timer event, so this method repeats based on the interval set in your timer 
    @Override
    public void actionPerformed(ActionEvent e) 
    {   
        this.revalidate();
        // Causes the screen to be redrawn
        this.repaint();
    }

    // Our paint component method that draws every thing we need to the screen
    public void paintComponent(Graphics g) 
    {

        // This line ensures that every that would usually be drawn by a panel is
        super.paintComponent(g);

        // Clear the screen
        g.setColor(Color.black);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());

        if(player!= null && player.isActive())
        {
            // Draw the player
            player.draw(g);
        } 

        // If statement that stops this code running once it's deactivated once
        if (mothershipstop == false)
        {
            // If there are no enemies left
            if (enemyNumber == 0)
            {
                if(mothership!= null && mothership.isActive())
                {
                    // Draw and move the mothership
                    mothership.draw(g);
                    mothership.Move();
                }

                // Detects whether there's been a collision
                for (int b = 0; b < player.getBulletCount(); b++)
                {
                    // Collision detection for bullet
                    player.getBullet(b).detectCollision(mothership);
                }

                if (player.isActive() == true && mothership.isActive())
                {
                    // Collision detection for player
                    player.detectCollision(mothership);     
                }           
            }
        }

        // If statement that stops this code running once it's deactivated once
        if (destroyerstop == false)
        {
            // Each tick will have a 1 in 1000 chance of spawning a destroyer 
            if (random.nextInt(1000) == 1)
            {
                destroyerspawn = true;
            }
            // If the random integer got activated, destroyer spawns
            if (destroyerspawn == true && destroyer!= null && destroyer.isActive())
            {  
                // Draw and move the destroyer
                destroyer.draw(g);
                destroyer.Move();

                // Detects whether there's been a collision
                for (int b = 0; b < player.getBulletCount(); b++)
                {
                    // Collision detection for bullet
                    player.getBullet(b).detectCollision(destroyer);             
                }
            }
            else if (destroyer.isActive() == false)
            {
                destroyerstop = true;
                totalscore = totalscore + destroyer.GetScore();
            }
        }

        // If statement that stops this code running once it's deactivated once
        if (meteorstop == false)
        {
            // Each tick will have a 1 in 700 chance of spawning an asteroid 
            if (random.nextInt(700) == 1)
            {
                meteorspawn = true;
            }
            // If the random integer got activated, asteroid spawns
            if (meteorspawn == true && meteor!= null && meteor.isActive())
            {

                // Draw and move the asteroid
                meteor.draw(g);
                meteor.Move();

                // Detects whether there's been a collision
                for (int b = 0; b < player.getBulletCount(); b++)
                {
                    // Collision detection for bullet
                    player.getBullet(b).detectCollision(meteor);
                }

                if (player.isActive() == true && meteor.isActive())
                {
                    // Collision detection for player
                    player.detectCollision(meteor);
                }   
            }
            else if (meteor.isActive() == false)
            {
                meteorstop = true;
                totalscore = totalscore + meteor.GetScore();
            }
        }

        // Code to draw the enemy
        Iterator<Enemy> iterator = enemyList.iterator();

        // Loops to check each enemy
        while (iterator.hasNext()) 
        {
            // Checks the next enemy
            enemy = iterator.next();

            // If there's an enemy or active enemy
            if(enemy != null && enemy.isActive())
            {
                // Draw and move the enemy
                enemy.draw(g);
                enemy.Move();
            } // If non-existent enemy or is inactive
            else
            {
                // Get score
                totalscore = totalscore + enemy.GetScore();
                // Remove the enemy
                iterator.remove();
            }

            // If an enemy has been removed
            if (enemy.lives == 0)
            {
                // Decrement number of enemies
                enemyNumber--;
            }

            // Detects whether there's been a collision
            for (int b = 0; b < player.getBulletCount(); b++)
            {         
                // Collision detection for bullet
                player.getBullet(b).detectCollision(enemy);
            }

            if (player.isActive() == true && enemy.isActive())
            {
                // Collision detection for player

            }           
        }

        // Checks if game ends
        endGame();  

    }

    public void endGame()
    {
        if (player.isActive() == false)
        {
            // You lose
            System.out.println("Game over! You lose.");
            System.out.println("Your score is: " + totalscore);
            // Close game
            System.exit(ABORT);
        }else if (mothership.isActive() == false)
        {
            // You win
            totalscore = totalscore + mothership.GetScore(); 
            System.out.println("Congratulations! You win.");
            System.out.println("Your score is: " + totalscore);
            // Close game
            System.exit(ABORT);

        }

    }

    // Code here controls the key events
    @Override
    public void keyPressed(KeyEvent event) 
    {
        switch(event.getKeyCode())
        {
            case KeyEvent.VK_RIGHT: player.move(1); break;
            case KeyEvent.VK_LEFT: player.move(-1); break;
            case KeyEvent.VK_SPACE: player.fire(); break;
        }   
    }


    @Override
    public void keyReleased(KeyEvent event) 
    {

    }

    @Override
    public void keyTyped(KeyEvent event) 
    {

    }

}

在我的子弹类中有一个我们必须填写的检测碰撞方法,但我不知道如何做到这一点。这是子弹类的代码。

import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Bullet {

    private Point position;
    private int height, width;
    private BufferedImage img;
    private int speed = 20;
    private boolean active;


    public Bullet(Point playerPosition){

        //same as the player class this simply loads the image for the bullet.
        try {
            img = ImageIO.read(getClass().getResource("/playerbullet.jpg"));
            //System.out.println("***************OK*******************");
        } catch (IOException e) {
            //System.out.println("***************CAN'T READ FILE*******************");
            e.printStackTrace();
        }

        height = img.getHeight();
        width = img.getWidth();

        //sets the bullet position we have to do a little offset wit the bullet image so our bullet appears in the (horizontal) centre of our player
        position = new Point(playerPosition.x - (width/2), playerPosition.y);

        active = true;
    }

    //draws the bullet
    public void draw(Graphics g) {

        g.drawImage(img, position.x, position.y, width, height, null);

    }

    //moves the bullet unless it has gone off the top of the screen in which case the bullet is destroyed
    public void move(){
        if(position.y < 0){
            destroy();
        }
        else{
            position.y-=speed;
        }

    }

    //sets the bullet as inactive
    public void destroy(){
        active = false;
    }

    //returns whether the bullet is active or not
    public boolean isActive(){
        return active;
    }

    //returns the bullets current position
    public Point getPosition() {
        // TODO Auto-generated method stub
        return position;
    }

    // this method will flag as an error until you create your enemy classes
    public void detectCollision(Enemy e)
    {

    }



}

1 个答案:

答案 0 :(得分:1)

您可以在Java中尝试Rectangle

有一个名为“createIntersection”的方法,它返回两个矩形重叠的Rectangle。如果该区域为零,则不会发生碰撞。

在Bullet类中,您存储了位置,宽度和高度。但实际上这告诉你实际上存储的是“矩形”。因此,尝试重构您的实现并改为使用Rectangle。

在detectCollision()方法中,参数应该是检查目标(即播放器)的Rectangle。然后,您可以使用createIntersection()来检查重叠区域