[JAVA] Afficher le texte caractère par caractère dans Surface View sur Android

Auto-introduction

Bonjour, c'est Hokkaido des étudiants. En gros, j'ai une petite expérience de développement avec Android, et les langages que je pense pouvoir utiliser sont Java et C #. Je vous remercie. Quand j'ai essayé de faire quelque chose comme RPG sur Android, j'étais un peu coincé avec la méthode d'affichage du texte caractère par caractère sur SurfaceView, donc je vais l'écrire pour ne pas l'oublier. Je pense qu'il y a beaucoup d'erreurs, mais pardonnez-moi s'il vous plaît.

Qu'est-ce que Surface View?

――Idéal pour les choses qui nécessitent des performances de dessin telles que des animations et des jeux, des graphiques complexes et des contenus de dessin constamment mis à jour. --Il est possible de dessiner sur un autre thread que le thread principal, mais attention au traitement exclusif entre les threads.

code

Créez une classe dédiée aux graphiques et mettez-y des instructions de dessin.

Graphics.java



    //constructeur
    public Graphics(int w, int h, SurfaceHolder holder) {
        this.holder = holder;
        this.holder.setFormat(PixelFormat.RGBA_8888);
        this.holder.setFixedSize(w, h);
        paint = new Paint();
        paint.setAntiAlias(true);
    }

    public Canvas getCanvas() {
        return canvas;
    }

    //Fermer à clé
    public void lock() {
        canvas = holder.lockCanvas();
        if (canvas == null) return;
        canvas.translate(originX, originY);
    }

    //ouvrir
    public void unlock() {
        if (canvas == null) return;
        holder.unlockCanvasAndPost(canvas);
    }

    //Spécification de l'origine du dessin
    public void setOrigin(int x, int y) {
        originX = x;
        originY = y;
    }

    //Obtenir la coordonnée X de l'origine du dessin
    public int getOriginX() {
        return originX;
    }

    //Obtenir la coordonnée Y de l'origine du dessin
    public int getOriginY() {
        return originY;
    }

    //Spécification de couleur
    public void setColor(int color) {
        paint.setColor(color);
    }

    //Spécifiez la taille de la police
    public void setTextSize(int fontSize) {
        paint.setTextSize(fontSize);
    }

    //Obtenir des métriques de police
    public Paint.FontMetrics getFontMetrics() {
        return paint.getFontMetrics();
    }

    //Obtenir la largeur des caractères
    public int measureText(String string) {
        return (int)paint.measureText(string);
    }

    //Dessiner un rectangle rempli
    public void fillRect(int x, int y, int w, int h) {
        if (canvas == null) return;
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(new Rect(x, y, x+w, y+h), paint);
    }

    //Dessin bitmap
    public void drawBitmap(Bitmap bitmap, int x, int y) {
        if (canvas == null) return;
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Rect src = new Rect(0, 0, w, h);
        Rect dst = new Rect(x, y, x+w, y+h);
        canvas.drawBitmap(bitmap, src, dst, null);
    }

    //Dessin bitmap
    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst) {
        if (canvas == null) return;
        canvas.drawBitmap(bitmap, src, dst, null);
    }

    //Dessiner une chaîne
    public void drawText(String string, int x, int y) {
        if (canvas == null) return;
        canvas.drawText(string, x, y, paint);
    }

Ensuite, créez une classe qui hérite de SurfaceView et définissez-la dans Activity. (Ce sera un peu plus long)

IndexActivity.java



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new RPGView(this, storyNum));
    }

RPGView.java




    
    public RPGView(Activity activity, int story) {
        super(activity);
        holder = getHolder();
        holder.addCallback(this);

        //Génération graphique
        g = new Graphics(dw, H, holder);
        g.setOrigin((dw - W) / 2, 0);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        thread = null;
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (thread != null) {

            //Programmez le processus de dessin de la boucle principale ici

            //dormir
            key = KEY_NONE;
            sleep(200);
        }
    }

Après cela, j'écrirai le processus de dessin dans la boucle principale du fil. (Qu'est-ce que tu fais?)

Textez un caractère à la fois ...

La vue est mise à jour à chaque fois dans le fil SurfaceView, j'ai donc ajouté la chaîne un caractère à la fois et cela a fonctionné.

RPGView.java



     //Dessin de l'écran de dialogue
    private void talk(String message, Bitmap bitmap, String who) {
        int color = Color.rgb(0, 0, 0);
        if (bitmap != null) {
            g.lock();
            g.setColor(color);
            g.fillRect(0, 0, W, H);

            g.getCanvas().translate(0, 0);
            g.fillRect(0, 0, realX, realY);
            g.getCanvas().translate((dspW - W) / 2, 0);

            g.drawBitmap(bitmap, 0, 0);
            g.setColor(Color.rgb(255, 255, 255));
            g.fillRect((W - 504) / 2, H - 122, 504, 104);
            g.setColor(color);
            g.fillRect((W - 500) / 2, H - 120, 500, 100);

            //Rompre la ligne du personnage TODO! !! !! !!
            g.setColor(Color.rgb(255, 255, 255));
            g.setTextSize(25);
            if (message.length() > 18) {
                String message1 = message.substring(0, 18);
                String message2 = message.substring(18);
                g.drawText(message1, (W - 500) / 2 + 25, 370 - (int) g.getFontMetrics().top);
                g.drawText(message2, (W - 500) / 2 + 10, 410 - (int) g.getFontMetrics().top);
            } else {
                g.drawText(message,
                        (W - 500) / 2 + 25, 370 - (int) g.getFontMetrics().top);
            }

            g.unlock();
        }
    }

Si vous appelez cette méthode à partir de la boucle et passez le texte avec un autre caractère ...

RPGView.java



    String text = "AIUEO";
    if (moji_count == text.length() || moji_count == 9999) {
          talk(text, background, null);
          moji_count = 9999;
    } else {
          talk(text.substring(0, moji_count), background, null);
          moji_count++;
    }     

J'ai pu le faire personnage par personnage. Vous pouvez l'afficher à la bonne vitesse en le mettant en veille pendant une courte période.

référence

Recommended Posts

Afficher le texte caractère par caractère dans Surface View sur Android
Afficher les chaînes de caractères caractère par caractère [Note]
Source pour afficher le tableau de caractères avec numberPicker dans Android Studio (Java)
Vue Android
Afficher la vue au-dessus des autres applications sur Android (Résumé des méthodes de support par version d'API)
Afficher le texte en tant qu'art ASCII en Java (jfiglet)
[Localisation japonaise] Rails i18n Affichage de la vue de localisation japonaise simplifiée uniquement
[Rails] Comment afficher les images dans la vue