pré-carregando imagens em Java

Estou programando um jogo básico do TowerDefense. Está tudo ótimo, mas estou tentando fazer o pré-carregamento de imagens. Minha situação é que, quando eu chamo o método de pintura da minha classe Canvas (estende o JPanel), ele abre um thread chamado "Image Fetcher x", em que 'x' é um número começando com 0 e subindo para várias instâncias do thread . Pelo que entendi, esse segmento está pegando as imagens das minhas variáveis de imagem, localizando-as no disco, carregando-as na RAM para o meu jogo exibir e depois desenhando-a
Isso funciona bem, no entanto, no meio do jogo, há momentos em que nada aparece porque o método de desenho que eu chamo está tentando desenhar uma imagem que não foi carregada. A jogabilidade ainda é eficaz, mas a representação visual está confusa porque o jogador basicamente vê um bloco de grama atirando em um inimigo. De repente, a imagem carrega e é desenhada e parece normal.

Isso é bom e tudo, mas quero poder pré-carregar todos os recursos (e possivelmente criar uma tela de carregamento para que o player sabe que o jogo está carregando) para que as imagens não carregadas não destruam a ilusão da jogabilidade - se isso faz sentido. Eu tentei usar um MediaTracker, que não funcionou. Eu pesquisei isso e parece que não consigo encontrar nada em nenhum luga

Meu código atual consiste em matrizes de imagens de um mapa de imagens. Cada imagem em uma matriz é desenhada na tela de acordo com certos identificadores que informam ao jogo qual bloco / torre desenhar. Estou usando a classe java.awt.Image para armazenar minhas imagens. Então, existe alguma maneira de pré-carregar minhas imagens para que elas não precisem carregar no meio do jogo?
Obrigado

Editar
Código

for(int y=0; y<tileMap.length; y++) {
    for(int x=0; x<tileMap[y].length; x++) {
        tileMap[y][x] = new ImageIcon("res/tileMap.png").getImage();
        tileMap[y][x] = createImage(new FilteredImageSource(tileMap[y][x].getSource(), new CropImageFilter(x * Room.blockSize, y * Room.blockSize, Room.blockSize, Room.blockSize))); 
    }
}

public void paintcomponent(Graphics g) {
    g.drawImage(tileMap[1][2], 5, 7, null);
}

Essa é uma versão simplificada, tenho cerca de 1500 linhas, então não acho que você queira ver tudo isso, lol. Basicamente, eu apenas crio as variáveis da imagem e as desenho. No momento de desenhá-los, uma linha do Image Fetcher é iniciada, carrega a imagem e desaparece após o término do carregamento da imagem. Enquanto a imagem está sendo carregada (e o segmento Image Fetcher está ativo), o método drawImage não desenha nada, pois a imagem não é pré-carregada na RAM. No entanto, depois de concluir o carregamento da imagem, o método drawImage realmente desenha a imagem correta e o segmento do Image Fetcher não está mais ativo. Existe uma maneira de iniciar o processo de busca de imagens para que tudo isso aconteçaante iniciando o programa?
Eu também tentei desenhar tudo no começo, que não funcionou, já que o programa é executado muito rápido para o Image Fetchers carregar com êxito todas as imagens antes da reprodução do usuário. idk, os Image Fetchers são complicados. Eu só preciso saber como pré-carregar imagens na RAM.

questionAnswers(0)

yourAnswerToTheQuestion