# Focus on item from ArrayList in zty.pe like game

**URL:** <https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522>\
**Category:** Libraries\
**Created:** [September 13, 2018, 7:20pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522 "2018-09-13T19:20:57Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 13, 2018, 7:20pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/1 "2018-09-13T19:20:57Z")

</div>

I am in the process of making a zty.pe game, and I have defined classes for own ship, enemies (those meant to be shot with words) as well as a projectile which own ship fires. The Enemy-class item has a string assigned when it is created. When the user presses a key on the keyboard Enemy-class will then react if it corresponds to the first character of the assigned string:

```auto
if (outputString.length() >= 1 && key == outputString.charAt(0) {
            manipulString.deleteCharAt(0);
            projectiles.add(new Projectile(location.x, location.y));
            score = score + 1;
        }

```

This works, however, it is not good enough, as it should only choose the item which is corresponds and is closest.

I am trying to remedy this by making a new ArrayList out of the ArrayList of enemies, where I only include the items with the first character of the word/belonging string.

```auto
boolean corresponding() {
      if (outputString.length() >= 1 && key == outputString.charAt(0))
        return true;
    }

```

I would then like to sort the items after which items have the closest `PVector location`, i.e. sort after

```auto
enemies.location.dist(new PVector(width/2, height-40));

```

which is the distance to the mothership/own ship. I have searched for ways to sort ArrayLists with PVector, however, it seems to not be applicable in this case.

Gif of how it currently works. Additionally, if two characters repeat, it will remove both of them.

 ![2018-09-13_21-01-42](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/30e20439e70ad591b5b6a0b69e8b4a8df6db9c00.gif)

Thank you in advance. Please tell me if this is not understandable. Alternatively, [I have linked my GitHub repository](https://github.com/Pyrross/ptype) where `fjender.pde` is the Enemy class, `skib.pde` is the OwnShip class, `projektilet.pde` is the Projectile class and the main sketch is `Spiludvikling.pde`.

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [September 13, 2018, 10:08pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/2 "2018-09-13T22:08:19Z")

</div>

First off, this is a well formatted question - I appreciate the work you’ve put into this.

However, I don’t know if I completely understand your problem, so I want to clarify:

- The closest ship needs to be found
- Only the current “target” ship should have letters removed

Is this right? Assuming it is, let’s address that first problem

**Finding The Closest Ship**  
It looks like you already understand how to find distance:

`enemies.location.dist(new PVector(width/2, height-40));`

However, while there are a variety of ways to sort these distances, a question I ask is - do you care about any of the distances besides the closest ship? If not, it might be simpler to find the smallest distance, and remember it’s index.

```auto
// pseudocode
enemy_distance_list = all enemy distances from mothership

min_index = 0
for ( i < enemy_distance_list.length )
   if ( enemy_distance_list[i] < enemy_distance_list[min_index] )
     min_index = i;

```

Something like this might work. So the second question is, what do we do with this “closest” ship?

**Targeting Only The Closest Ship**

I played zty.pe a little and one of the elegant things it does is “lock” you onto a ship until you have destroyed it - this means that even if a different ship is closer, you don’t care about it until the first ship is gone. So maybe you can keep track of the current “target” with a global variable of some sort. The only times you need to search for the closest enemy is whenever the current target is destroyed, or a new wave starts!

Does this help?

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 14, 2018, 6:41am UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/3 "2018-09-14T06:41:55Z")

</div>

Hi tony, thank you for your answer. I think you understood it correctly. However, your interpretation of the locking system is not entirely correct, as you can _unlock_ by pressing backspace — this should not be a huge thing to implement.

Although your pseudocode is helpful, I am still unsure as to how I can do this. Have you seen my GitHub directory? If not, I will try to explain my programme in further detail:  
My Enemy-class consists of PVectors for velocity, location and targetLocation. The enemies are in `ArrayList<Enemy> enemies = new ArrayList<Enemy>();`. Can I just sort these by making a list?

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [September 14, 2018, 3:47pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/4 "2018-09-14T15:47:48Z")

</div>

I was thinking you could iterate through `enemies` and make a temporary array of floats, lets say, `enemy_distances`. It would be an unsorted array. From there, you would find the smallest ‘distance’ just by iterating through the entire array with that pseudocode I wrote above.

Now the key is that you would be searching for the smallest distance, **but** remembering just the index of it. This way, that index you found would correspond to the index of the enemy with that shortest distance.

Does that make sense?

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 14, 2018, 8:01pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/5 "2018-09-14T20:01:44Z")

