Erro:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 420 out of bounds for length 400

Olá bom dia, estou no processo de aprendizagem de desenvolvimento de jogos, e cheguei em um ponto onde está ocorrendo o erro:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 420 out of bounds for length 400
at Game01/com.deCria.world.World.<init>(World.java:19)
at Game01/com.deCria.main.Game.<init>(Game.java:48)
at Game01/com.deCria.main.Game.main(Game.java:83)

Já vi um erro muito parecido que foi solucionado em 2020, porém quando fui checar se era o mesmo, não era. Segue o Código:

package com.deCria.main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

import com.deCria.Graficos.Spritesheet;
import com.deCria.entities.Entity;
import com.deCria.entities.Player;
import com.deCria.world.World;

public class Game extends Canvas implements Runnable, KeyListener{
	
	private static final long serialVersionUID = 1L;
	public static JFrame frame;
	private Thread thread;
	private boolean isRunning = true;
	private final int WIDTH = 240;
	private final int HEIGHT = 160;
	private final int SCALE = 3;
	
	
	private BufferedImage image;
	
	public List<Entity> entities;
	public static Spritesheet spritesheet;
	
	public static World world;
	private Player player;
			
	public Game(){
		addKeyListener(this);
			
		setPreferredSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
		initFrame();	
		//Inicializando objetos.
		image = new  BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB );
		spritesheet = new Spritesheet("/spritesheet.png");
		world = new World("/map.png");
		entities = new ArrayList<Entity>();
		player =new Player(0,0,16,16,spritesheet.getSprite(32, 0, 16, 16));
		entities.add(player);
	}
	
	public void initFrame() {
		frame = new JFrame("Game #1");
		frame.add(this);
		frame.setResizable(false);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	public synchronized void start() {
		thread = new Thread(this);
		isRunning = true;
		thread.start();
		
	}
	
	public synchronized void stop() {
		isRunning = false;
		try {
			thread.join();
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
	
		
	}

	
	public static void main(String args[]) {
		Game game = new Game();
		game.start();
		
	}
	public void tick() {
		for(int i = 0; i < entities.size();i++){
			Entity e = entities.get(i);
			e.tick();
		}
	
		}
		
		
	
	public void render() {
		BufferStrategy bs = this.getBufferStrategy();
		if(bs == null) {
			this.createBufferStrategy(3);
			return;
		}
		Graphics g = image.getGraphics();
		g.setColor(new Color(0,0,0));
		g.fillRect(0,0,WIDTH, HEIGHT);
		
		//Renderização do jogo
		//Graphics2D g2 = (Graphics2D) g;
		world.render(g);
		for(int i = 0; i < entities.size();i++){
			Entity e = entities.get(i);
			e.render(g);
		}

		/***/
		g.dispose();
		g = bs.getDrawGraphics();
		g.drawImage(image, 0, 0, WIDTH*SCALE, HEIGHT*SCALE, null);
		bs.show();
		
	}
	public void run() {
		long lastTime = System.nanoTime();
		double amountOfTicks = 60.0;
		double ns = 1000000000 / amountOfTicks;
		double delta = 0;
		int frames = 0;
		double timer = System.currentTimeMillis();
		while(isRunning) {
			long now = System.nanoTime();
			delta+= (now - lastTime) / ns;
			lastTime = now;
			if (delta >= 1){
				tick();
				render();
				frames++;
				delta--;
				
				
			}
			if(System.currentTimeMillis() - timer >= 1000) {
				System.out.println("FPS: "+ frames);
				frames = 0;
				timer = System.currentTimeMillis();
						
			}
					
			
		}
		
		stop();
	
			
	}

	@Override
	public void keyTyped(KeyEvent e) {
		
			
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()== KeyEvent.VK_RIGHT ||
				e.getKeyCode()== KeyEvent.VK_D) {
			player.right = true;
			
		}else if(e.getKeyCode()== KeyEvent.VK_LEFT ||
				e.getKeyCode()== KeyEvent.VK_A) { 
			player.left = true;

		}
		
		if(e.getKeyCode()== KeyEvent.VK_UP ||
				e.getKeyCode()== KeyEvent.VK_W) {
			player.up = true;

			
		}else if(e.getKeyCode()== KeyEvent.VK_DOWN ||
				e.getKeyCode()== KeyEvent.VK_S) {
			player.down = true;

			
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode()== KeyEvent.VK_RIGHT ||
				e.getKeyCode()== KeyEvent.VK_D) {
			player.right = false;
			
		}else if(e.getKeyCode()== KeyEvent.VK_LEFT ||
				e.getKeyCode()== KeyEvent.VK_A) { 
			player.left = false;

		}
		
		if(e.getKeyCode()== KeyEvent.VK_UP ||
				e.getKeyCode()== KeyEvent.VK_W) {
			player.up = false;

			
		}else if(e.getKeyCode()== KeyEvent.VK_DOWN ||
				e.getKeyCode()== KeyEvent.VK_S) {
			player.down = false;

			
		}
	}
	

}
package com.deCria.entities;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import com.deCria.main.Game;

public class Player extends Entity{
	
	public boolean right = true,up,left,down;
	public int right_dir = 0,left_dir = 1;
	public int dir = right_dir;
	public double speed = 1.4;
	
	private int frames = 0, maxFrames = 5, index = 0, maxIndex = 3;
	private boolean moved = false;
	private BufferedImage[] rightPlayer;
	private BufferedImage[] leftPlayer;

