如何在Java中的JPanel之上显示VLCj EmbeddedMediaPlayerComponent?

问题描述 投票:0回答:1

我尝试使用不同的库在我的 Java Swing 游戏中播放视频,我决定使用 VLCj,我有一个名为 CutscenePlayer 的类,它负责播放视频,但我还有一个名为 JPanel 的类 GamePanel和另一个名为CutsceneManager的类调用CutscenePlayer,每当视频播放时我都可以听到声音,但只有黑屏,这是我的CutscenePlayer类:

import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.base.MediaPlayerEventAdapter;

public class CutscenePlayer extends MediaPlayerEventAdapter {
    
    GamePanel gp;
    public static EmbeddedMediaPlayerComponent mediaPlayerComponent;
    public boolean playing;
    public String video;
    
    public CutscenePlayer(GamePanel gp) {
        this.gp = gp;
    }
    
    public void setCutscene(String filePath) {
        video = filePath;
    }
    public void playCutscene() {
        mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
        
        Main.window.add(mediaPlayerComponent);
        
        mediaPlayerComponent.mediaPlayer().events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
                @Override
                public void finished(MediaPlayer mediaPlayer) {
                    System.out.println("Hello");
                    mediaPlayerComponent.release();
                    gp.gameState = gp.cutsceneState;
                    playing = false;
                }
            }
        );
        
        mediaPlayerComponent.mediaPlayer().media().play(video);
    }
    public void play() {
        mediaPlayerComponent.mediaPlayer().controls().pause();
    }
    public void pause() {
        mediaPlayerComponent.mediaPlayer().controls().pause();
    }
} 

这里是调用 CutscenePlayerCutsceneManager 代码:

if (isCutscenePlaying == false) {
    gp.csPlayer.setCutscene("test3.mp4");
    gp.csPlayer.playCutscene();
    isCutscenePlaying = true;
    gp.gameState = gp.cutscenePlayingState;
}
else {
    scenePhase++;
    isCutscenePlaying = false;
}

这是具有线程并绘制所有内容的 GamePanel 代码:

