package hud import ( "image" "math" "github.com/chompy/roguelike_rpg/internal/client/gfx" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/text/v2" ) func RenderDialogBox(gfx *gfx.Context, width, height int) (*ebiten.Image, error) { frames, err := gfx.SpriteLibrary.Get("hud.dialog.corner", "hud.dialog.edge", "hud.dialog.inner") if err != nil { return nil, err } frameCorner := frames[0].GetAnimationFrame(0) frameEdge := frames[1].GetAnimationFrame(0) frameInner := frames[2].GetAnimationFrame(0) frameSize := frameCorner.Bounds().Size() tileWidth := int(math.Floor(float64(width)/float64(frameSize.X))) + frameSize.X tileHeight := int(math.Floor(float64(height)/float64(frameSize.Y))) + frameSize.Y dialogRender := ebiten.NewImage(tileWidth*frameSize.X, tileHeight*frameSize.Y) for x := range tileWidth { for y := range tileHeight { op := &ebiten.DrawImageOptions{} var frame *ebiten.Image if x == 0 && y == 0 { // top left frame = frameCorner } else if x == 0 && y == tileHeight-1 { // bottom left frame = frameCorner op.GeoM.Scale(1, -1) op.GeoM.Translate(0, float64(frameSize.Y)) } else if x == tileWidth-1 && y == 0 { // top right frame = frameCorner op.GeoM.Scale(-1, 1) op.GeoM.Translate(float64(frameSize.X), 0) } else if x == tileWidth-1 && y == tileHeight-1 { // bottom right frame = frameCorner op.GeoM.Scale(-1, -1) op.GeoM.Translate(float64(frameSize.X), float64(frameSize.Y)) } else if x == 0 { // left edge frame = frameEdge op.GeoM.Rotate(-math.Pi * .5) op.GeoM.Translate(0, float64(frameSize.Y)) } else if x == tileWidth-1 { // right edge frame = frameEdge op.GeoM.Rotate(math.Pi * .5) op.GeoM.Translate(float64(frameSize.X), 0) } else if y == 0 { // top edge frame = frameEdge } else if y == tileHeight-1 { // bottom edge frame = frameEdge op.GeoM.Scale(1, -1) op.GeoM.Translate(0, float64(frameSize.Y)) } else { frame = frameInner } op.GeoM.Translate(float64(x*frameSize.X), float64(y*frameSize.Y)) dialogRender.DrawImage(frame, op) } } return dialogRender, nil } func RenderButton(gfx *gfx.Context, buttonText string) (*ebiten.Image, error) { font, err := gfx.FontLibrary.GetOne("button") if err != nil { return nil, err } width, height := font.Measure(buttonText) dialogImage, err := RenderDialogBox(gfx, int(width), int(height)) if err != nil { return nil, err } dSize := dialogImage.Bounds().Size() op := &text.DrawOptions{} op.GeoM.Translate(float64(dSize.X)/2-width/2, float64(dSize.Y)/2-height/2) font.DrawText(dialogImage, buttonText, 0, op) return dialogImage, nil } func RenderLabelWithIcon(gfx *gfx.Context, label string, icon *ebiten.Image) (*ebiten.Image, error) { font, err := gfx.FontLibrary.GetOne("button") if err != nil { return nil, err } lw, lh := font.Measure(label) var iconSize image.Point if icon != nil { iconSize = icon.Bounds().Size() iconSize.X += 4 } w, h := int(lw)+iconSize.X, max(int(lh), iconSize.Y) image := ebiten.NewImage(w, h) if icon != nil { op := &ebiten.DrawImageOptions{} image.DrawImage(icon, op) } op := &text.DrawOptions{} if icon != nil { op.GeoM.Translate(float64(iconSize.X), float64(iconSize.Y)/2-lh/2) } font.DrawText(image, label, 0, op) return image, nil }