</div>

Hi Tony, it does. I am not fully aware as to how I have to code it, I have come up with the following:

```auto
void sortering () {
  int indexFlag = 0;
  for (Enemy before : enemies) {
    indexFlag = indexOf(before);
    for (Enemy inProcess : enemies) {
      if (before != inProcess) {
        if (inProcess.distance < before.distance && indexOf(inProcess) > indexFlag && before.corresponding) {
          int indexinProcess = indexOf(inProcess);
          int indexbefore = indexOf(before);
          enemies.set(indexinProcess, before);
          enemies.set(indexbefore, inProcess);
        }
      }
    }
  }
}

```

However, it does not work (not surprisingly, as I am not entirely sure about how to do this). I want to sort, where I have an indexFlag (standpoint), a for-loop which goes through the different enemies. `before` should be the first to initially be what is at enemies[0], and indexFlag should be set to be the indexOf(before). Then it should loop through different enemies (inProcess) if before is not the same as inProcess (before and inProcess are items from enemies). If inProcess’ distance is less than that of before as well as having index after indexFlag, it (inProcess) should switch places with before. This will then continue until it is correctly sorted.

Do you think this (not the code, the idea) will work? And do you have the capacity to help with rewriting the code?

Thank you.

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [September 15, 2018, 12:05am UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/6 "2018-09-15T00:05:35Z")

</div>

Lets start by making a float array. How long should this be? As long as enemies ArrayList.

`float[] distances = new float[enemies.length];`

Now, lets load up our array:

```auto
for(int i = 0; i < enemies.length; i++)
{
   distances[i] = enemies[i].location.dist(new PVector(width/2, height-40));
}

```

Finally, lets, find the index of the smallest distance:

```auto
int mindex = 0; // This should be a global variable

for(int i = 0; i < enemies.length; i++)
{
   if( distances[i] < distances[mindex] )
   {
      mindex = i;
   }
}

```

At this point, we can use `mindex` to find the enemy with the closest distance.  
As a function, this might look like:

```auto
int getIndexOfClosestEnemy()
{
   int mindex = 0; // This should be a global variable
   float[] distances = new float[enemies.length];
   for(int i = 0; i < enemies.length; i++)
   {
      distances[i] = enemies[i].location.dist(new PVector(width/2, height-40));
   }
   
   for(int i = 0; i < enemies.length; i++)
   {
      if( distances[i] < distances[mindex] )
      {
         mindex = i;
      }
   }

   return mindex;
}

```

Hope this helps 🤙 (Note: I didn’t test any of this in the IDE so it probably needs to be debugged)

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 15, 2018, 9:57am UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/7 "2018-09-15T09:57:35Z")

</div>

Thank you so much tony, that was very helpful. As my enemies is an ArrayList and not just a list I have changed the code a bit. In my drawEnemy method, where I loop through my enemies ArrayList, I suppose I should implement our sorting mechanism by saying something like

```auto
if (i == mindex) {
        manipulString.deleteCharAt(0);
        projectiles.add(new Projectile(location.x, location.y));
        score = score + 1;
}   

```

The sorting algorithm now looks like this:

```auto
void sortering () {
  float[] distances = new float[enemies.size()];

  for (int i = 0; i < enemies.size(); i++)
  {
     distances[i] = enemies.get(i).location.dist(new PVector(width/2, height-40));
  }

  for (int i = 0; i < enemies.size() - 1; i++)
  {
     if ( distances[i] < distances[mindex] )
     {
        mindex = i;
     }
  }
}

int getIndexOfClosestEnemy () {
   int mindex = 0; // This should be a global variable
   float[] distances = new float[enemies.size()];
   for (int i = 0; i < enemies.size(); i++)
   {
      distances[i] = enemies.get(i).location.dist(new PVector(width/2, height-40));
   }

   for(int i = 0; i < enemies.size(); i++)
   {
      if( distances[i] < distances[mindex] && enemies.get(i).corresponding)
      {
         mindex = i;
      }
   }
   return mindex;
}

```

