迁安网站建设公司,广西seo排名,wordpress 菜单没了,中国建设银行网站设计评价概述
到这一节为止#xff0c;我们已经学习了如何在CanvasItem中绘制简单几何图形、图片以及样式盒。但是对于很重要的文字一直没有涉及。 本节就来讲一下字符和字符串绘制函数#xff0c;以及替换它们的两个类。
系列目录
0.概述1.绘制简单图形2.设定绘图变换3.绘制纹理4…概述
到这一节为止我们已经学习了如何在CanvasItem中绘制简单几何图形、图片以及样式盒。但是对于很重要的文字一直没有涉及。 本节就来讲一下字符和字符串绘制函数以及替换它们的两个类。
系列目录
0.概述1.绘制简单图形2.设定绘图变换3.绘制纹理4.绘制样式盒5.绘制字符和字符串6.TextLine和TextParagraph详解7.自定义节点TextBoard8.绘制点索引9.绘制表格
CanvasItem内置字符和字符串绘制函数
CanvasItem内置了以下几个函数用来绘制字符和字符串
draw_char()用来绘制单个字符draw_string()用来绘制字符串draw_string_outline()用来绘制字符串的文本描边draw_multiline_string()用来绘制多行文本
同时因为绘制文本与具体的字体挂钩所以也可以用Font类的一些方法来作为辅助。
绘制字符
draw_char()参数如下
参数类型默认值说明fontFont字体posVector2绘制位置charString要绘制的字符font_sizeint16字号modulateColorColor(1, 1, 1, 1)调制颜色
测试代码
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))var font ThemeDB.fallback_fontdraw_char(font,Vector2(),9)在上面的代码中
在绘制字符之前我们将绘图原点设为了(200,200)并绘制了从坐标原点到绘图原点(200,200)的矩形用ThemeDB.fallback_font获取了Godot主题的默认字体最后通过draw_char在(200,200)处以默认的16号字体大小和默认的白色绘制了字符9。
绘制效果 可以看到draw_char()绘制的字符是以左下角为绘制位置向上向左绘制的。 注意如果给draw_char()传入的字符串长度不为1会报错也就是说绘制空字符串或者长度大于1的字符串都会报“长度不为1”的错
绘制字符串
将draw_char()换为draw_string()就可以绘制字符串了
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))var font ThemeDB.fallback_fontdraw_string(font,Vector2(),绘制文本测试)绘制效果 可以看到依然是从左下角位置开始。
设定文本裁切
draw_string(font,Vector2(),绘制文本测试,HORIZONTAL_ALIGNMENT_CENTER,50)上面的代码设定draw_string()的width参数为50这意味着超过50像素的宽度后字符串会被裁剪。
绘制文本描边
通过draw_string_outline()可以绘制文本的描边。
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))var font ThemeDB.fallback_fontdraw_string(font,Vector2(),绘制文本测试)draw_string_outline(font,Vector2(),绘制文本测试,0,-1,16,1,Color.BLACK)计算和绘制字符串矩形
如果我们想更好的控制绘制的字符串必须要获取字符绘制的矩形区域信息。
Font的get_string_size()可以返回相应字体和设置下一段字符串所占据的矩形区域尺寸。返回的尺寸宽度是比较精确的但是高度有很大的偏差因为它返回的是字体中所有字形的平均高度。
以下面代码为例
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))# 设定文本和字体var font ThemeDB.fallback_fontvar text 中文123abcghxvar font_size 56var alignment HORIZONTAL_ALIGNMENT_CENTERvar size font.get_string_size(text,alignment,-1,font_size)# 获取字符串的矩形区域var string_rect Rect2(Vector2(0,-size.y),size)# 绘制字符串的矩形区域draw_rect(string_rect,Color.BROWN)# 绘制文本draw_string(font,Vector2(),text,alignment,-1,font_size)绘制的效果 可以看到获取的字符串区域有一定的偏差。尤其是高度部分。所以我们需要其他的思路来降低这种误差。 这里补充一点额外的东西
英文字体设计中有基线的概念因为英文小写字母有的顶部会延伸出去一部分而有的会在底部延伸出一部分。为了美观就以一个基准线来排列也就是基线。在Godot的Font类中以基线将英文小写字母的高度分为了两部分分别可以用get_ascent和get_descent获取这两部分的值。 经过实际测试
Font的get_string_size()或get_height()返回的高度减去get_descent()是最接近真实的高度。而Font的get_string_size()或get_height()返回的高度减去2倍的get_descent()就是最接近中文和阿拉伯数字真实的高度。
据此我编写了以下两个函数
# 获取字符串的尺寸
func get_string_size(font:Font,string:String,alignment:HorizontalAlignmentHORIZONTAL_ALIGNMENT_LEFT,width:-1,font_size:16):var w font.get_string_size(string,alignment,width,font_size).xvar h font.get_height(font_size) - font.get_descent(font_size)return Vector2(w,h)# 获取字符串的矩形
func get_string_rect(font:Font,string:String,alignment:HorizontalAlignmentHORIZONTAL_ALIGNMENT_LEFT,width:-1,font_size:16):var size get_string_size(font,string,alignment,width,font_size)var pos Vector2(0,-(size.y - font.get_descent(font_size)))return Rect2(pos,size)get_string_size()获取更接近真实的字符串尺寸get_string_rect()获取更接近真实的字符串矩形区域
改进后的代码
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))# 设定文本和字体var font ThemeDB.fallback_fontvar text 中文123abcghxvar font_size 56var alignment HORIZONTAL_ALIGNMENT_CENTER# 获取字符串的矩形区域var string_rect get_string_rect(font,text,alignment,-1,font_size)# 绘制字符串的矩形区域draw_rect(string_rect,Color.BROWN)# 绘制文本draw_string(font,Vector2(),text,alignment,-1,font_size)绘制效果
绘制换行文本
使用CanvasItem的draw_multiline_string()方法可以绘制换行文本。
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))# 设定文本和字体var font ThemeDB.fallback_fontvar text 中文123abcghxvar font_size 56var alignment HORIZONTAL_ALIGNMENT_CENTERvar width 160var size font.get_multiline_string_size(text,alignment,width,font_size)var d font.get_descent(font_size)# 获取字符串的矩形区域var string_rect Rect2(Vector2(0,-size.y/2),size)# 绘制字符串的矩形区域draw_rect(string_rect,Color.BROWN)# 绘制多行文本draw_multiline_string(font,Vector2(),text,0,width,font_size)同样可以看到获得的实际矩形不是很精确
使用TextLine和TextParagraph
Godot封装了更好用的单行文本和段落文本类不仅更易于理解和使用而且获得的文本矩形也更精确可以获得更好的控制。 所以我个人建议是在绘制文本时直接构造TextLine和TextParagraph实例而完全弃用CanvasItem内置字符和字符串绘制函数。
使用TextLine构造和绘制单行文本
extends Node2D# 设定文本和字体
var font ThemeDB.fallback_font
var font_size 56
var pos Vector2(200,200)func _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),pos),Color.AQUA)# 修改绘图坐标原点draw_set_transform(pos)# 创建单行文本var text TextLine.new()text.add_string(单行文本测试,font,font_size) # 修改绘图坐标原点# 绘制单行文本的矩形区域draw_rect(Rect2(Vector2(),text.get_size()),Color.BROWN)# 绘制单行文本text.draw(get_canvas_item(),Vector2())在上面的代码中
通过TextLine.new()创建了TextLine的实例text通过add_string()方法向text添加了一段文本通过text的draw()方法绘制文本
绘制效果 可以看到TextLine的绘制方式就比较符合直觉了而且获取的矩形区域也比较精确。
设定宽度和裁切文本
TextLine可以设定最大宽度width超过这个宽度的文本将不会被绘制。
extends Node2Dfunc _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))# 设定文本和字体var font ThemeDB.fallback_fontvar font_size 56 # 创建单行文本var text TextLine.new()text.add_string(ha ha ho ho heiehi hiehie ,font,font_size)text.width 160 # 限制宽度# 绘制单行文本的矩形区域draw_rect(Rect2(Vector2(),text.get_size()),Color.BROWN)# 绘制单行文本text.draw(get_canvas_item(),Vector2())绘制效果
使用TextParagraph构造和绘制段落文本
extends Node2D# 设定文本和字体
var font ThemeDB.fallback_font
var font_size 56 func _draw() - void:# 绘制坐标原点到绘图原点的矩形draw_rect(Rect2(Vector2(),Vector2(200,200)),Color.AQUA)# 修改绘图坐标原点draw_set_transform(Vector2(200,200))# 创建TextParagraphvar textP TextParagraph.new()textP.add_string(ha ha ho ho,font,font_size)textP.width 160 # 限制宽度# 绘制单行文本的矩形区域draw_rect(Rect2(Vector2(),textP.get_size()),Color.BROWN)# 绘制多行文本textP.draw(get_canvas_item(),Vector2())注意设定换行宽度后英文将以空格作为自动换行的依据之一在标点符号后要加一个空格才能正常的自动换行。比如Hello,my Godot必须在每个标点之后添加一个空格成为Hello, my Godot才能正确换行 前者因为没有在逗号后面加空格所以没有正确的自动换行。或者你也可以添加换行符\n来强制换行。你可以认为英文有两种换行一种是基于单词的换行也就是空格隔开的内容。另一种是强制换行也就是手动加\n。中文的规则则简单的多可以正确的自动换行当然也可以使用强制换行。 总结
本节简要讲述了CanvasItem内置的字符和字符串绘制函数及其缺点然后讲述了更好用的TextLine和TextParagraph用于绘制单行和多行文本。实际上TextLine和TextParagraph好有很多特性和功能可以让我们轻松实现很多东西。但是篇幅所限留到下节。对于文本绘制的综合使用也会专门留几个案例也是相当有趣。