vector: add FillCircle and StrokeCircle

Updates #2387
This commit is contained in:
Hajime Hoshi 2022-10-21 23:06:52 +09:00
parent fa942c824f
commit 5e15bafde8
4 changed files with 46 additions and 41 deletions

View File

@ -17,7 +17,6 @@ package ebitenutil
import (
"image"
"image/color"
"math"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/vector"
@ -53,20 +52,8 @@ func DrawRect(dst *ebiten.Image, x, y, width, height float64, clr color.Color) {
// DrawCircle draws a circle on given destination dst.
//
// DrawCircle is intended to be used mainly for debugging or prototyping purpose.
//
// Deprecated: as of v2.5. Use vector.FillCircle instead.
func DrawCircle(dst *ebiten.Image, cx, cy, r float64, clr color.Color) {
var path vector.Path
rd, g, b, a := clr.RGBA()
path.Arc(float32(cx), float32(cy), float32(r), 0, 2*math.Pi, vector.Clockwise)
vertices, indices := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vertices {
vertices[i].SrcX = 1
vertices[i].SrcY = 1
vertices[i].ColorR = float32(rd) / 0xffff
vertices[i].ColorG = float32(g) / 0xffff
vertices[i].ColorB = float32(b) / 0xffff
vertices[i].ColorA = float32(a) / 0xffff
}
dst.DrawTriangles(vertices, indices, whiteSubImage, nil)
vector.FillCircle(dst, float32(cx), float32(cy), float32(r), clr)
}

View File

@ -343,9 +343,9 @@ func (p *Player) draw(screen *ebiten.Image) {
// Draw the cursor on the bar.
c := p.current
cx := float64(x) + float64(w)*float64(p.current)/float64(p.total)
cy := float64(y) + float64(h)/2
ebitenutil.DrawCircle(screen, cx, cy, 12, playerCurrentColor)
cx := float32(x) + float32(w)*float32(p.current)/float32(p.total)
cy := float32(y) + float32(h)/2
vector.FillCircle(screen, cx, cy, 12, playerCurrentColor)
// Compose the curren time text.
m := (c / time.Minute) % 100

View File

@ -46,10 +46,13 @@ func (g *Game) Draw(screen *ebiten.Image) {
cf := float32(g.count)
vector.StrokeLine(screen, 100, 100, 300, 100, 1, color.RGBA{0xff, 0xff, 0xff, 0xff})
vector.StrokeLine(screen, 50, 150, 50, 350, 1, color.RGBA{0xff, 0xff, 0x00, 0xff})
vector.StrokeLine(screen, 50, 100+float32(cf), 200+float32(cf), 250, 4, color.RGBA{0x00, 0xff, 0xff, 0xff})
vector.StrokeLine(screen, 50, 100+cf, 200+cf, 250, 4, color.RGBA{0x00, 0xff, 0xff, 0xff})
vector.FillRect(screen, 50+float32(cf), 50+float32(cf), 100+float32(cf), 100+float32(cf), color.RGBA{0x80, 0x80, 0x80, 0xff})
vector.StrokeRect(screen, 300-float32(cf), 50, 120, 120, 10, color.RGBA{0x00, 0x80, 0x00, 0xff})
vector.FillRect(screen, 50+cf, 50+cf, 100+cf, 100+cf, color.RGBA{0x80, 0x80, 0x80, 0xc0})
vector.StrokeRect(screen, 300-cf, 50, 120, 120, 10+cf/4, color.RGBA{0x00, 0x80, 0x00, 0xff})
vector.FillCircle(screen, 400, 400, 100, color.RGBA{0x80, 0x00, 0x80, 0x80})
vector.StrokeCircle(screen, 400, 400, 10+cf, 10+cf/2, color.RGBA{0xff, 0x80, 0xff, 0xff})
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f", ebiten.ActualTPS()))
}

View File

@ -17,6 +17,7 @@ package vector
import (
"image"
"image/color"
"math"
"github.com/hajimehoshi/ebiten/v2"
)
@ -30,7 +31,7 @@ func init() {
whiteImage.Fill(color.White)
}
func updateVerticesForUtil(vs []ebiten.Vertex, clr color.Color) {
func drawVerticesForUtil(dst *ebiten.Image, vs []ebiten.Vertex, is []uint16, clr color.Color) {
r, g, b, a := clr.RGBA()
for i := range vs {
vs[i].SrcX = 1
@ -40,6 +41,11 @@ func updateVerticesForUtil(vs []ebiten.Vertex, clr color.Color) {
vs[i].ColorB = float32(b) / 0xffff
vs[i].ColorA = float32(a) / 0xffff
}
op := &ebiten.DrawTrianglesOptions{}
op.ColorScaleFormat = ebiten.ColorScaleFormatPremultipliedAlpha
op.AntiAlias = true
dst.DrawTriangles(vs, is, whiteSubImage, op)
}
// StrokeLine strokes a line (x0, y0)-(x1, y1) with the specified width and color.
@ -51,12 +57,7 @@ func StrokeLine(dst *ebiten.Image, x0, y0, x1, y1 float32, strokeWidth float32,
strokeOp.Width = strokeWidth
vs, is := path.AppendVerticesAndIndicesForStroke(nil, nil, strokeOp)
updateVerticesForUtil(vs, clr)
op := &ebiten.DrawTrianglesOptions{}
op.ColorScaleFormat = ebiten.ColorScaleFormatPremultipliedAlpha
op.AntiAlias = true
dst.DrawTriangles(vs, is, whiteSubImage, op)
drawVerticesForUtil(dst, vs, is, clr)
}
// FillRect fills a rectangle with the specified width and color.
@ -68,12 +69,7 @@ func FillRect(dst *ebiten.Image, x, y, width, height float32, clr color.Color) {
path.LineTo(x+width, y)
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
updateVerticesForUtil(vs, clr)
op := &ebiten.DrawTrianglesOptions{}
op.ColorScaleFormat = ebiten.ColorScaleFormatPremultipliedAlpha
op.AntiAlias = true
dst.DrawTriangles(vs, is, whiteSubImage, op)
drawVerticesForUtil(dst, vs, is, clr)
}
// StrokeRect strokes a rectangle with the specified width and color.
@ -92,10 +88,29 @@ func StrokeRect(dst *ebiten.Image, x, y, width, height float32, strokeWidth floa
strokeOp.MiterLimit = 10
vs, is := path.AppendVerticesAndIndicesForStroke(nil, nil, strokeOp)
updateVerticesForUtil(vs, clr)
op := &ebiten.DrawTrianglesOptions{}
op.ColorScaleFormat = ebiten.ColorScaleFormatPremultipliedAlpha
op.AntiAlias = true
dst.DrawTriangles(vs, is, whiteSubImage, op)
drawVerticesForUtil(dst, vs, is, clr)
}
// FillCircle filles a circle with the specified center position (cx, cy), the radius (r), width and color.
func FillCircle(dst *ebiten.Image, cx, cy, r float32, clr color.Color) {
var path Path
path.Arc(float32(cx), float32(cy), float32(r), 0, 2*math.Pi, Clockwise)
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
drawVerticesForUtil(dst, vs, is, clr)
}
// StrokeCircle strokes a circle with the specified center position (cx, cy), the radius (r), width and color.
//
// clr has be to be a solid (non-transparent) color.
func StrokeCircle(dst *ebiten.Image, cx, cy, r float32, strokeWidth float32, clr color.Color) {
var path Path
path.Arc(float32(cx), float32(cy), float32(r), 0, 2*math.Pi, Clockwise)
path.Close()
strokeOp := &StrokeOptions{}
strokeOp.Width = strokeWidth
vs, is := path.AppendVerticesAndIndicesForStroke(nil, nil, strokeOp)
drawVerticesForUtil(dst, vs, is, clr)
}