However, when I try to use it

```auto
void drawEnemy() {
  for (int i = enemies.size()-1; i >= 0; i--) {
    Enemy enemy = (Enemy) enemies.get(i);
    enemy.informationProjektil();
    sortering();
    getIndexOfClosestEnemy();
    if (i == mindex && keyPressed && enemy.corresponding && key == enemy.manipulString.charAt(0) && enemy.manipulString.length() > 0) {
          enemy.manipulString.deleteCharAt(0);
          projectiles.add(new Projectile(enemy.location.x, enemy.location.y));
          score = score + 1;
    }
    if (enemy.dead())
        enemies.remove(i);
    enemy.update();
    enemy.display();
    if (enemy.location.x < width / 2 + 20 && enemy.location.x > width / 2 - 20 && enemy.location.y > height - 60 && enemy.location.y < height - 20)
        end = true;
  }
}

```

I get this error: `fjender.pde:103:0:103:0: StringIndexOutOfBoundsException: String index out of range: 0`. Line 103 is where it says `if (i == mindex && keyPressed && enemy.corresponding ... )`  
I do not understand why, as I think I have ensured that it shouldn’t happen. Other than that, the algorithm works. My manipulString is a StringBuilder object.

EDIT: it only focuses on the nearest. It should focus on the nearest corresponding enemy.

**BIG UPDATE:**  
So I fixed the major error with StringIndexOutOfBoundsException by making a new if-statement instead of incorporating it in an already existing one. However, I have got two problems (the latter being somewhat unrelated to the topic):

1. It only focuses on the nearest enemy. It does not focus on the nearest enemy that corresponds.
2. If a word has repeating characters it will actually delete both of them, whereas it should only delete one. Please see the image: ![2018-09-15_13-08-14](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/9/99abea15ccfa977f8623e77872c90310d5927453.gif)

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [September 15, 2018, 4:37pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/8 "2018-09-15T16:37:55Z")

</div>

> [@Pyrros](#):
>
> 1. It only focuses on the nearest enemy. It does not focus on the nearest enemy that corresponds.

What does this line really do?

```auto
    if (i == mindex && keyPressed && enemy.corresponding && key == enemy.manipulString.charAt(0) && enemy.manipulString.length() > 0) {

```

What is `mindex` telling you?

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 15, 2018, 5:02pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/9 "2018-09-15T17:02:54Z")

</div>

`mindex` tells me at what index in the enemies ArrayList the enemy with the smallest distance is positioned. The line checks whether an enemy is closest, whether or not a key has been pressed and if the enemy corresponds. The last to conditionals are not relevant.

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [September 15, 2018, 8:05pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/10 "2018-09-15T20:05:27Z")

</div>

Oh, I didn’t see that second conditional in `getIndexOfClosestEnemy()`.

Is drawEnemy() run every frame? If so, `getIndexOfClosestEnemy()` is going to be called 60 times a second, and in just the first frame, your closest enemy is going to found, decremented, and “disqualified”.

This is a guess, but to address this, perhaps have a global `Enemy target`, and check only `target` every `draw()` loop, unless `target` is destroyed or you switch to a different target. This might require some code restructuring.

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 16, 2018, 1:20pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/11 "2018-09-16T13:20:28Z")

</div>

Alright @tony, I am not entirely sure about what you are saying. drawEnemy() is drawn every frame, but what do you mean by it being “found, decremented, and “disqualified””?  
I don’t think that targetting is really important. I just want it to shoot/select the closest corresponding enemy (that is, where `keyPressed && key == enemy.manipulString.charAt(0)` evaluates to `true`). I have tried a lot of ways to implement this, but it either fails miserably and messes up the whole thing or just doesn’t work. I think I need to change the sorting algorithm somewhat, to also accommodate whether `enemies.get(mindex).corresponding == true`. This is just a minor issue though.  
Largely thanks to you my game works quite well:

 ![2018-09-16_15-18-37](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/546fbf434a22221963cb7506271327fbded40274.gif)

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [September 16, 2018, 8:44pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/12 "2018-09-16T20:44:20Z")

</div>

