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

如何在Golang Ebitengine v2中显示大尺寸棋盘棋子文本?

问题描述

我做了一个棋盘,需要在上面显示K、Q、P这类棋子文本,但目前只能显示小字体。请问怎么在屏幕上显示更大的文本?比如字号32。

我试过用basicfont包创建字体,但没法放大。理想情况是用Ebitengine v2在屏幕指定位置显示任意尺寸、颜色文本的简便方法。

附带代码示例:

package main

import (
    "fmt"
    "image/color"
    "log"

    "github.com/hajimehoshi/ebiten/v2"
    "github.com/hajimehoshi/ebiten/v2/ebitenutil"
    "github.com/hajimehoshi/ebiten/v2/text"
    "github.com/hajimehoshi/ebiten/v2/vector"
    "golang.org/x/image/font/basicfont"
)

// Game represents the game state
type Game struct {
}

func (g *Game) Update() error {
    return nil
}

func (g *Game) Draw(screen *ebiten.Image) {

    vector.DrawFilledRect(screen, float32(0), float32(0), float32(100), float32(100), color.Black, true)
    vector.DrawFilledRect(screen, float32(100), float32(0), float32(100), float32(100), color.White, true)

    // print text, default
    ebitenutil.DebugPrintAt(screen, fmt.Sprintf("%v", "K"), 50, 50)

    //with color, but font is still small
    exampleImage := ebiten.NewImage(50, 50)
    exampleImage.Fill(color.RGBA{0x00, 0x00, 0xff, 0xff})

    op := &ebiten.DrawImageOptions{}
    op.GeoM.Translate(float64(125), float64(25))
    screen.DrawImage(exampleImage, op)

    var myFont = &basicfont.Face{
        Advance: 7,
        Width:   32,
        Height:  32,
        Ascent:  11,
        Descent: 2,
        Mask:    basicfont.Face7x13.Mask,
        Ranges: []basicfont.Range{
            {'\u0020', '\u007f', 0},
            {'\ufffd', '\ufffe', 95},
        },
    }

    text.Draw(screen, fmt.Sprint("Q"), myFont, 150, 50, color.RGBA{0xff, 0x00, 0x00, 0xff})

}

func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
    return 640, 640
}

func main() {
    ebiten.SetWindowSize(640, 640)
    if err := ebiten.RunGame(&Game{}); err != nil {
        log.Fatal(err)
    }
}
解决方案

basicfont是点阵字体,本身尺寸固定,修改Face的Width/Height参数只会改变布局空间,不会真正放大字体。要实现任意尺寸的文本显示,推荐使用Ebitengine的text/v2包,它支持矢量字体缩放,具体步骤如下:

1. 替换并新增依赖包

替换原有的text包导入为text/v2,同时添加字体解析相关的依赖:

import (
    // ...原有其他导入
    "github.com/hajimehoshi/ebiten/v2/text/v2"
    "golang.org/x/image/font"
    "golang.org/x/image/font/opentype"
)

2. 加载矢量字体

可以加载系统自带字体,也可以嵌入自定义字体文件。以下示例以加载系统字体为例:

var largeFont font.Face

func init() {
    // 替换为对应系统的字体路径:
    // Windows: "C:/Windows/Fonts/arial.ttf"
    // macOS: "/Library/Fonts/Arial.ttf"
    // Linux: "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
    fontPath := "/Library/Fonts/Arial.ttf"
    fontBytes, err := os.ReadFile(fontPath)
    if err != nil {
        log.Fatalf("加载字体失败: %v", err)
    }

    tt, err := opentype.Parse(fontBytes)
    if err != nil {
        log.Fatalf("解析字体失败: %v", err)
    }

    // 创建32号字体实例
    const fontSize = 32
    largeFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
        Size:    fontSize,
        DPI:     72,
        Hinting: font.HintingFull,
    })
    if err != nil {
        log.Fatalf("创建字体Face失败: %v", err)
    }
}

3. 绘制大尺寸文本

