未从LinkedList中删除Java项
我正在开发一个简单的视频游戏,很快就遇到了一个无法修复的问题……我的游戏中有很多敌人,所以他们当然都继承自一个类未从LinkedList中删除Java项,java,linked-list,Java,Linked List,我正在开发一个简单的视频游戏,很快就遇到了一个无法修复的问题……我的游戏中有很多敌人,所以他们当然都继承自一个类敌人。但是当玩家和敌人发生碰撞时,敌人不会被移除……这是我为实体,蓝敌,控制器,以及敌人编写的代码。我假设我的Player类没问题,因为当它们碰撞时,我的播放器会消失 Entity.java package com.darksunproductions.ld47.Entities; import java.awt.Point; import java.awt.image.Buffer
敌人。但是当玩家和敌人发生碰撞时,敌人不会被移除……这是我为实体
,蓝敌
,控制器
,以及敌人
编写的代码。我假设我的Player
类没问题,因为当它们碰撞时,我的播放器会消失
Entity.java
package com.darksunproductions.ld47.Entities;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import com.darksunproductions.ld47.Game.Game;
public class Entity {
private int x;
private int y;
private Point pos;
private double velX;
private double velY;
private BufferedImage icon;
private boolean dead = false;
private int updatesSinceDeath = -1;
protected Game game;
protected Entity(int x, int y, double velX, double velY, Game game, BufferedImage icon){
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
this.game = game;
this.icon = icon;
}
public void setUpdatesSinceDeath(int i){
updatesSinceDeath = i;
}
public int getUpdatesSinceDeath(){
return updatesSinceDeath;
}
public boolean isDead(){
return dead;
}
public void kill(){
dead = true;
updatesSinceDeath = 0;
try{
icon = ImageIO.read(new File("Explosion.png"));
}catch(Exception e){
e.printStackTrace();
}
}
public Point topLeft(){
return new Point(x, y);
}
public Point topRight(){
return new Point(x+icon.getWidth(), y);
}
public Point bottomLeft(){
return new Point(x, y+icon.getHeight());
}
public Point bottomRight(){
return new Point(x+icon.getWidth(), y+icon.getHeight());
}
public void setX(int x){
this.x = x;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setY(int y){
this.y = y;
}
public double getVelX() {
return velX;
}
public void setVelX(double velX) {
this.velX = velX;
}
public double getVelY() {
return velY;
}
public void setVelY(double velY) {
this.velY = velY;
}
public BufferedImage getIcon() {
return icon;
}
public void setIcon(BufferedImage icon) {
this.icon = icon;
}
}
java
package com.darksunproductions.ld47.Entities;
import java.io.File;
import javax.imageio.ImageIO;
import com.darksunproductions.ld47.Game.Drawable;
import com.darksunproductions.ld47.Game.Game;
public class BlueEnemy extends Enemy implements Drawable{
public BlueEnemy(int x, int y, double velX, double velY, Game game){
super(x, y, velX, velY, game, null, Type.BLUE);
try{
setIcon(ImageIO.read(new File("Blue_Enemy.png")));
}catch(Exception e){
setIcon(null);
}
}
}
package com.darksunproductions.ld47.Entities;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import com.darksunproductions.ld47.Game.Drawable;
import com.darksunproductions.ld47.Game.Game;
public class Enemy extends Entity implements Drawable{
public enum Type{
BLUE
}
private Type type;
public Enemy(int x, int y, double velX, double velY, Game game, BufferedImage icon, Type type){
super(x, y, velX, velY, game, icon);
this.type = type;
}
public void render(Graphics g){
if(getIcon() != null)
g.drawImage(getIcon(), getX(), getY(), null);
}
public void update(){
if(getUpdatesSinceDeath() < 0){
setY(getY() + (int)getVelY());
if(getY() > 550){
setY(-50);
setX((int)(Math.random()*468));
}
}else if(getUpdatesSinceDeath() >= 0){
setUpdatesSinceDeath(getUpdatesSinceDeath() + 1);
if(getUpdatesSinceDeath() > 60){
game.c.remove(this);
}
}
}
}
Controller.java
package com.darksunproductions.ld47.Game;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;
import com.darksunproductions.ld47.Entities.Enemy;
import com.darksunproductions.ld47.Entities.Entity;
import com.darksunproductions.ld47.Entities.Player;
public class Controller {
LinkedList<Drawable> entities = new LinkedList<Drawable>();
Game game;
public Controller(Game g){
game = g;
}
public void testCollision(int startID){
if(entities.size() > 0){
Entity e1 = (Entity) entities.get(startID);
Point corner[] = new Point[4];
corner[0] = e1.topLeft();
corner[1] = e1.topRight();
corner[2] = e1.bottomLeft();
corner[3] = e1.bottomRight();
for (int e = startID + 1; e < entities.size(); e++) {
Entity e2 = (Entity) entities.get(e);
for (int c = 0; c < 4; c++) {
if (corner[c].x > e2.topLeft().x && corner[c].x < e2.topRight().x) {
if (corner[c].y > e2.topLeft().y && corner[c].y < e2.bottomLeft().y) {
collide(e1, e2);
}
}
}
}
}
}
public void collide(Entity e1, Entity e2){
if(e1 instanceof Player && !e1.isDead()){
if(e2 instanceof Enemy && !e2.isDead()){
e1.kill();
e2.kill();
}
}
}
public void update(){
if(entities.size() > 0){
for(Drawable d : entities)
d.update();
}
}
public void render(Graphics g){
if(entities.size() > 0){
for(Drawable d : entities)
d.render(g);
}
}
public void add(Drawable d){
entities.add(d);
}
public void remove(Drawable d){
entities.remove(d);
}
public void remove(int i){
entities.remove(i);
}
public int size(){
return entities.size();
}
public int getIdOf(Entity e){
for(int i = 0; i < entities.size(); i++){
if(e == (Entity)entities.get(i))
return i;
}
return -1;
}
public int getIdOf(Drawable d){
Entity e = (Entity)d;
for(int i = 0; i < entities.size(); i++){
if(e == (Entity)entities.get(i))
return i;
}
return -1;
}
}
除了一个小问题……当我点击LinkedList.java:778时,Eclipse说LinkedList没有第778行
提前感谢您提供的任何帮助…我假设game.c是BlueDebuy类中的控制器,在这种情况下,您将在控制器中循环使用可能从中删除的同一列表。这就是并发修改异常的原因。您可以在列表的副本上循环,这将是一个解决办法。我假设game.c是BlueDebuy类中的控制器,在这种情况下,您将在控制器中循环您可能从中删除的同一列表。这就是并发修改异常的原因。您可以循环查看列表的副本,这将是一个解决方法。game.c.remove(此)
是不良设计的良好指示器,实体不负责决定何时移除它,只负责向控制器提供它可以使用的信息
主要问题是,增强的循环涉及到列表
的迭代器
,这会阻止在对基础列表
进行迭代时对其进行修改
相反,您可以自己使用列表
s迭代器
,当控制器
确定某个实体已失效(死亡或其他情况)时,例如,使用迭代器
的删除
方法将其删除
public void update(){
if(entities.size() > 0){
LinkedList<Drawable> entities = new LinkedList<>();
while (it.hasNext()) {
Drawable d = it.next();
d.update();
// Or what ever flag you want to use
if (d.isRemovable()) {
it.remove(d);
}
}
}
}
public void update(){
如果(entities.size()>0){
LinkedList entities=新建LinkedList();
while(it.hasNext()){
Drawable d=it.next();
d、 更新();
//或者你想用什么标志
如果(d.isRemovable()){
删除(d);
}
}
}
}
game.c.移除(此)
是不良设计的良好指示器,实体不负责决定何时移除它,只负责向控制器提供它可以使用的信息
主要问题是,增强的循环涉及到列表
的迭代器
,这会阻止在对基础列表
进行迭代时对其进行修改
相反,您可以自己使用列表
s迭代器
,当控制器
确定某个实体已失效(死亡或其他情况)时,例如,使用迭代器
的删除
方法将其删除
public void update(){
if(entities.size() > 0){
LinkedList<Drawable> entities = new LinkedList<>();
while (it.hasNext()) {
Drawable d = it.next();
d.update();
// Or what ever flag you want to use
if (d.isRemovable()) {
it.remove(d);
}
}
}
}
public void update(){
如果(entities.size()>0){
LinkedList entities=新建LinkedList();
while(it.hasNext()){
Drawable d=it.next();
d、 更新();
//或者你想用什么标志
如果(d.isRemovable()){
删除(d);
}
}
}
}
通常,您可以使用LinkedList
sIterator
和remove
方法来避免这种情况,但由于您要传递一些责任,这就有点困难了。你可以做的一件事,就是不用game.c.remove(这个)
在敌方
内部,您可以将敌方
标记为“可移动”,以便在更新周期期间或更新之后,您可以收集所有“已移除”元素,然后使用removeAll
一步移除它们。这应该在渲染过程之前完成。您得到的异常意味着您在某个地方有竞争条件,即两个线程试图访问相同的列表,或者您试图删除的项目是您正在浏览的列表…方式不好。在控制器中#更新方法,而不是for(可绘制的d:实体)
,您需要获取实体的一个实例
迭代器
,并使用它来循环实体。每次调用d.update
,都需要检查是否应该删除该实体,并使用迭代器的删除方法删除它…不正确,mmalik。您可以轻松地在删除集合元素的同时对集合进行迭代,只要您采取适当的措施-在删除元素后递减i
(不这样做甚至可能是导致此问题的原因),或者,如果它是LinkedList或LinkedHashMap或类似的非连续集合,程序员对迭代器的看法。通常,您可以使用LinkedList
sIterator
,它是remove
方法来避免这种情况,但是由于您要传递一些责任,这就有点困难了。你可以做的一件事,就是不用game.c.remove(这个)
在敌方
内部,您可以将敌方
标记为“可移动”,以便在更新周期期间或更新之后,您可以收集所有“已移除”元素,然后使用removeAll
一步移除它们。这应该在渲染过程之前完成。您得到的异常意味着您在某个地方有竞争条件,即两个线程试图访问相同的列表,或者您试图删除的项目是您正在浏览的列表…方式不好。在控制器中#更新方法,而不是for(可绘制的d:实体)
,您需要获取实体的一个实例
Iter