我有一个射击游戏,当按下空格键时,会创建一个子弹对象。当子弹对象在屏幕之外时,我想删除对象,这样我可以拍摄10次以上。
实例化:
Shot[] shot = new Shot[10];
空格键代码:
if (key == KeyEvent.VK_SPACE) {
if (shots < maxShots) {
if (canShoot) {
shot[shots] = new Shot(player.x, player.y, player.width, player.height, shotDir);
shots++;
canShoot = false;
}
}
}
绘图代码:
for (int i = 0; i < shots; i++) {
if (shot[i].active) {
shot[i].drawShot(g);
}
}
我想要删除镜头:
for (int i = 0; i < shots; i++) {
shot[i].shotLoop();
if (shot[i].outOfBounds(WINDOW_SIZE.width, WINDOW_SIZE.height)) {
// Delete Bullet
shot[i].active = false;
}
}
我尝试shots--;
但是当一次拍摄离开屏幕时,屏幕上当前的所有镜头都会被删除。有什么建议吗?
以下是shot[i].outOfBounds()
代码
public boolean outOfBounds(int screenx, int screeny) {
if (x < 0 || x > screenx || y < 0 || y > screeny) {
return true;
} else {
return false;
}
}
答案 0 :(得分:1)
请改用ArrayList,以便在超出范围时将其从列表中删除?
ArrayList<Shot> shot = new ArrayList<Shot>();
迭代时不应删除,因此您可能必须存储对象的索引(或对象本身),并在找到要删除的项目符号后删除它们。
此外,如果你只想要10,你可以设置10的容量,只需监控大小以确保它不会过去。
答案 1 :(得分:0)
class Weapon
{
private ArrayList<Shot> magazine;
private int maxShots;
private double rotationAngle = 90;
private double rotationSpeed = 1.5;
public Weapon(int maxShots)
{
this.maxShots = maxShots;
magazine = new ArrayList<Shot>(maxShots);
}
public void rotate(int direction)
{
// no need to create hashamp etc to hold "left" or "right"
// when passing keyPressed, KeyeEvent.getKeyCode is enough.
// i see alot of people having separate if statements,
// why, i dont know when you can only go in one
// direction at a time!
// also of note, most people wrongly assume that
// either left or right will be passed, hence, if/else
// statements. use "if/else if" to guarantee only
// left or right
if (direction == KeyEvent.VK_LEFT)
{
angle-=speed;
}
else if (direction == KeyEvent.VK_RIGHT)
{
angle+=speed;
}
}
public void draw(Graphics2D g2, Dimension boundary)
{
// do NOT check if shot is out of bounds here,
// the only thing that should be done in draw,
// is draw!
}
public Iterator<Shot> getMagazine()
{
// by returning the iterator, you guarantee
// concurrency i.e preventing concurrent modifications
// to data, for example, drawing shots, moving shots
// and removing them
return magazine.iterator();
}
public void shoot()
{
double radian = Math.toRadians(-angle); // invert angle
double x = [center x] + ([length of weapon] * Math.cos(radian))-[your shot diameter];
double y = [center y] + ([length of weapon] * Math.sin(radian))-[your shot diameter];
if (magazine.size() < capacity)
{
magazine.add(new Shot(x,y,radian));
}
}
}
class Shot extends Ellipse2D.Double
{
Point2D.Double point;
Point2D.Double velocity;
double shotSpeed = 10;
public Shot(Point2D.Double origin, double radian)
{
velocity = new Point2D.Double(Math.cos(radian)*shotSpeed,Math.sin(radian)*shotSpeed);
point = new Point2D.Double(origin.x+velocity.x,origin.y+velocity.y);
setFrame(point.x,point.y,[shot diameter],[shot diameter]);
}
public void draw(Graphics2D g2)
{
g2.setColor(Color.pink);
g2.fill(this);
}
public void move()
{
point.x+=velocity.x;
point.y+=velocity.y;
setFrame(point.x,point.y,[shot diameter],[shot diameter]);
}
}
// use javax.swing.Timer to update/paint instead is
// while(true) with a Thread.sleep. it allows for stopping and
// restarting without creating additional objects
public void actionPerformed(ActionEvent event)
{
// check for rotation......
// check for shots fired....
// iterator is faster than conditional loops
Iterator<Shot> iterator = weapon.getMagazine();
while(iterator.hasNext())
{
Shot shot = iterator.next();
// getBounds() is the bounds of your panel
// shot.getBounds() is an inherited method of
// Ellipse2D.Double
// use java.awt.geom.RectangleShape.contains(Rectangle) method
if (getBounds().contains(shot.getBounds()))
{
// if the shot is within the rectangle, move it
shot.move();
}
else
{
iterator.remove();
}
}
// collision detection etc...
repaint();
}