在Android游戏开发中,我们不可能全部用图片来显示,很多时候需要绘制字符串,比如开发一个RPG的游戏,有大量的对话内容,这时如果全部用图片来显示肯定不行。下面我们就看看如何在Canvas画布中绘制字符串吧。
Android中提供了一系列的drawText方法来绘制字符串,在绘制字符串之前需要设置画笔对象,包括字符串的尺寸、颜色等属性。使用 FontMetrics来规划字体的属性,可以通过getFontMetrics方法来获得系统字体的相关内容。下面来看一个大量文本自动换行、翻页的示例是如何操作字符串的,运行效果如图5-9所示,当我们按下方向键翻页时,如图5-10所示。
关于字符串自动换行的完整代码如下所示:
001 | /** |
002 | * 实现文字自动换行 |
003 | * 自动翻页 |
004 | */ |
005 | package com.yarin.android.Examples_05_06; |
006 | |
007 | import java.util.Vector; |
008 | import android.graphics.Canvas; |
009 | import android.graphics.Color; |
010 | import android.graphics.Paint; |
011 | import android.graphics.Paint.FontMetrics; |
012 | import android.view.KeyEvent; |
013 | |
014 | public class TextUtil |
015 | { |
016 | int m_iTextPosX; //绘制的x点 |
017 | int m_iTextPosY; //绘制的y点 |
018 | int m_iTextWidth; //绘制宽度 |
019 | int m_iTextHeight; //绘制高度 |
020 | |
021 | int m_iFontHeight; //字体高度 |
022 | |
023 | int m_ipageLineNum; //每一页显示的行数 |
024 | |
025 | int m_iTextBGColor; // 背景颜色 |
026 | int m_iTextColor; // 字体颜色 |
027 | int m_iAlpha; //Alpha值 |
028 | |
029 | int m_iRealLine; // 字符串真实的行数 |
030 | int m_iCurLine; //当前行 |
031 | |
032 | String m_strText; |
033 | |
034 | Vector m_String; |
035 | |
036 | Paint m_paint; |
037 | |
038 | int m_iTextSize; |
039 | |
040 | |
041 | public TextUtil() |
042 | { |
043 | m_paint = new Paint(); |
044 | m_String = new Vector(); |
045 | } |
046 | |
047 | |
048 | public TextUtil(String strText, int x, int y, int w, int h, int bgcolor, int txetcolor, int a, int iTextSize) |
049 | { |
050 | m_paint = new Paint(); |
051 | m_String = new Vector(); |
052 | |
053 | m_strText = strText; |
054 | |
055 | m_iTextPosX = x; |
056 | m_iTextPosY = y; |
057 | m_iTextWidth = w; |
058 | m_iTextHeight = h; |
059 | |
060 | m_iTextBGColor = bgcolor; |
061 | m_iTextColor = txetcolor; |
062 | |
063 | m_iTextSize = iTextSize; |
064 | |
065 | m_iAlpha = a; |
066 | |
067 | } |
068 | |
069 | /** |
070 | * 初始化 |
071 | * @param strText 要显示的字符串 |
072 | * @param x x |
073 | * @param y y |
074 | * @param w w |
075 | * @param h h |
076 | * @param bgcolor 背景颜色 |
077 | * @param txetcolor 文字的颜色 |
078 | * @param a Alpha |
079 | * @param iTextSize 字体大小 |
080 | */ |
081 | public void InitText(String strText, int x, int y, int w, int h, int bgcolor, int txetcolor, int a, int iTextSize) |
082 | { |
083 | m_iCurLine = 0 ; |
084 | m_ipageLineNum = 0 ; |
085 | m_iRealLine = 0 ; |
086 | m_strText = "" ; |
087 | m_iTextPosX = 0 ; |
088 | m_iTextPosY = 0 ; |
089 | m_iTextWidth = 0 ; |
090 | m_iTextHeight = 0 ; |
091 | m_iTextBGColor = 0 ; |
092 | m_iTextColor = 0 ; |
093 | m_iTextSize = 0 ; |
094 | m_iAlpha = 0 ; |
095 | |
096 | m_String.clear(); |
097 | |
098 | SetText(strText); |
099 | SetRect(x, y, w, h); |
100 | SetBGColor(bgcolor); |
101 | SetTextColor(txetcolor); |
102 | SetFontSize(iTextSize); |
103 | SetAlpha(a); |
104 | |
105 | SetPaint(); |
106 | |
107 | GetTextIfon(); |
108 | } |
109 | |
110 | /** |
111 | * 设置Alpha |
112 | * @param a Alpha值 |
113 | */ |
114 | public void SetAlpha( int a) |
115 | { |
116 | m_iAlpha = a; |
117 | } |
118 | |
119 | /** |
120 | * 对Paint属性的设置 |
121 | */ |
122 | public void SetPaint() |
123 | { |
124 | m_paint.setARGB(m_iAlpha, Color.red(m_iTextColor), Color.green(m_iTextColor), Color.blue(m_iTextColor)); |
125 | m_paint.setTextSize(m_iTextSize); |
126 | } |
127 | |
128 | /** |
129 | * 设置字体尺寸 |
130 | * @param iTextSize |
131 | */ |
132 | public void SetFontSize( int iTextSize) |
133 | { |
134 | m_iTextSize = iTextSize; |
135 | } |
136 | |
137 | /** |
138 | * 设置显示文本的区域 |
139 | * @param x |
140 | * @param y |
141 | * @param w |
142 | * @param h |
143 | */ |
144 | public void SetRect( int x, int y, int w, int h) |
145 | { |
146 | m_iTextPosX = x; |
147 | m_iTextPosY = y; |
148 | m_iTextWidth = w; |
149 | m_iTextHeight = h; |
150 | } |
151 | |
152 | /** |
153 | * 设置背景颜色 |
154 | * @param bgcolor |
155 | */ |
156 | public void SetBGColor( int bgcolor) |
157 | { |
158 | m_iTextBGColor = bgcolor; |
159 | } |
160 | |
161 | /** |
162 | * 设置字体颜色 |
163 | * @param txetcolor |
164 | */ |
165 | public void SetTextColor( int txetcolor) |
166 | { |
167 | m_iTextColor = txetcolor; |
168 | } |
169 | |
170 | /** |
171 | * 色绘制要显示的字符串 |
172 | * @param strText |
173 | */ |
174 | public void SetText(String strText) |
175 | { |
176 | m_strText = strText; |
177 | } |
178 | |
179 | /** |
180 | * 得到字符串的信息 |
181 | * 包括:行数、页数等信息 |
182 | * 内部调用 |
183 | */ |
184 | public void GetTextIfon() |
185 | { |
186 | char ch; |
187 | int w = 0 ; |
188 | int istart = 0 ; |
189 | FontMetrics fm = m_paint.getFontMetrics(); |
190 | |
191 | m_iFontHeight = ( int ) Math.ceil(fm.descent - fm.top) + 2 ; |
192 | |
193 | m_ipageLineNum = m_iTextHeight / m_iFontHeight; |
194 | |
195 | for ( int i = 0 ; i < m_strText.length(); i++) |
196 | { |
197 | ch = m_strText.charAt(i); |
198 | float [] widths = new float [ 1 ]; |
199 | String srt = String.valueOf(ch); |
200 | m_paint.getTextWidths(srt, widths); |
201 | |
202 | if (ch == '\n' ) |
203 | { |
204 | m_iRealLine++; |
205 | m_String.addElement(m_strText.substring(istart, i)); |
206 | istart = i + 1 ; |
207 | w = 0 ; |
208 | } |
209 | else |
210 | { |
211 | w += ( int ) (Math.ceil(widths[ 0 ])); |
212 | if (w > m_iTextWidth) |
213 | { |
214 | m_iRealLine++; |
215 | m_String.addElement(m_strText.substring(istart, i)); |
216 | istart = i; |
217 | i--; |
218 | w = 0 ; |
219 | } |
220 | else |
221 | { |
222 | if (i == (m_strText.length() - 1 )) |
223 | { |
224 | m_iRealLine++; |
225 | m_String.addElement(m_strText.substring(istart, m_strText.length())); |
226 | } |
227 | } |
228 | } |
229 | } |
230 | } |
231 | |
232 | /** |
233 | * 绘制字符串 |
234 | * @param canvas |
235 | */ |
236 | public void DrawText(Canvas canvas) |
237 | { |
238 | for ( int i = m_iCurLine, j = 0 ; i < m_iRealLine; i++, j++) |
239 | { |
240 | if (j > m_ipageLineNum) |
241 | { |
242 | break ; |
243 | } |
244 | canvas.drawText((String) (m_String.elementAt(i)), m_iTextPosX, m_iTextPosY + m_iFontHeight * j, m_paint); |
245 | } |
246 | } |
247 | |
248 | /** |
249 | * 翻页等按键处理 |
250 | * @param keyCode |
251 | * @param event |
252 | * @return |
253 | */ |
254 | public boolean KeyDown( int keyCode, KeyEvent event) |
255 | { |
256 | if (keyCode == KeyEvent.KEYCODE_DPAD_UP) |
257 | { |
258 | if (m_iCurLine > 0 ) |
259 | { |
260 | m_iCurLine--; |
261 | } |
262 | } |
263 | else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) |
264 | { |
265 | if ((m_iCurLine + m_ipageLineNum) < (m_iRealLine - 1 )) |
266 | { |
267 | m_iCurLine++; |
268 | } |
269 | } |
270 | return false ; |
271 | } |
272 | } |
setTextSize:设置字符串的尺寸
setARGB:设置颜色(ARGB)
getTextWidths:获取字符串的宽度
setFlags(Paint.ANTI_ALIAS_FLAG):消除锯齿
当然要取得字符串的宽度还可以使用measureText方法,得到字符串宽度,可以使用如下代码:
1 | FontMetrics fm = m_paint.getFontMetrics(); |
2 | m_iFontHeight = ( int )Math.ceil(fm.descent - fm.top) + 2 ; |
到这里,我们己经可以绘制出一些几何图形和字符串了。一个游戏当然不是这些简简单单的几何图形加上字符串就能组成的,还需要一些美工资源的支持,界面才能更加的漂亮。