The reason I suggested using a `target` is because, 60 times a second, you are iterating through _every single enemy in your list_.

As you said yourself, all you care about is the

> [@Pyrros](#):
>
> closest corresponding enemy

In addition, having a `target` would address that other bug:

> [@Pyrros](#):
>
> 1. If a word has repeating characters it will actually delete both of them, whereas it should only delete one. Please see the image:

The reason (I think) this problem is happening, is due to the fact that you’re going through the entire enemy list every frame. It is very hard to hold down a key _for a single frame_, meaning that if you press **‘a’** , it’s going to be detected for multiple frames.

**Take this example:**

- You have two enemies, `APPLE` and `ANT`
- You press **‘a’** , which is detected for at least **2 frames**

Given that `enemyDrawn()` is called _every frame_:

Frame 01 → `APPLE` is detected, targeted, and the first `A` is deleted. `PPLE` is left  
Frame 02 → `PPLE` does not correspond to the current key ‘ **a** ’, so the next valid enemy is `ANT`. `ANT` is targeted, `A` is removed, `NT` is left.

This is all executed in _only two frames_. To the viewer, it looks like our program is buggy and deleting all the enemies with A in the front!

I hope this helps. As it currently is, the game looks great!

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 17, 2018, 8:25am UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/13 "2018-09-17T08:25:50Z")

</div>

Oops @tony, apparently I forgot to tell you that I have already solved problem 2:

> [@](#):
>
> 1. If a word has repeating characters it will actually delete both of them, whereas it should only delete one.

by putting `keyPressed = false;` at the end of the `draw`-loop.

As making `target`s would require a major reprogramming of the whole thing, I would like to avoid that. It is not a major issue though.

I am trying to use audio, put I keep getting errors:

```auto
sep. 17, 2018 10:14:32 AM com.jsyn.devices.javasound.JavaSoundAudioDevice 
INFO: JSyn: default output latency set to 80 msec for Windows 10
sep. 17, 2018 10:14:32 AM com.jsyn.engine.SynthesisEngine start
INFO: Pure Java JSyn from www.softsynth.com, rate = 44100, RT, V16.8.0 (build 463, 2017-10-16)
Spiludvikling.pde:18:0:18:0: ArrayIndexOutOfBoundsException

```

where Spiludvikling.pde:18:0:18:0 is

```auto
    eksplosionsLyd = new SoundFile(this, "eksplosion.mp3");

```

And I have installed library Sound.

```auto
import processing.sound.*;
SoundFile eksplosionsLyd;

    eksplosionsLyd = new SoundFile(this, "eksplosion.mp3");

...

        eksplosionsLyd.play();
        eksplosionsLyd.amp(1);

```

The soundfile exists. Could this be a problem with the library/incompability?

---

<div class="post-metadata">

**Author:** ![Pyrros](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@Pyrros](https://discourse.processing.org/u/Pyrros)\
**Post date:** [September 17, 2018, 10:30am UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/14 "2018-09-17T10:30:32Z")

</div>

> [@Pyrros](#):
>
> The soundfile exists. Could this be a problem with the library/incompability?

I have solved the problem by using Minim.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [September 22, 2018, 10:52pm UTC](https://discourse.processing.org/t/focus-on-item-from-arraylist-in-zty-pe-like-game/3522/15 "2018-09-22T22:52:21Z")

</div>

> [@Pyrros](#):
>
> as it should only choose the item which is corresponds and is closest.

This was a very interesting discussion – and I love the game project.

My understanding of zty.pe’s opening levels is that it constrains the enemy set so that, when new enemies are spawned, the new enemy always has a unique first letter. There are never two enemies beginning with ‘a’ on the screen at the same time, so the player doesn’t need to think about proximity – whatever word they are looking at and begin typing always works, as if by magic (although this magic can never have more than 26 labeled enemies on screen).

If a word is partially consumed and then unlocked with backspace – say, ‘basis’-\>‘sis’ – and another whole word is available – say ‘shy’ – then one way to choose is proximity. However one could also choose the first spawned, or the last touched, or the shortest or the most consumed (with tiebreaker).

I personally would probably ditch the backspace unlocking option. It adds a lot of complexity and I’m not sure why it is useful for gameplay.
