Visual Novel的可绘制和可点击文本

时间:2016-10-19 16:14:25

标签: java eclipse applet

这不重复。我尝试的所有其他解决方案都已过时。

首先看看这张图片

enter image description here

今天我用Java在Eclipse中做到了这一点。 它看起来像一部视觉小说。

关键是我想在屏幕上绘制一些文字但不知道如何操作。 起初我只想知道:

  1. 如何在屏幕上绘制文字并进行更改
  2. 制作某些内容,例如图片或某些文字,可点击以移至 下一个场景
  3. 这是我目前的代码:

    package textboxes;
    
    import java.applet.Applet;
    import java.awt.Color;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.net.URL;
    
    
    public class test extends Applet implements Runnable, KeyListener {
    
    private Image Image, Background;
    private Image actor1, actor2;
    private Image textbox;
    private Graphics graphics;
    private URL base;
    private static testbg bg;
    
    @Override
    public void init(){
        setSize(960, 540);
        setBackground(Color.LIGHT_GRAY);
        setFocusable(true);
        Frame frame = (Frame)this.getParent().getParent();
        frame.setTitle("School Scene");
        try{
            base = getDocumentBase();
        }catch(Exception e){};
    
        //getImages from disk
        Background = getImage(base, "res/background.jpg"); 
        actor1 = getImage(base, "res/actor1.jpg");
        actor2 = getImage(base, "res/actor2.jpg");
        textbox = getImage(base, "res/textbox.jpg");
    }
    
    public test(){
    
    }
    
    @Override
    public void start(){
        bg = new testbg();
    Thread thread = new Thread(this);
    thread.start();
    }
    @Override
    public void keyPressed(KeyEvent arg0) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void run() {
        bg.update();
        repaint();
        try{
            Thread.sleep(17);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    
    }
    
    @Override
    public void update(Graphics g){
        if(Image == null){
            Image = createImage(this.getWidth(), this.getHeight());
            graphics = Image.getGraphics();
        }
    
        graphics.setColor(getBackground());
        graphics.fillRect(0, 0, getWidth(), getHeight());
        graphics.setColor(getForeground());
        paint(graphics);
    
        g.drawImage(Image, 0, 0, this);
    }
    
    @Override
    public void paint(Graphics g){
        super.paint(g);
    
    g.drawImage(Background, bg.getBgX(), bg.getBgY(), this);
    g.drawImage(actor2, 40, 20, this);
    g.drawImage(textbox, 80, 350, this);
    }
    
    public static testbg getBg() {
        return bg;
    }
    
    }
    

    以上这段代码就是我所说的test.java

    如果您想知道背景部分

    以下代码就是我所说的testbg.java

    package textboxes;
    
    public class testbg {
    
    private int bgX, bgY;
    
    public testbg(){
        bgX = 0;
        bgY = 0;
    }
    
    public void update(){
    
    }
    
    public int getBgX(){
        return bgX;
    }
    
    public int getBgY(){
        return bgY;
    }
    
    public void setBgX(int bgX) {
        this.bgX = bgX;
    }
    
    public void setBgY(int bgY) {
        this.bgY = bgY;
    }
    
    }
    
      

    感谢您阅读这么多直到最后......现在我也知道怎么做了吗?

1 个答案:

答案 0 :(得分:0)

至于文本,我有两个解决方案,但是对于你想要的(以及我所知道的CG游戏),我猜第一个是最好的。

这个第一个解决方案是我很久以前在StackOverflow中遇到的一个问题(我不记得在哪里,对不起),其中包括将几个类一起使用直接在面板。

private final String message;
private final java.awt.geom.Rectangle2D.Float aboutMessageBounds;
private final AttributedString aboutMessageAttributedString;
private final AttributedCharacterIterator paragraph;


// The LineBreakMeasurer used to line-break the paragraph.
private java.awt.font.LineBreakMeasurer lineMeasurer;
// index of the first character in the paragraph.
private final int paragraphStart;
// index of the first character after the end of the paragraph.
private final int paragraphEnd;

@Override
public void init(){

    (...)

    java.util.Hashtable<TextAttribute, Object> textAtributMap = 
                new java.util.Hashtable<TextAttribute, Object>();

    textAtributMap.put(TextAttribute.FAMILY, "Serif");
    textAtributMap.put(TextAttribute.SIZE, new Float(26.0));
    textAtributMap.put(TextAttribute.JUSTIFICATION, TextAttribute.JUSTIFICATION_FULL );
    textAtributMap.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_DEMIBOLD );
    textAtributMap.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON );

    message = "This is a sample of a message.";

    aboutMessageAttributedString = new AttributedString( aboutMessage, textAtributMap );
    paragraph = aboutMessageAttributedString.getIterator();
    paragraphStart = paragraph.getBeginIndex();
    paragraphEnd = paragraph.getEndIndex();

    (...)

}

@Override
protected void paintComponent( Graphics g ) {
    super.paintComponent( g ); //To change body of generated methods, choose Tools | Templates.

    Graphics2D g2 = (Graphics2D)g.create();
        try {

            g2.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );

            // Create a new LineBreakMeasurer from the paragraph.
            // It will be cached and re-used.
            if (lineMeasurer == null) {
                FontRenderContext frc = g2.getFontRenderContext();
                lineMeasurer = new java.awt.font.LineBreakMeasurer(paragraph, frc);
            }

            //You can scale it like I did. this part is not part of the code that I found.
            g2.scale( ratio.scaleDx, ratio.scaleDy );

            // Set break width to width of Component.
            //these were the measures I used for a something in a game;
            float breakWidth = 734.0f;
            float drawPosY = 90.0f;
            float posX0 = 30.0f;
            // Set position to the index of the first character in the paragraph.
            lineMeasurer.setPosition(paragraphStart);

            // Get lines until the entire paragraph has been displayed.
            while (lineMeasurer.getPosition() < paragraphEnd) {
                int next = lineMeasurer.nextOffset(breakWidth);

                int limit = next;
                if (limit <= message.length()) {
                    for (int i = lineMeasurer.getPosition(); i < next; ++i) {
                        char c = aboutMessage.charAt(i);
                        if (c == '\n') {
                            limit = i + 1;
                            break;
                        }
                    }
                }

                java.awt.font.TextLayout layout = lineMeasurer.nextLayout( breakWidth, limit, false );
                // Retrieve next layout. A cleverer program would also cache
                // these layouts until the component is re-sized.


                // Compute pen x position. If the paragraph is right-to-left we
                // will align the TextLayouts to the right edge of the panel.
                // Note: this won't occur for the English text in this sample.
                // Note: drawPosX is always where the LEFT of the text is placed.
                float drawPosX = layout.isLeftToRight()
                        ? posX0 : breakWidth - layout.getAdvance();
                // Move y-coordinate by the ascent of the layout.
                drawPosY += layout.getAscent();

                // Draw the TextLayout at (drawPosX, drawPosY).
                layout.draw(g2, drawPosX, drawPosY);

                // Move y-coordinate in preparation for next layout.
                drawPosY += layout.getDescent() + layout.getLeading();
            }

        } 
        finally {
            g2.dispose();
        }
}

对于第二种解决方案,您可以使用JEditorPane或JTextPane。请参阅本教程的Oracle教程:

https://docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html

我跳了,我帮了。

祝你有个愉快的一天。 :)