在Draw方法中使用text/v2的Draw函数,支持指定位置、颜色和字体:

func (g *Game) Draw(screen *ebiten.Image) {
    // ...原有棋盘绘制代码

    // 绘制32号黑色K(注意文本基线位置,需加上字体 ascent 偏移)
    kOpts := &text.DrawOptions{}
    kOpts.GeoM.Translate(50, 50+float64(largeFont.Metrics().Ascent.Floor()))
    text.Draw(screen, "K", largeFont, kOpts)

    // 绘制32号红色Q
    qOpts := &text.DrawOptions{}
    qOpts.GeoM.Translate(150, 50+float64(largeFont.Metrics().Ascent.Floor()))
    qOpts.ColorScale.ScaleWithColor(color.RGBA{0xff, 0x00, 0x00, 0xff})
    text.Draw(screen, "Q", largeFont, qOpts)
}

替代方案:缩放点阵文本图像

如果不想使用矢量字体,也可以先将文本绘制到临时图像,再通过缩放实现大字体效果:

func drawScaledText(screen *ebiten.Image, str string, face font.Face, x, y float64, scale float64, col color.Color) {
    bounds, _ := text.BoundString(face, str)
    img := ebiten.NewImage(bounds.Dx(), bounds.Dy())
    img.Fill(color.Transparent)
    text.Draw(img, str, face, -bounds.Min.X, -bounds.Min.Y, col)

    op := &ebiten.DrawImageOptions{}
    op.GeoM.Scale(scale, scale)
    op.GeoM.Translate(x, y-float64(bounds.Max.Y)*scale)
    screen.DrawImage(img, op)
}

// 在Draw方法中调用(放大3倍)
drawScaledText(screen, "K", basicfont.Face7x13, 50, 50, 3, color.Black)

完整修改后的代码

package main

import (
    "image/color"
    "log"
    "os"

    "github.com/hajimehoshi/ebiten/v2"
    "github.com/hajimehoshi/ebiten/v2/text/v2"
    "github.com/hajimehoshi/ebiten/v2/vector"
    "golang.org/x/image/font"
    "golang.org/x/image/font/opentype"
)

var largeFont font.Face

func init() {
    // 替换为你的系统字体路径
    fontPath := "/Library/Fonts/Arial.ttf"
    fontBytes, err := os.ReadFile(fontPath)
    if err != nil {
        log.Fatalf("加载字体失败: %v", err)
    }

    tt, err := opentype.Parse(fontBytes)
    if err != nil {
        log.Fatalf("解析字体失败: %v", err)
    }

    const fontSize = 32
    largeFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
        Size:    fontSize,
        DPI:     72,
        Hinting: font.HintingFull,
    })
    if err != nil {
        log.Fatalf("创建字体Face失败: %v", err)
    }
}

type Game struct{}

func (g *Game) Update() error { return nil }

func (g *Game) Draw(screen *ebiten.Image) {
    // 绘制棋盘格子
    vector.DrawFilledRect(screen, float32(0), float32(0), float32(100), float32(100), color.Black, true)
    vector.DrawFilledRect(screen, float32(100), float32(0), float32(100), float32(100), color.White, true)

    // 绘制32号黑色K
    kOpts := &text.DrawOptions{}
    kOpts.GeoM.Translate(50, 50+float64(largeFont.Metrics().Ascent.Floor()))
    text.Draw(screen, "K", largeFont, kOpts)

    // 绘制32号红色Q
    qOpts := &text.DrawOptions{}
    qOpts.GeoM.Translate(150, 50+float64(largeFont.Metrics().Ascent.Floor()))
    qOpts.ColorScale.ScaleWithColor(color.RGBA{0xff, 0x00, 0x00, 0xff})
    text.Draw(screen, "Q", largeFont, qOpts)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) { return 640, 640 }

func main() {
    ebiten.SetWindowSize(640, 640)
    if err := ebiten.RunGame(&Game{}); err != nil {
        log.Fatal(err)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:57:07