2015-02-17 5 views
0

Контекст этого вопроса заключается в том, что я часть небольшой группы, которая работает над созданием маленькой игры на Android. Игра, которую мы выбрали для разработки, - это нисходящий 2D-шутер, в котором игрок управляет космическим кораблем, который должен защищаться от инопланетных существ, которые движутся к игроку с верхней части экрана игры, подобно космическому захватчику, но отличаются тем, что они появляются в случайных шаблонах.Обнаружение столкновений в 2D-шутерской игре на основе Java

До сих пор нам удалось запустить игру, заставить игрока и врагов появиться и двигаться в правильном направлении, а также оружие игрока, которое обозначено как «снаряд» (хотя в настоящее время оно только появляется самостоятельно, а не по команде игрока). Проблема, которую мы имеем, состоит в том, что мы пытаемся настроить событие столкновения в коде между снарядом и врагами, чтобы, когда они встречались, враг и пуля исчезают.

Однако то, что мы в настоящее время записывали в коде, похоже, не делает этой работы, поэтому мне было интересно, может ли кто-нибудь еще увидеть, где мы ошибаемся. Ниже перечислены соответствующие классы кода. Мы будем очень признательны за любую помощь, которую кто-либо может дать.

Класс детектора столкновений (удерживает поведение при обнаружении столкновения для всех объектов в игре).

package uk.ac.qub.eeecs.gage.util; 

import uk.ac.qub.eeecs.gage.world.GameObject; 

/** 
* Collision Detector Helper Library 
* 
* @version 1.0 
*/ 
public class CollisionDetector { 

    /** 
    * Type of collision 
    */ 
    public enum CollisionType { 
     None, Top, Bottom, Left, Right, destroy //for the platform game, not yours 
    }; 

    /** 
    * Determine if the two specified bounding boxes are in collision 
    * 
    * @param one 
    *   First bounding box 
    * @param two 
    *   Second bounding box 
    * @return boolean true if the boxes overlap, false otherwise 
    */ 
    //is relevant to your game 
    public static boolean isCollision(BoundingBox one, BoundingBox two) { 
     return (one.x - one.halfWidth < two.x + two.halfWidth 
       && one.x + one.halfWidth > two.x - two.halfWidth 
       && one.y - one.halfHeight < two.y + two.halfHeight && one.y 
       + one.halfHeight > two.y - two.halfHeight); 

     //Do we add the code to set the enemies to disappear/destroy here or in the 
     //individual classes such as the player? 
    } 

