Téléportation random entre points définis

Kenda

Architecte en herbe
16 Juillet 2016
300
1
2
125
32
www.youtube.com
Bonjour/bonsoir,

Actuellement en train de ctée un mini-jeu, je suis à la recherche d'une méthode pouvant faire une téléportation aléatoire au coordonnées précise.

Par exemple, j'ai défini 6 coordonnées :

Java:
        World world = Bukkit.getWorld("world");
        spawns.add(new Location(world, 948.500, 79, -16.500, -90f, 0f));
        spawns.add(new Location(world, 970.500, 73, -5.500, -90f, 0f));
        spawns.add(new Location(world, 986.500, 77, 25.500, 180f, 0f));
        spawns.add(new Location(world, 1018.500, 80, -21.500, 65.5f, 6f));
        spawns.add(new Location(world, 1024.500, 81, 10.500, 180f, 0f));
        spawns.add(new Location(world, 1049.500, 79, -12.500, 90f, 0f));

J'aimerai savoir, comment faire pour téléporter mes joueurs à une location aléatoire entre cette liste :)

(Exemple : Joueur 1, téléporter à spawn 2, et joueur 2 téléporter au spawn 6)


Merci bien de l'aide :)
 
Solution
Bonsoir,

Il te suffit de récupérer la liste où tu l'a définie, avec un accesseur si nécessaire.
Et sinon, tu peux aussi mélanger une liste avec Collections#shuffle(List<?>), puis après récupérer les positions dans l'ordre.

Une variante de ton code avec un plus de robustesse :
Java:
public class K265 {
   public static final List<Location> SPAWN_LOCATIONS = new LinkedList<>();
  
