You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Processing中使用for循环将句子居中显示在画布上

Processing:实现句子按单词拆分并居中显示

问题描述

我还在学习阶段,想要实现输入新句子时,将句子按单词拆分并居中显示在Processing画布上。尝试用for循环,但没法确定循环里怎么设置X、Y坐标来完成单词拆分和居中;手动拆分单词的话,更新新句子时会出错。以下是我当前的代码:

import javax.swing.JOptionPane;
String Answer; // 存储输入答案
String Secret = "Sponge"; // 正确答案
int textposX, textposY; // 文本的X、Y坐标
final int ansBoxHeight = 50; // 答案输入框高度
final int ansBoxWidth = 200; // 答案输入框宽度
int boxPosX, boxPosY; // 答案输入框的X、Y坐标
String riddle = "WHAT IS: FULL OF HOLES BUT STILL HOLDS WATER, WHAT AM I?";

void setup() {
  size(500, 500);
  textposX = width/2;
  textposY = height/2;
  textAlign(CENTER, CENTER); // 先设置文本对齐方式,方便居中
}

void draw() {
  background(255); // 每次绘制清空背景,避免重叠
  answerBox();
  riddle();
  answerComparison();
}

void riddle() {
  fill(0);
  textSize(24); // 调整字号避免超出画布
  // 原错误循环:重复绘制整个句子,没有拆分单词
  for (int textposX = 0; textposX<=450; textposX = textposX+120) {
    for (int textposY = 0; textposY>=450; textposY = textposY+100) {
      text(riddle, textposX, textposY);
    }
  }
  // 手动拆分的代码,更新句子时需要修改多处,扩展性差
  //text("WHAT IS:", textposX-100, textposY-200);
  //text("FULL OF HOLES", textposX-150, textposY-90);
  //text("BUT", textposX-50, textposY-50);
  //text("STILL HOLDS", textposX-130, textposY-10);
  //text("WATER?", textposX-70, textposY+30);
  //text("WHAT AM I;", textposX-110, textposY+120);
}

void answerBox() {
  noFill();
  rect(150, 440, ansBoxWidth, ansBoxHeight); // 简化坐标计算,boxPosX/Y初始为0,可直接写数值
  // 修正鼠标点击范围判断:原逻辑错误,把宽高加反了
  if (mouseX > 150 && mouseX < 150 + ansBoxWidth && mouseY > 440 && mouseY < 440 + ansBoxHeight && mousePressed) {
    noLoop();
    Answer = JOptionPane.showInputDialog("请输入答案:");
    loop(); // 重新开启绘制循环
  }
}

void answerComparison() {
  if (Answer != null && Secret.equalsIgnoreCase(Answer)) { // 避免空指针,忽略大小写匹配
    background(0);
    fill(255);
    text("答对了!", width/2, height/2);
  }
}

解决方案

要实现动态拆分单词并居中,核心是利用字符串拆分和文本宽度计算来自动定位坐标,以下是修改后的关键代码和逻辑:

修改后的完整代码

import javax.swing.JOptionPane;
String Answer;
String Secret = "Sponge";
final int ansBoxHeight = 50;
final int ansBoxWidth = 200;
String riddle = "WHAT IS: FULL OF HOLES BUT STILL HOLDS WATER, WHAT AM I?";
float lineHeight = 30; // 行间距,根据字号调整

void setup() {
  size(500, 500);
  textAlign(CENTER, CENTER);
}

void draw() {
  background(255);
  answerBox();
  drawCenteredSplitText(riddle, width/2, height/2 - 100, 24); // 调用拆分居中绘制函数
  answerComparison();
  // 显示输入的答案
  if (Answer != null) {
    fill(0);
    textSize(20);
    text(Answer, width/2, 465);
  }
}

// 核心函数:拆分句子为单词,居中显示
void drawCenteredSplitText(String text, float centerX, float startY, float fontSize) {
  fill(0);
  textSize(fontSize);
  textAlign(LEFT, CENTER); // 临时设置左对齐,方便逐个绘制单词
  String[] words = split(text, " "); // 按空格拆分单词
  float totalWidth = 0;
  
  // 计算所有单词(含空格)的总宽度
  for (String word : words) {
    totalWidth += textWidth(word + " "); // 每个单词后加空格,计算总宽度
  }
  
  float currentX = centerX - totalWidth/2; // 起始X坐标,实现水平居中
  float currentY = startY;
  
  // 逐个绘制单词
  for (String word : words) {
    text(word, currentX, currentY);
    currentX += textWidth(word + " "); // 更新X坐标到下一个单词位置
    
    // 可选:如果一行放不下,自动换行(这里简单判断,可根据需求优化)
    if (currentX + textWidth(word) > width - 20) {
      currentX = centerX - totalWidth/2;
      currentY += lineHeight;
    }
  }
  textAlign(CENTER, CENTER); // 恢复全局对齐方式
}

void answerBox() {
  noFill();
  rect(150, 440, ansBoxWidth, ansBoxHeight);
  if (mouseX > 150 && mouseX < 150 + ansBoxWidth && mouseY > 440 && mouseY < 440 + ansBoxHeight && mousePressed) {
    noLoop();
    String newRiddle = JOptionPane.showInputDialog("输入新句子:");
    if (newRiddle != null && !newRiddle.isEmpty()) {
      riddle = newRiddle; // 更新句子
    }
    Answer = JOptionPane.showInputDialog("请输入答案:");
    loop();
  }
}

void answerComparison() {
  if (Answer != null && Secret.equalsIgnoreCase(Answer)) {
    background(0);
    fill(255);
    textSize(30);
    text("答对了!", width/2, height/2);
  }
}

关键逻辑说明

  1. 拆分单词:用split(text, " ")将句子拆分为单词数组,支持任意句子动态更新
  2. 水平居中计算:先遍历所有单词计算总宽度,再通过centerX - totalWidth/2得到起始X坐标,确保整体水平居中
  3. 逐词绘制:循环遍历单词数组,逐个绘制并更新X坐标,自动处理单词间距
  4. 可选换行:判断当前X坐标是否超出画布,自动换行并保持垂直居中
  5. 修复原代码问题:修正了输入框鼠标点击范围错误、空指针异常、文本重叠等问题

内容的提问来源于stack exchange,提问作者Jrishi_del14

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:47:52