    /** 
    * Determine the type of collision between the two bounding boxes. 
    * CollisionType.None is returned if there are no collisions. 
    * 
    * @param one 
    *   First bounding box 
    * @param two 
    *   Second bounding box 
    * @return Collision type 
    */ 

Класс AISpaceship.java (класс, используемый для инородных объектов emeny и их свойств).

package uk.ac.qub.eeecs.game.spaceDemo; 

import uk.ac.qub.eeecs.gage.ai.SteeringBehaviours; 
import uk.ac.qub.eeecs.gage.engine.ElapsedTime; 
import uk.ac.qub.eeecs.gage.util.CollisionDetector; 
import uk.ac.qub.eeecs.gage.util.Vector2; 
import uk.ac.qub.eeecs.gage.util.CollisionDetector.CollisionType; 
import uk.ac.qub.eeecs.gage.world.GameObject; 
import uk.ac.qub.eeecs.gage.world.Sprite; 

/** 
* AI controlled spaceship 
* 
* @version 1.0 
*/ 
    public class AISpaceship extends Sprite { 

// ///////////////////////////////////////////////////////////////////////// 
// Properties 
// ///////////////////////////////////////////////////////////////////////// 

/** 
* AI control behaviour 
*/ 

/** 
* Acceleration with which the spaceship can move along 
* the x-axis 
*/ 
private float RUN_ACCELERATION = 150.0f; 

public enum ShipBehaviour { 
    Turret, Seeker 
} 

private boolean visible; 

private ShipBehaviour mShipBehaviour; 

/** 
* Distance at which the spaceship should avoid other game objects 
*/ 
private float separateThresholdShip = 75.0f; 
private float separateThresholdAsteroid = 125.0f; 

/** 
* Accumulators used to build up the net steering outcome 
*/ 
private Vector2 accAccumulator = new Vector2(); 
private Vector2 accComponent = new Vector2(); 



// ///////////////////////////////////////////////////////////////////////// 
// Constructors 
// ///////////////////////////////////////////////////////////////////////// 

/** 
* Create a AI controlled spaceship 
* 
* @param startX 
*   x location of the AI spaceship 
* @param startY 
*   y location of the AI spaceship 
* @param shipBehaviour 
*   Steering behaviour to be used by the AI ship 
* @param gameScreen 
*   Gamescreen to which AI belongs 
*/ 

public AISpaceship(float startX, float startY, ShipBehaviour shipBehaviour, 
     SteeringDemoGameScreen gameScreen) { 
    super(startX, startY, 50.0f, 50.0f, null, gameScreen); 

    mShipBehaviour = shipBehaviour; 

    visible = true; 

    switch (mShipBehaviour) { 
    case Turret: 
     maxAcceleration = 0.0f; 
     maxVelocity = 0.0f; 
     mBitmap = gameScreen.getGame().getAssetManager().getBitmap("Turret"); 
     break; 
    case Seeker: 
     maxAcceleration = -40.0f; 
     maxVelocity = 50.0f; 
     mBitmap = gameScreen.getGame().getAssetManager().getBitmap("enemy sprites 7"); 
     break; 
    } 
} 

// ///////////////////////////////////////////////////////////////////////// 
// Methods 
// ///////////////////////////////////////////////////////////////////////// 

/* 
* (non-Javadoc) 
* 
* @see 
* uk.ac.qub.eeecs.gage.world.Sprite#update(uk.ac.qub.eeecs.gage.engine. 
* ElapsedTime) 
*/ 
@Override 
public void update(ElapsedTime elapsedTime) { 

    switch (mShipBehaviour) { 
    case Seeker: 
     //Move down towards the player in a straight line 
     acceleration.y = RUN_ACCELERATION; 

     // Seek towards the player 

     // Try to avoid a collision with the playership 


     // Try to avoid a collision with the other spaceships   


     // Try to avoid a collision with the asteroids 
     SteeringBehaviours.separate(this, 
       ((SteeringDemoGameScreen) mGameScreen).getAsteroids(), 
       separateThresholdAsteroid, 1.0f, accComponent); 
     accAccumulator.add(accComponent); 

     // If we are trying to avoid a collision then combine 
     // it with the seek behaviour, placing more emphasis on 
     // avoiding the collision.   
     if (!accAccumulator.isZero()) { 
      acceleration.x = 0.3f * acceleration.x + 0.7f 
        * accAccumulator.x; 
      acceleration.y = 0.3f * acceleration.y + 0.7f 
        * accAccumulator.y; 
     } 

     // Make sure we point in the direction of travel. 

     break; 
    } 

    // Call the sprite's superclass to apply the determine accelerations 
    super.update(elapsedTime); 

    // Check that our new position has not collided by one of the 
    // defined projectiles. If so, then removing any overlap and 
    // ensure a valid velocity. 
    checkForAndResolveCollisions(projectiles);  
} 

/** 
* Check for and then resolve any collision between the AiShip and the 
* player projectiles. 
* 
* @param projectiles 
*   Array of projectiles to test for collision against 
*/ 
private void checkForAndResolveCollisions(GameObject[] projectiles) { 

    CollisionType collisionType; 

    // Consider each platform for a collision 
    for (GameObject projectile : projectiles) { 
     collisionType = 
       CollisionDetector.determineAndResolveCollision(this, Projectile); 

     switch (collisionType) { 
     case destroy: 
      visible = false; 
      break; 
     } 
    } 

} 

}

Projectile1 (класс используется для определения снарядов всех игр и их behavoir).

package uk.ac.qub.eeecs.game.spaceDemo; 

import uk.ac.qub.eeecs.gage.ai.SteeringBehaviours; 
import uk.ac.qub.eeecs.gage.engine.ElapsedTime; 
import uk.ac.qub.eeecs.gage.util.Vector2; 
import uk.ac.qub.eeecs.gage.world.Sprite; 

/** 
* AI controlled spaceship 
* 
* @version 1.0 
*/ 
public class Projectile1 extends Sprite { 