   static {
      World world = Bukkit.getWorld("world");
      if(world == null)
         throw new NullPointerException("The world 'world' does not exist or is unloaded");
     
      SPAWN_LOCATIONS.add(new Location(world,   948.5d  ,  79d  ,  -16.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   948.5d  ,  79d  ,  -16.5d  ,  -...

EdgarPi

Correcteur
Staff
Correcteur
9 Février 2014
179
13
25
135
Salut !

Il existe la class Random tout simplement. Une de ses méthodes est getInt(int max).

Donc, pour choisir dans ta liste :

Java:
private Location getRandomLocation(List<Location> locs) {
    Random random = new Random();
    return locs.get(random.getInt(locs.size()));
}
//Random#getInt(int max) retourne un nombre entre 0 inclus et [max] exclus ([0;max[).

EDIT: En informatique, comprendre est la clé. Donc si tu ne comprends pas une partie, n'hésite pas ;)

En espérant avoir pu t'aider,

EdgarPi
 

Kenda

Architecte en herbe
16 Juillet 2016
300
1
2
125
32
www.youtube.com
Salut !

Il existe la class Random tout simplement. Une de ses méthodes est getInt(int max).

Donc, pour choisir dans ta liste :

Java:
private Location getRandomLocation(List<Location> locs) {
    Random random = new Random();
    return locs.get(random.getInt(locs.size()));
}
//Random#getInt(int max) retourne un nombre entre 0 inclus et [max] exclus ([0;max[).

EDIT: En informatique, comprendre est la clé. Donc si tu ne comprends pas une partie, n'hésite pas ;)

En espérant avoir pu t'aider,

EdgarPi


Je connais la class Random, mais je l'ai très très peu expérimenté. Pour sa que je fais des systèmes un peu plus complexe histoire de m'entrainé et comprendre.
En tous cas, je te remercie bien de l'aide et je pense avoir compris comment sa marche :)

Merci de ton aide, et à voir si sa fonctionne :)
 

Kenda

Architecte en herbe
16 Juillet 2016
300
1
2
125
32
www.youtube.com
Je connais la class Random, mais je l'ai très très peu expérimenté. Pour sa que je fais des systèmes un peu plus complexe histoire de m'entrainé et comprendre.
En tous cas, je te remercie bien de l'aide et je pense avoir compris comment sa marche :)

Merci de ton aide, et à voir si sa fonctionne :)


EDIT :

Je viens de l'intégré dans mon code, mais je n'arrive pas vraiment à comprendre comment le faire fonctionner.

Par exemple, j'ai déjà crée ma liste
Code:
private List<Location> spawns = new ArrayList<>();
J'ai mes localisation de spawns ici :
Code:
//Load Spawns
        World world = Bukkit.getWorld("world");
        spawns.add(new Location(world, 948.500, 79, -16.500, -90f, 0f));
        spawns.add(new Location(world, 970.500, 73, -5.500, -90f, 0f));
        spawns.add(new Location(world, 986.500, 77, 25.500, 180f, 0f));
        spawns.add(new Location(world, 1018.500, 80, -21.500, 65.5f, 6f));
        spawns.add(new Location(world, 1024.500, 81, 10.500, 180f, 0f));
        spawns.add(new Location(world, 1049.500, 79, -12.500, 90f, 0f));

Et j'ai ma méthode qui permet de récupéré mes spawns dans une autre class :
Code:
    public List<Location> getSpawns() {
        return spawns;
    }


Ensuite, j'ai pris ta méthode en la modifiant pour y mettre des variables qui permette de mieux m'aiguillé (du moins j'espère :


Code:
private Location getRandomLocation(List<Location> spawns) {
        Random random = new Random();
        return spawns.get(random.nextInt(spawns.size()));
    }

Mais, je n'arrive pas à accéder à cette méthode dans une autre class. Aurais-je oublié quelque chose ?
 

Kenda

Architecte en herbe
16 Juillet 2016
300
1
2
125
32
www.youtube.com
Oui, la méthode est privée, il faut la rendre publique.

Cordialement,
EdgarPi

C'est bon, j'ai bien corrigé, et en effet, je n'avais même pas vu alors que c'est tout con.

Maintenant, question à part, comment faire pour récupéré la liste des spawns définis ?

La méthode est crée, je l'ai implémentés dans une autre class
Code:
for (int i = 0; i < main.getPlayers().size(); i++) {
                    Player player = main.getPlayers().get(i);
                    Location spawn = main.getRandomLocation(); //Ici que je l'ai implementés
                    player.teleport(spawn);
                    player.getInventory().clear();
                    player.setGameMode(GameMode.ADVENTURE);
                    
                    [...]

Hors, je ne sais pas trop comment récupéré ma liste.
 

EdgarPi

Correcteur
Staff
Correcteur
9 Février 2014
179
13
25
135
D'après ce que tu m'as envoyé, ce serait la méthode main.getSpawns() (la méthode qui donne une liste de spawns)

Si je peux me permettre, pour une array la boucle dite foreach est plus efficace. Dans ton cas ce serait for (Player player : main.getPlayers()) {... et tu peux donc supprimer ton Player player = main.getPlayers().get(i); ;)

Pour plus d'exemples : http://www.codeurjava.com/2015/07/La-boucle-java-for-each.html

Cordialement,
EdgarPi
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 308
172
480
247
21
Mìlhüsa
Bonsoir,

Il te suffit de récupérer la liste où tu l'a définie, avec un accesseur si nécessaire.
Et sinon, tu peux aussi mélanger une liste avec Collections#shuffle(List<?>), puis après récupérer les positions dans l'ordre.

Une variante de ton code avec un plus de robustesse :
Java:
public class K265 {
   public static final List<Location> SPAWN_LOCATIONS = new LinkedList<>();
   
   static {
      World world = Bukkit.getWorld("world");
      if(world == null)
         throw new NullPointerException("The world 'world' does not exist or is unloaded");
      
      SPAWN_LOCATIONS.add(new Location(world,   948.5d  ,  79d  ,  -16.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   948.5d  ,  79d  ,  -16.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   970.5d  ,  73d  ,  - 5.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   986.5d  ,  77d  ,   25.5d  ,   180f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,  1018.5d  ,  80d  ,  -21.5d  ,  65.5f  ,  6f  ));
      SPAWN_LOCATIONS.add(new Location(world,  1024.5d  ,  81d  ,   10.5d  ,   180f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,  1049.5d  ,  79d  ,  -12.5d  ,    90f  ,  0f  ));
   }
   
   public static void teleportPlayers(List<Player> players) {
      if(players.isEmpty())
         throw new IllegalArgumentException("players must not be empty");
      
      if(players.size() > SPAWN_LOCATIONS.size())
         throw new UnsupportedOperationException("Not enough spawn locations");
      
      // on mélange les positions
      Collections.shuffle(SPAWN_LOCATIONS);
      
      for(int i = 0; i < players.size(); ++i) {
         Player player = players.get(i);
         Location spawnLocation = SPAWN_LOCATIONS.get(i);
         
         teleportPlayer(player, spawnLocation);
      }
   }
   
   private static void teleportPlayer(Player player, Location spawnLocation) {
      if(!player.teleport(spawnLocation))
         // uh, un plugin tier a annulé la téléportation
         throw new RuntimeException("Teleportation of '" + player.getName() + "' denied");
      
      player.getInventory().clear();
      player.setGameMode(GameMode.ADVENTURE);
      // [...]
   }
}


Cordialement,
ShE3py.
 

EdgarPi

Correcteur
Staff
Correcteur
9 Février 2014
179
13
25
135
Bonsoir,

Il te suffit de récupérer la liste où tu l'a définie, avec un accesseur si nécessaire.
Et sinon, tu peux aussi mélanger une liste avec Collections#shuffle(List<?>), puis après récupérer les positions dans l'ordre.

Une variante de ton code avec un plus de robustesse :
Java:
public class K265 {
   public static final List<Location> SPAWN_LOCATIONS = new LinkedList<>();
  
   static {
      World world = Bukkit.getWorld("world");
      if(world == null)
         throw new NullPointerException("The world 'world' does not exist or is unloaded");
     
      SPAWN_LOCATIONS.add(new Location(world,   948.5d  ,  79d  ,  -16.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   948.5d  ,  79d  ,  -16.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   970.5d  ,  73d  ,  - 5.5d  ,  - 90f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,   986.5d  ,  77d  ,   25.5d  ,   180f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,  1018.5d  ,  80d  ,  -21.5d  ,  65.5f  ,  6f  ));
      SPAWN_LOCATIONS.add(new Location(world,  1024.5d  ,  81d  ,   10.5d  ,   180f  ,  0f  ));
      SPAWN_LOCATIONS.add(new Location(world,  1049.5d  ,  79d  ,  -12.5d  ,    90f  ,  0f  ));
   }
  
   public static void teleportPlayers(List<Player> players) {
      if(players.isEmpty())
         throw new IllegalArgumentException("players must not be empty");
     
      if(players.size() > SPAWN_LOCATIONS.size())
         throw new UnsupportedOperationException("Not enough spawn locations");
     
      // on mélange les positions
      Collections.shuffle(SPAWN_LOCATIONS);
     
      for(int i = 0; i < players.size(); ++i) {
         Player player = players.get(i);
         Location spawnLocation = SPAWN_LOCATIONS.get(i);
        
         teleportPlayer(player, spawnLocation);
      }
   }
  
   private static void teleportPlayer(Player player, Location spawnLocation) {
      if(!player.teleport(spawnLocation))
         // uh, un plugin tier a annulé la téléportation
         throw new RuntimeException("Teleportation of '" + player.getName() + "' denied");
     
      player.getInventory().clear();
      player.setGameMode(GameMode.ADVENTURE);
      // [...]
   }
}


Cordialement,
ShE3py.

Le shuffle mélange définitivement, donc s'il veut récupérer la liste intacte... Et pourquoi pas utiliser une foreach pour players ?

Cordialement,
EdgarPi
 
Solution