我使用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)
{
}
}
答案 0 :(得分:1)
您可以在Java中尝试Rectangle类
有一个名为“createIntersection”的方法,它返回两个矩形重叠的Rectangle。如果该区域为零,则不会发生碰撞。
在Bullet类中,您存储了位置,宽度和高度。但实际上这告诉你实际上存储的是“矩形”。因此,尝试重构您的实现并改为使用Rectangle。
在detectCollision()方法中,参数应该是检查目标(即播放器)的Rectangle。然后,您可以使用createIntersection()来检查重叠区域