	public Player(int x, int y, int width, int height, BufferedImage sprite) {
		super(x, y, width, height, sprite);
		
		rightPlayer = new BufferedImage[4];
		leftPlayer = new BufferedImage[4];
		for(int i = 0; i<4; i++) {
		rightPlayer[i] = Game.spritesheet.getSprite(32 +(i*16), 0, 16, 16);
		}
		for(int i = 0; i<4; i++) {
			leftPlayer[i] = Game.spritesheet.getSprite(32 +(i*16), 16, 16, 16);
			}
		
		
	}
	
	public void tick() {
		moved = false;
		if(right) {
			moved = true;
			dir = right_dir;
			x+=speed;
		}
		else if(left) {
			moved = true;
			dir = left_dir;
			x-=speed;
		}
		if(up) {
			moved = true;
			y-=speed;
		}
		else if(down) {
			moved = true;
			y+=speed;
		}
		if(moved) {
			frames++;
			if(frames == maxFrames) {
				frames = 0;
				index++;
				if(index > maxIndex)
					index = 0;
			}
		}
		
		
	}
	public void render(Graphics g) {
		if(dir == right_dir) {
			g.drawImage(rightPlayer[index], this.getX(),this.getY(),null);
		}else if(dir == left_dir) {
			g.drawImage(leftPlayer[index], this.getX(),this.getY(),null);

		}
		
	}

}
package com.deCria.entities;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Entity {
	protected double x;
	protected double y;
	protected int width;
	protected int height;
	
	private BufferedImage sprite;
	
	public void setX(int newX) {
		this.x = newX;
	}
	public void setY(int newY) {
		this.y = newY;
	}
	
	
	public Entity(int x,int y, int width, int height, BufferedImage sprite) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.sprite = sprite;
	}
	
	public int getX(){
		return (int)this.x;
		
	}
	public int getY() {
		return (int)this.y;
	
	}
	public int getWidith() {
		return this.width;
		
	}
	public int getHeight() {
		return this.height;
	}
	
	public void tick() {
		
	}
	
	

	
	
	public void render(Graphics g) {
		g.drawImage(sprite, this.getX(), this.getY(), null);
	}

}
package com.deCria.world;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class World {
	private Tile[] tiles;
	public static int WIDTH,HEIGHT;
	public World(String path) {
		try {
			BufferedImage map = ImageIO.read(getClass().getResource(path));
			int[] pixels = new int[map.getWidth() * map.getHeight()];
			WIDTH = map.getWidth();
			HEIGHT = map.getHeight();
			tiles = new Tile[map.getWidth() * map.getHeight()];
			map.getRGB(0, 0,map.getWidth(),map.getHeight(),pixels, 0, map.getWidth());
			for( int xx = 0; xx < map.getWidth();xx++) {
				for(int yy = 0; yy < map.getHeight();yy++) {
					int pixelAtual = pixels[xx + (yy*map.getWidth())];
					
					
					if(pixelAtual == 0xFF000000) {
						//Floor/Chão
						tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);
					}else if(pixelAtual == 0xFFFFFFFF) {
						//Parede
						tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_WALL);

					}else if(pixelAtual == 0xFF0000FF) {
						//Player
						tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);

					}else {
						//Floor/Chão
						tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);

					}
				}
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public void render(Graphics g) {
		for(int xx = 0; xx < WIDTH; xx++) {
			for(int yy = 0; yy < HEIGHT; yy++) {
				Tile tile = tiles[xx +(yy*WIDTH)];
				tile.render(g);
			}
		}
		
	}

}
package com.deCria.world;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import com.deCria.main.Game;

public class Tile {
	
	public static BufferedImage TILE_FLOOR = Game.spritesheet.getSprite(0, 0, 16, 16 );
	public static BufferedImage TILE_WALL = Game.spritesheet.getSprite(16, 0, 16, 16 );
	
	private BufferedImage sprite;
	private int x,y;
	
	public Tile(int x, int y, BufferedImage sprite) {
		this.x = x;
		this.y = y;
		this.sprite = sprite;
		
		
	}
	
	public void render(Graphics g) {
		g.drawImage(sprite, x, y, null);
	}

}
package com.deCria.world;

import java.awt.image.BufferedImage;

public class FloorTile extends Tile {

	public FloorTile(int x, int y, BufferedImage sprite) {
		super(x, y, sprite);
	}
	

}
package com.deCria.world;

import java.awt.image.BufferedImage;

public class WallTile extends Tile {

	public WallTile(int x, int y, BufferedImage sprite) {
		super(x, y, sprite);
	}
	

}

Peço desculpas pela quantidade de packages, é só porque não tenho ideia onde o erro está.
Agradeço a compreenção
Juliano.

Provavelmente essa linha está errada.
Porque está multiplicando a coordenada yy pela largura do mapa?
Vai gerar uma posição que não existe no array.

Mas, aí como eu faria para fazer o jogo rodar normalmete?

Não sei, o que exatamente aquele código deve fazer?
Não tem como perguntar para o professor do curso?

O codigo deverá mostrar o sprite do player e o mapa (sem colisoes)
mas de qualquer maneira irei entrar em contato com o professor.
Se eu obtiver exito atualizo aqui.

Atualização: Problema resolvido!!!

				if(pixelAtual == 0xFF000000) {
					//Floor/Chão
					tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);
				}else if(pixelAtual == 0xFFFFFFFF) {
					//Parede
					tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_WALL);

				}else if(pixelAtual == 0xFF0000FF) {
					//Player
					tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);

				}else {
					//Floor/Chão
					tiles[xx = (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);

O erro é que eu deveria somar ao envez de igualar o xx ao(yy*WIDTH)
Obrigado a todos e muito obrigado.