【问题标题】:Java referencing to single ArrayList instanceJava 引用单个 ArrayList 实例
【发布时间】:2014-06-04 13:42:14
【问题描述】:

我遇到了我正在使用的 ArrayList 的问题。这是一个包含具有不同颜色和位置的精灵的对象列表。列表成功返回,我可以使用 foreach 循环将它们全部绘制到屏幕上。之后,我正在检查是否有人点击了他们的位置,并且我想返回对象包含的颜色。问题是我总是把颜色变回绿色。可能是因为我引用了所有对象而不是单个对象。我搜索了这个网站,发现了类似的问题和教程。但我似乎找不到修复代码所需的信息,以便我可以在使用 foreach 循环检查所有实例时引用列表中的单个实例。

阅读答案并使用 break 和忘记的 secondColor = true 后,我仍然遇到同样的问题。即使将单击的对象发送到另一个函数,我的问题也没有解决。因此,我不仅显示了读取列表的代码,还显示了列表填充时的代码。如何解决我在读取列表时始终只引用绿色对象但在使用 for 循环绘制时得到每种颜色的问题????

for(KleurWissel i : gameManager.getColorsList())
        {
            i.colorRectangle.draw(batch);
        }
        //Welke kleuren kies je?
        if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
            Iterator<KleurWissel> iterator = gameManager.getColorsList().iterator(); 
            while(iterator.hasNext()) 
            {
                KleurWissel item = (KleurWissel) iterator.next();

                if(item.getRectangle().contains(input.x, input.y)) 
                { 
                    if(firstColor == true && secondColor == false && item.selected == false)
                    {
                        colorArraySecond = item.colorArray;
                        colorArrayUsed = colorArrayFirst;
                        colorSelected = true;
                        item.selected = true;
                        secondColor = true;
                        break;
                    }
                    if(firstColor == false && item.selected == false){
                        colorArrayFirst = item.colorArray;
                        firstColor = true;
                        item.selected = true;
                        break;
                    }
                }
            }  
        }

这里是填充列表的代码。

private int[] colorsRGB = {0, 50, 150, 150, 200, 255};
float[] colorArrayUsed = new float[4];
private ArrayList<KleurWissel> colorsList = new ArrayList<KleurWissel>();


public void setColorsList()
{
    Vector2 tempV;
    KleurWissel temp;
    for(int i = 0; i < 6; i++)
    {
        if(i<3)
        {
            colorArrayUsed[0] = colorsRGB[5-i];
            colorArrayUsed[1] = colorsRGB[0+i];
            colorArrayUsed[2] = 0;
            colorArrayUsed[3] = 1;
            tempV = new Vector2(Gdx.graphics.getWidth()/2 - 150 + i * 150, Gdx.graphics.getHeight()/2 + 130);
        }
        else{
            if(i == 3)
            {
                colorArrayUsed[0] = 0;
                colorArrayUsed[1] = 0;
                colorArrayUsed[2] = colorsRGB[5];
                colorArrayUsed[3] = 1;
                tempV = new Vector2(Gdx.graphics.getWidth()/2 - 150, Gdx.graphics.getHeight()/2);
            }
            else{
                colorArrayUsed[0] = 0;
                colorArrayUsed[1] = colorsRGB[0+i];
                colorArrayUsed[2] = colorsRGB[5-i];
                colorArrayUsed[3] = 1;
                tempV = new Vector2(Gdx.graphics.getWidth()/2 - 600 + i * 150, Gdx.graphics.getHeight()/2);
            }

        }
        temp = new KleurWissel(colorArrayUsed, tempV);

        colorsList.add(temp);
    }
}

public ArrayList<KleurWissel> getColorsList()
{
    return colorsList;
}

KleurWissel 是颜色对象,抱歉有点荷兰语>.>.

【问题讨论】:

  • 一团糟。我建议您为循环中使用的 Gdx.input.getY() 等创建局部变量。眼睛会更轻松,效率也会更高。
  • 你确定问题不在逻辑上,而是在列表的遍历上?
  • 我建议你在调试器下运行这段代码。

标签: java object collections arraylist foreach


【解决方案1】:

根据 cmets 编辑:

libGDX Rectangle 类有一个 contains 方法,看起来这就是您手动检查的内容。您还可以打印一些信息,告诉您有关物体是否被击中的更多信息。

似乎预期的过程如下:

  • 单击第一项时,其颜色应存储为colorArrayFirst
  • 单击第二个项目时,其颜色应存储为colorArraySecondcolorSelected 标志应设置为true

以下代码显示了如何做到这一点。但问题仍然是这些信息何时会“重置”。也就是两个数组什么时候重置为nullcolorSelected标志什么时候重置为false

private boolean colorSelected = false;
private int colorArrayFirst[] = null;
private int colorArraySecond[] = null;

void someGameLoopMethod()
{
    if(Gdx.input.isButtonPressed(Input.Buttons.LEFT))
    {
        Iterator<ColorObject> iterator = gameManager.getColorsList().iterator();
        while(iterator.hasNext())
        {
            ColorObject item = (ColorObject) iterator.next();

            float x = Gdx.input.getX();
            float y = Gdx.input.getY();
            Rectangle r = item.colorRectangle;

            System.out.println("Check if "+x+" "+y+" is in "+r+": "+r.contains(x,y));

            if (r.contains(x,y))
            {
                clickedItem(item);
            }
        }
    }
}


private void clickedItem(ColorObject item)
{
    if (colorArrayFirst == null)
    {
        colorArrayFirst = item.colorArray;
    }
    else if (colorArraySecond == null)
    {
        colorArraySecond = item.colorArray;
        colorSelected = true;
    }
}

// TODO Think about when this method should be called
private void resetClickingInformation()
{
    colorSelected = false;
    colorArrayFirst = null;
    colorArraySecond = null;
}

【讨论】:

  • 第一种和第二种颜色用于保存选择的颜色。之后游戏开始,这些颜色用于创建两个新对象。也用于获得正确的颜色以进行绘画。
  • Ow 并感谢您的回复,contain 方法比我以前使用的方法要好得多:D。
  • @Ano333333 好的,我仍然想知道为什么这可以被接受为答案。如果它以某种方式帮助解决了您的问题,那么如果您告诉我们实际问题是什么,那就太好了。如果它没有有助于解决问题,则不应将其标记为“已接受”答案(最好只标记为“有帮助”)
  • 抱歉,误解了标记的目的,但问题仍然存在,因为我无法从数组列表中获取单击对象的颜色。
  • @Ano333333 请再次解释(最好通过编辑您的原始问题)firstColorsecondColor 标志的用途以及它们的使用方式。它们在哪里设置为truefalse?您想保存到(最多)两个鼠标单击的对象的颜色是否正确?
【解决方案2】:

您原始问题中的逻辑很好,除了您需要添加任何一个

secondColor = true;
break;

在带有if(firstColor == true &amp;&amp; secondColor == false)的块内。

如果您不这样做,那么在设置第二种颜色后,您将继续遍历 ColorObject 对象,寻找更多包含被单击点的对象,直到最终到达最后一个 - 大概横跨整个画布并以绿色为颜色。

break; 不是绝对必要的,但它可以让您避免重复迭代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-18
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多