    // ///////////////////////////////////////////////////////////////////////// 
    // Properties 
    // ///////////////////////////////////////////////////////////////////////// 

    /** 
    * AI control behaviour 
    */ 

    /** 
    * Acceleration with which the projectile can move along 
    * the x-axis 
    */ 
    private float RUN_ACCELERATION = 150.0f; 


    public enum ShipBehaviour { 
     bullet 
    } 

    private ShipBehaviour mShipBehaviour; 

    /** 
    * Distance at which the spaceship should avoid other game objects 
    */ 


    /** 
    * Accumulators used to build up the net steering outcome 
    */ 
    private Vector2 accAccumulator = new Vector2(); 
    private Vector2 accComponent = new Vector2(); 

    // ///////////////////////////////////////////////////////////////////////// 
    // Constructors 
    // ///////////////////////////////////////////////////////////////////////// 

    /** 
    * Create a AI controlled spaceship 
    * 
    * @param startX 
    *   x location of the AI spaceship 
    * @param startY 
    *   y location of the AI spaceship 
    * @param shipBehaviour 
    *   Steering behaviour to be used by the AI ship 
    * @param gameScreen 
    *   Gamescreen to which AI belongs 
    */ 
    public Projectile1(float startX, float startY, ShipBehaviour shipBehaviour, 
      SteeringDemoGameScreen gameScreen) { 
     super(startX, startY, 50.0f, 50.0f, null, gameScreen); 

     mShipBehaviour = shipBehaviour; 

     switch (mShipBehaviour) { 
     case bullet: 
      maxAcceleration = 20.0f; 
      maxVelocity = 30.0f; 
      mBitmap = gameScreen.getGame().getAssetManager().getBitmap("Spaceship2"); 
      break; 

     } 
    } 

    // ///////////////////////////////////////////////////////////////////////// 
    // Methods 
    // ///////////////////////////////////////////////////////////////////////// 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * uk.ac.qub.eeecs.gage.world.Sprite#update(uk.ac.qub.eeecs.gage.engine. 
    * ElapsedTime) 
    */ 
    @Override 
    public void update(ElapsedTime elapsedTime) { 

     switch (mShipBehaviour) { 
     case bullet: 
      // Seek towards the player 

       acceleration.y = RUN_ACCELERATION; 




      break; 
     } 

     // Call the sprite's superclass to apply the determine accelerations 
     super.update(elapsedTime); 
    } 
} 

SterringGameDemo (Основной класс для уровня, на котором игра происходит и где игрок, враги и снаряды ведут себя и взаимодействуют друг с другом (заметьте, это называется «SteeringGameDemo», потому что это пережиток шаблон, который мы использовали, чтобы помочь сделать класс и еще не переименован)).

package uk.ac.qub.eeecs.game.spaceDemo; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import uk.ac.qub.eeecs.gage.Game; 
import uk.ac.qub.eeecs.gage.engine.AssetStore; 
import uk.ac.qub.eeecs.gage.engine.ElapsedTime; 
import uk.ac.qub.eeecs.gage.engine.graphics.IGraphics2D; 
import uk.ac.qub.eeecs.gage.util.BoundingBox; 
import uk.ac.qub.eeecs.gage.util.CollisionDetector; 
import uk.ac.qub.eeecs.gage.world.GameObject; 
import uk.ac.qub.eeecs.gage.world.GameScreen; 
import uk.ac.qub.eeecs.gage.world.LayerViewport; 
import uk.ac.qub.eeecs.gage.world.ScreenViewport; 
import android.graphics.Color; 