@Override
public void run() {
final double drawInterval = 1000000000 / FPS;
        double delta = 0.0;
        long lastTime = System.nanoTime();
        long currentTime;
        
        while (gameThread != null) {
            currentTime = System.nanoTime();
            
            delta += (currentTime - lastTime) / drawInterval;
            lastTime = currentTime;
            while (delta >= 1.0) {
                if (gameState != cutscenePlayingState) {
                    update();
                    drawToTempScreen();
                    drawToScreen();
                }
                --delta;
            }
        }
    }
    public void update() {
        if (gameState == playState) {
            //PLAYER
            player.update();
            //NPC
            for (int i = 0; i < npc[1].length; i++) {
                if (npc[currentMap][i] != null) {
                    npc[currentMap][i].update();
                }
            }
            for (int i = 0; i < monster[1].length; i++) {
                if (monster[currentMap][i] != null) {
                    if (monster[currentMap][i].alive == true && monster[currentMap][i].dying == false) {
                        monster[currentMap][i].update();
                    }
                    if (monster[currentMap][i].alive == false) {
                        monster[currentMap][i].checkDrop();
                        monster[currentMap][i] = null;
                    }
                }
            }
            for (int i = 0; i < projectile[1].length; i++) {
                if (projectile[currentMap][i] != null) {
                    if (projectile[currentMap][i].alive == true) {
                        projectile[currentMap][i].update();
                    }
                    if (projectile[currentMap][i].alive == false) {
                        projectile[currentMap][i] = null;
                    }
                }
            }
            for (int i = 0; i < particleList.size(); i++) {
                if (particleList.get(i) != null) {
                    if (particleList.get(i).alive == true) {
                        particleList.get(i).update();
                    }
                    if (particleList.get(i).alive == false) {
                        particleList.remove(i);
                    }
                }
            }
            for (int i = 0; i < iTile[1].length; i++) {
                if (iTile[currentMap][i] != null) {
                    iTile[currentMap][i].update();
                }
            }
            eManager.update();
        }
        if (gameState == pauseState) {
            //nothing
        }
    }
    public void drawToTempScreen() {
        //DEBUG
        long drawStart = 0;
        if (keyH.debugOn == true) {
            drawStart = System.nanoTime();
        }
        
        //TITLE SCREEN
        if (gameState == titleState) {
            ui.draw(g2);
        }
//      //MAP SCREEN
//      else if (gameState == mapState){
//          map.drawFullMapScreen(g2);
//      }
        //OTHERS
        else {
            //TILE
            tileM.draw(g2);
            
            //INTERACTIVE TILE
            for (int i = 0; i < iTile[1].length; i++) {
                if (iTile[currentMap][i] != null) {
                    iTile[currentMap][i].draw(g2);
                }
            }
            
            //ADD ENTITIES TO THE LIST
            entityList.add(player);
            
            for (int i = 0; i < npc[1].length; i++) {
                if (npc[currentMap][i] != null ) {
                    entityList.add(npc[currentMap][i]);
                }
            }
            
            for (int i = 0; i < obj[1].length; i++ ) {
                if (obj[currentMap][i] != null) {
                    entityList.add(obj[currentMap][i]);
                }
            }
            
            for (int i = 0; i < monster[1].length; i++ ) {
                if (monster[currentMap][i] != null) {
                    entityList.add(monster[currentMap][i]);
                }
            }
            
            for (int i = 0; i < projectile[1].length; i++ ) {
                if (projectile[currentMap][i] != null) {
                    entityList.add(projectile[currentMap][i]);
                }
            }
            for (int i = 0; i < particleList.size(); i++ ) {
                if (particleList.get(i) != null) {
                    entityList.add(particleList.get(i));
                }
            }
            //SORT
            Collections.sort(entityList, new Comparator<Entity>() {
                
                @Override
                public int compare(Entity e1, Entity e2) {
                    int result = Integer.compare(e1.worldY, e2.worldY);
                    return result;
                }
            });
            
            //DRAW ENTITIES
            for (int i = 0; i < entityList.size(); i++) {
                entityList.get(i).draw(g2);;
            }
            //EMPTY ENTITY LIST
            entityList.clear();
            
            //ENVIORNMENT
            eManager.draw(g2);
            
//          //MINIMAP
//          map.drawMinimap(g2);
            
            //CUTSCENE MANAGER
            csManager.draw(g2);
            
            //UI
            ui.draw(g2);
            
            //TIME AMULET SCREEN
            if (gameState == timeAmuletState){
                g2.setColor(new Color(0, 0, 0, 150));
                g2.fillRect(0, 0, screenWidth, screenHeight);
                dClock.drawClock(g2);
            }
            
        }
        
        //DEBUG
        if (keyH.debugOn == true) {
            long drawEnd = System.nanoTime();
            long passed = drawEnd - drawStart;
            System.out.println("Draw Time: " + passed);
            
            g2.setFont(getFont().deriveFont(20F));
            g2.setColor(Color.WHITE);
            int x = 10;
            int y = 400;
            int lineHeight = 20;
            
            g2.drawString("Draw Time: " + passed, x, y); y += lineHeight;
            g2.drawString("Col: " + (player.worldX + player.solidArea.x)/tileSize, x, y); y += lineHeight;
            g2.drawString("Row: " + (player.worldY + player.solidArea.y)/tileSize, x, y); y += lineHeight;
            g2.drawString("God Mode: "+ keyH.godModeOn, x, y); //y += lineHeight;
        }
    }
    public void drawToScreen() {
        if (gameState != cutscenePlayingState) {
            Graphics g = getGraphics();
            g.drawImage(tempScreen, 0, 0, screenWidth2, screenHeight2, null);
            g.dispose();
        }
    }

最后是Main类:

public static void main(String[] args) {
        window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setResizable(false);
        window.setTitle("Time Maze");
        new Main().setIcon();
        
        window.add(gamePanel);

        gamePanel.config.loadConfig();
        if (gamePanel.fullScreenOn) {
            window.setUndecorated(true);
        }

        window.pack();

        window.setLocationRelativeTo(null);
        window.setVisible(true);
        
        gamePanel.setUpGame();
        gamePanel.startGameThread();
}

我想让它播放视频,然后恢复到 GamePanel 以便游戏可以继续,但我却得到黑屏(GamePanel 背景的颜色),并且游戏甚至无法恢复。问题是 GamePanel 显示在 mediaPlayerComponent 上。我在 mediaPlayerComponent 上尝试了 setContentPane,但视频播放完毕后,屏幕将卡在视频的最后一帧。

java swing jframe jpanel vlcj
1个回答
0
投票

我用这个替换了 playCutscene() 方法:

public void playCutscene() {
    mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
    Main.window.add(mediaPlayerComponent);
    Main.gamePanel.setVisible(false);
    playing = true;
    
    mediaPlayerComponent.mediaPlayer().events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
            @Override
            public void finished(MediaPlayer mediaPlayer) {
                System.out.println("Hello");
                Main.window.remove(mediaPlayerComponent);
                Main.gamePanel.setVisible(true);
                //Main.gamePanel.setFocusable(true);
                gp.gameState = gp.cutsceneState;
                playing = false;
                mediaPlayerComponent.release();
            }
        }
    );
    
    mediaPlayerComponent.mediaPlayer().media().play(video);
}

它的工作原理是将 mediaPlayerComponent 添加到窗口,然后将 GamePanel 设置为不可见。在视频结束时,它将恢复正常并释放资源。

© www.soinside.com 2019 - 2024. All rights reserved.