/** 
* Simple steering game world 
* 
* @version 1.0 
*/ 
public class SteeringDemoGameScreen extends GameScreen { 

    // ///////////////////////////////////////////////////////////////////////// 
    // Properties 
    // ///////////////////////////////////////////////////////////////////////// 

    /** 
    * Width and height of the level 
    */ 
    private final float LEVEL_WIDTH = 480.0f; 
    private final float LEVEL_HEIGHT = 280.0f; 

    /** 
    * Define viewports for this layer and the associated screen projection 
    */ 
    private ScreenViewport mScreenViewport; 
    private LayerViewport mLayerViewport; 

    /** 
    * Define a background object, alongside a player controlled 
    * space ship and separate lists of asteroids and AI controlled 
    * space ships. 
    */ 

    private GameObject mSpaceBackground; 

    private PlayerSpaceship mPlayerSpaceship; 


    private final int NUM_ASTEROIDS = 0; 
    private List<Asteroid> mAsteroids; 

    private final int NUM_SEEKERS = 2; 
    private final int NUM_TURRETS = 1; 
    private final int NUM_PROJECTILE = 1; 
    private List<Projectile1> mProjectile1; 
    private List<AISpaceship> mAISpaceships; 

    // ///////////////////////////////////////////////////////////////////////// 
    // Constructors 
    // ///////////////////////////////////////////////////////////////////////// 

    /** 
    * Create a simple steering game world 
    * 
    * @param game 
    *   Game to which this screen belongs 
    */ 
    public SteeringDemoGameScreen(Game game) { 
     super("SteeringDemoGameScreen", game); 

     // Create the screen viewport 
     mScreenViewport = new ScreenViewport(0, 0, game.getScreenWidth(), 
       game.getScreenHeight()); 

     // Create the layer viewport, taking into account the orientation 
     // and aspect ratio of the screen. 
     if (mScreenViewport.width > mScreenViewport.height) 
      mLayerViewport = new LayerViewport(240.0f, 240.0f 
        * mScreenViewport.height/mScreenViewport.width, 240, 
        240.0f * mScreenViewport.height/mScreenViewport.width); 
     else 
      mLayerViewport = new LayerViewport(240.0f * mScreenViewport.height 
        /mScreenViewport.width, 240.0f, 240.0f 
        * mScreenViewport.height/mScreenViewport.width, 240); 

     // Load in the assets used by the steering demo 
     AssetStore assetManager = mGame.getAssetManager(); 
     assetManager.loadAndAddBitmap("Space BG 2", "img/Space BG 2.png");  
     assetManager.loadAndAddBitmap("Asteroid1", "img/Asteroid1.png"); 
     assetManager.loadAndAddBitmap("Asteroid2", "img/Asteroid2.png"); 
     assetManager.loadAndAddBitmap("enemy sprites 7", "img/enemy sprites 7.png"); 
     assetManager.loadAndAddBitmap("Spaceship2", "img/Spaceship2.png"); 
     assetManager.loadAndAddBitmap("Spaceship3", "img/Spaceship3.png"); 
     assetManager.loadAndAddBitmap("Spaceship3", "img/Spaceship3.png"); 
     assetManager.loadAndAddBitmap("Player sprite", "img/Player sprite.png"); 
     assetManager.loadAndAddBitmap("Turret", "img/Turret.png"); 

     // Create the space background 
     mSpaceBackground = new GameObject(LEVEL_WIDTH/2.0f, 
       LEVEL_HEIGHT/2.0f, LEVEL_WIDTH, LEVEL_HEIGHT, getGame() 
         .getAssetManager().getBitmap("Space BG 2"), this); 

     // Create the player spaceship 
     mPlayerSpaceship = new PlayerSpaceship(230, 10, this); 



     // Create a number of randomly positioned asteroids 
     Random random = new Random(); 
     mAsteroids = new ArrayList<Asteroid>(NUM_ASTEROIDS); 
     for (int idx = 0; idx < NUM_ASTEROIDS; idx++) 
      mAsteroids.add(new Asteroid(random.nextFloat() * LEVEL_WIDTH, random.nextFloat() * LEVEL_HEIGHT, this)); 


     // Create a number of randomly positioned AI controlled ships 
     mAISpaceships = new ArrayList<AISpaceship>(NUM_SEEKERS + NUM_TURRETS); 
     for (int idx = 0; idx < NUM_SEEKERS; idx++) 
      mAISpaceships.add(new AISpaceship(random.nextFloat() * LEVEL_WIDTH, 
        180 + random.nextFloat() * LEVEL_HEIGHT, 
        AISpaceship.ShipBehaviour.Seeker, this)); 
     for (int idx = 0; idx < NUM_TURRETS; idx++) 
      mAISpaceships.add(new AISpaceship(random.nextFloat() * LEVEL_WIDTH, 
        random.nextFloat() * LEVEL_HEIGHT, 
        AISpaceship.ShipBehaviour.Turret, this)); 

     //Use the above to help spawn the bullets 
     mProjectile1 = new ArrayList<Projectile1>(NUM_PROJECTILE); 
     for (int idx = 0; idx < NUM_PROJECTILE; idx++) 
     mProjectile1.add(new Projectile1(mPlayerSpaceship.position.x, mPlayerSpaceship.position.y, 
       Projectile1.ShipBehaviour.bullet, this)); 

    } 

    // ///////////////////////////////////////////////////////////////////////// 
    // Support methods 
    // ///////////////////////////////////////////////////////////////////////// 

    /** 
    * Return the player spaceship 
    * 
    * @return Player spaceship 
    */ 
    public PlayerSpaceship getPlayerSpaceship() { 
     return mPlayerSpaceship; 
    } 

    public List<Projectile1> getProjectile1() { 
     return mProjectile1; 
    } 

    /** 
    * Return a list of the AI spaceships in the level 
    * 
    * @return List of AI controlled spaceships 
    */ 
    public List<AISpaceship> getAISpaceships() { 
     return mAISpaceships; 
    } 

    /** 
    * Return a list of asteroids in the the level 
    * 
    * @return List of asteroids in the level 
    */ 
    public List<Asteroid> getAsteroids() { 
     return mAsteroids; 
    } 

    // ///////////////////////////////////////////////////////////////////////// 
    // Update and Draw methods 
    // ///////////////////////////////////////////////////////////////////////// 

    /* 
    * (non-Javadoc) fs 
    * 
    * @see 
    * uk.ac.qub.eeecs.gage.world.GameScreen#update(uk.ac.qub.eeecs.gage.engine 
    * .ElapsedTime) 
    */ 
    @Override 
    public void update(ElapsedTime elapsedTime) { 

     // Update the player spaceship 
     mPlayerSpaceship.update(elapsedTime); 

     // Ensure the player cannot leave the confines of the world 
     BoundingBox playerBound = mPlayerSpaceship.getBound(); 
     if (playerBound.getLeft() < 0) 
      mPlayerSpaceship.position.x -= playerBound.getLeft(); 
     else if (playerBound.getRight() > LEVEL_WIDTH) 
      mPlayerSpaceship.position.x -= (playerBound.getRight() - LEVEL_WIDTH); 

     if (playerBound.getBottom() < 0) 
      mPlayerSpaceship.position.y -= playerBound.getBottom(); 
     else if (playerBound.getTop() > LEVEL_HEIGHT) 
      mPlayerSpaceship.position.y -= (playerBound.getTop() - LEVEL_HEIGHT); 

     // Ensure the enemyships cannot leave the confines of the world 


     //Use the above for player and enemies bullets in this class 


     //IMPORTANT - THE below code is VITAL for the collision detection and was a 
       //added by the tutor. It calls the bounding box and collision detector for the 
       //player and enemy ship. Add this to the above section where the bounding box 
       // is already called, just below the update method. 
       BoundingBox playersBound = mPlayerSpaceship.getBound(); 
       for (AISpaceship aiSpaceship : mAISpaceships) { 
        BoundingBox aiBound = aiSpaceship.getBound(); 
        if(CollisionDetector.isCollision(playersBound, aiBound)) { 


        } 
       } 


     // Focus the layer viewport on the player 


     // Ensure the viewport cannot leave the confines of the world 
     if (mLayerViewport.getLeft() < 0) 
      mLayerViewport.x -= mLayerViewport.getLeft(); 
     else if (mLayerViewport.getRight() > LEVEL_WIDTH) 
      mLayerViewport.x -= (mLayerViewport.getRight() - LEVEL_WIDTH); 

     if (mLayerViewport.getBottom() < 0) 
      mLayerViewport.y -= mLayerViewport.getBottom(); 
     else if (mLayerViewport.getTop() > LEVEL_HEIGHT) 
      mLayerViewport.y -= (mLayerViewport.getTop() - LEVEL_HEIGHT); 

     // Update each of the AI controlled spaceships 
     for (AISpaceship aiSpaceship : mAISpaceships) 
      aiSpaceship.update(elapsedTime); 

     // Update each of the asteroids 
     for (Asteroid asteroid : mAsteroids) 
      asteroid.update(elapsedTime); 

     // Update each of the Player Projectile1 
       for (Projectile1 projectile1 : mProjectile1) 
        projectile1.update(elapsedTime); 


    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * uk.ac.qub.eeecs.gage.world.GameScreen#draw(uk.ac.qub.eeecs.gage.engine 
    * .ElapsedTime, uk.ac.qub.eeecs.gage.engine.graphics.IGraphics2D) 
    */ 
    @Override 
    public void draw(ElapsedTime elapsedTime, IGraphics2D graphics2D) { 

     // Create the screen to black and define a clip based on the viewport 
     graphics2D.clear(Color.BLACK); 
     graphics2D.clipRect(mScreenViewport.toRect()); 

     // Draw the background first of all 
     mSpaceBackground.draw(elapsedTime, graphics2D, mLayerViewport, 
       mScreenViewport); 

     // Draw each of the asteroids 
     for (Asteroid asteroid : mAsteroids) 
      asteroid.draw(elapsedTime, graphics2D, mLayerViewport, 
        mScreenViewport); 

     // Draw each of the AI controlled spaceships 
       for (Projectile1 projectile1 : mProjectile1) 
        projectile1.draw(elapsedTime, graphics2D, mLayerViewport, 
          mScreenViewport); 

     // Draw each of the AI controlled spaceships 
     for (AISpaceship aiSpaceship : mAISpaceships) 
      aiSpaceship.draw(elapsedTime, graphics2D, mLayerViewport, 
        mScreenViewport); 

     // Draw the player 
     mPlayerSpaceship.draw(elapsedTime, graphics2D, mLayerViewport, 
       mScreenViewport); 


    } 
} 

Снова, я говорю спасибо всем, кто может помочь.

+0

Вы можете легко написать несколько тестов вокруг некоторого кода, например 'boolean isCollision (BoundingBox one, BoundingBox two) {' Надеюсь, вы не стреляете в игру, каждое маленькое изменение и летающие корабли вокруг, так как это медленный способ развития. – weston

ответ

0

Я уже делал что-то подобное раньше. Попробуйте создать rectangle для каждой пули, врага или что-то еще, что у вас есть. Прямоугольники должны иметь размер, соответствующий размеру используемой графики. Конечно, прямоугольники должны двигаться с графикой.

Вы можете проверить, если столкновение произошло просто с

if(rectangleA.intersects(rectangleB)){ 
    doAwesomeStuff(); 
} 

Я надеюсь, что помогает.