人生第一个上线项目总结

  此时,项目公测第一天,项目组集体坐在公司值班,等待着用户反馈,鉴于之前已经做过为期半个月的内测,于是,公测的第一天晚上似乎不是多么紧张。

  毕业后,就进入现在公司,开始了现在项目。历时一年,很快。快结束的现在,总觉得自己应该总结下这一年发生的事情,于是,便记在这里,供自己“回眸”。(可能更多的是从程序员的视界来看待问题。


  使用技术:服务器,Linux + Java + Oracle;客户端,Unity3D(主要NGUI).

  产品框架

服务器 客户端 网站

1、登录服务器L。

2、登录场景。

 

2、主要服务器H。

1、登录器。

3、主要场景。

 

3、服务器G。

4、服务器D。

5、服务器O。

4、主要业务群。

 

  项目经过:1、练手阶段——使用Unity3D+NGUI(初次使用)。

       2、第一个东西——依然NGUI,客户端,主要为各种显示逻辑,显示效果。

         3、斗地主服务器——研究了一段时间的IOCP,最后因为所有服务器由Java开发,于是夭折。

       4、主要场景——由外包接手过来,基本全部(除通信部分)改掉,一直到现在。

         5、登录器——MFC。

       6、Debug阶段。

       7、内测、公测阶段。


 

懵懂的练手

  刚进入公司的时候,老大说客户端的所有效果将会由NGUI来完成,鉴于之前我有一年(实习)使用Unity3D的经验,于是让我直接开始做客户端中的一部分——一个场景(FS)。在将NGUI2.6.3导入场景之后,此时的我是不知如何建立Sprite,不知Atlas为何物。

  且摸着石头过河,看例子、群里问问。磕磕绊绊将FS所需功能、效果完成后,知晓NGUI的成员,知晓NGUI的层级。

NGUI

  NGUI,Unity3D中使用最多的UI插件,因其较少的Draw Call而受到开发者的喜爱。它通过将一系列图片通过一个序列进行排列,制成Atlas。使用它可以很方便的建立图片、按钮、文字、滚动条等。(现在我的水平为会用它,能够在需求下改改他的代码,至于全部读懂,还需要时间)。

  在使用NGUI前期,比较麻烦的就是层级问题,你不能单纯的通过z值来控制显示前后。自己总结了下:一个panel下的所有NGUI物体(有时候label除外)具有同一z值,通过depth来控制前后关系;一个panel里面的文字可以通过z值微调前后。多个panel的前后关系由z值控制。其他使用问题都比较简单,不再做说明。附一个之前改过的UiTextList(加入ScrollBar支持,可能后期版本需要修改使用,也可能以后版本的NGUI已经支持)。

  1 //----------------------------------------------
  2 //            NGUI: Next-Gen UI kit
  3 // Copyright ?2011-2013 Tasharen Entertainment
  4 //----------------------------------------------
  5 
  6 using UnityEngine;
  7 using System.Collections.Generic;
  8 using System.Text;
  9 
 10 /// <summary>
 11 /// Text list can be used with a UILabel to create a scrollable multi-line text field that's
 12 /// easy to add new entries to. Optimal use: chat window.
 13 /// </summary>
 14 
 15 [AddComponentMenu("NGUI/UI/Text List")]
 16 public class UITextList : MonoBehaviour {
 17     public enum Style {
 18         Text,
 19         Chat,
 20     }
 21 
 22     public Style style = Style.Text;
 23     public UILabel textLabel;
 24     public float maxWidth = 0f;
 25     public float maxHeight = 0f;
 26     public int maxEntries = 50;
 27     public bool supportScrollWheel = true;
 28 
 29     // Text list is made up of paragraphs
 30     protected class Paragraph {
 31         public string text;        // Original text
 32         public string[] lines;    // Split lines
 33     }
 34 
 35     protected char[] mSeparator = new char[] { '\n' };
 36     protected List<Paragraph> mParagraphs = new List<Paragraph>();
 37     protected float mScroll = 0f;
 38     protected bool mSelected = false;
 39     protected int mTotalLines = 0;
 40 
 41     /// <summary>
 42     /// Clear the text.
 43     /// </summary>
 44 
 45     public void Clear() {
 46         mParagraphs.Clear();
 47         UpdateVisibleText();
 48     }
 49 
 50     /// <summary>
 51     /// Add a new paragraph.
 52     /// </summary>
 53 
 54     public void Add(string text) {
 55         if (!isScreenLocked) Add(text, true);
 56         else Add(text, false);
 57     }
 58 
 59     /// <summary>
 60     /// Add a new paragraph.
 61     /// </summary>
 62 
 63     protected void Add(string text, bool updateVisible) {
 64         Paragraph ce = null;
 65 
 66         if (mParagraphs.Count < maxEntries) {
 67             ce = new Paragraph();
 68         } else {
 69             ce = mParagraphs[0];
 70             mParagraphs.RemoveAt(0);
 71         }
 72 
 73         ce.text = text;
 74         mParagraphs.Add(ce);
 75 
 76         if (textLabel != null && textLabel.font != null) {
 77             // Rebuild the line
 78             ce.lines = textLabel.font.WrapText(ce.text, maxWidth / textLabel.transform.localScale.y,
 79                 textLabel.maxLineCount, textLabel.supportEncoding, textLabel.symbolStyle).Split(mSeparator);
 80 
 81             // Recalculate the total number of lines
 82             mTotalLines = 0;
 83             for (int i = 0, imax = mParagraphs.Count; i < imax; ++i) mTotalLines += mParagraphs[i].lines.Length;
 84         }
 85 
 86         // Update the visible text
 87         if (updateVisible) {
 88             UpdateVisibleText();
 89             if (null != verticalScrollBar && mTotalLines > maxLines) {
 90                 verticalScrollBar.gameObject.SetActive(true);
 91                 downBtnGo.SetActive(true);
 92                 upBtnGo.SetActive(true);
 93                 verticalScrollBar.scrollValue = 1;
 94             }
 95         }
 96     }
 97 
 98     /// <summary>
 99     /// Automatically find the values if none were specified.
100     /// </summary>
101 
102     void Awake() {
103         if (textLabel == null) textLabel = GetComponentInChildren<UILabel>();
104         if (textLabel != null) textLabel.lineWidth = 0;
105 
106         Collider col = collider;
107 
108         if (col != null) {
109             // Automatically set the width and height based on the collider
110             if (maxHeight <= 0f) maxHeight = col.bounds.size.y / transform.lossyScale.y;
111             if (maxWidth <= 0f) maxWidth = col.bounds.size.x / transform.lossyScale.x;
112         }
113 
114         verticalScrollBar.onChange += OnVerticalBar;
115     }
116 
117     /// <summary>
118     /// Remember whether the widget is selected.
119     /// </summary>
120 
121     void OnSelect(bool selected) { mSelected = selected; isNotOnScroll = !selected; }
122 
123     /// <summary>
124     /// Refill the text label based on what's currently visible.
125     /// </summary>
126 
127     private int maxLines;
128     protected void UpdateVisibleText() {
129         if (textLabel != null) {
130             UIFont font = textLabel.font;
131 
132             if (font != null) {
133                 int lines = 0;
134                 maxLines = maxHeight > 0 ? Mathf.FloorToInt(maxHeight / textLabel.cachedTransform.localScale.y) : 100000;
135                 int offset = Mathf.RoundToInt(mScroll);
136 
137                 // Don't let scrolling to exceed the visible number of lines
138                 if (maxLines + offset > mTotalLines) {
139                     offset = Mathf.Max(0, mTotalLines - maxLines);
140                     mScroll = offset;
141                 }
142 
143                 if (style == Style.Chat) {
144                     offset = Mathf.Max(0, mTotalLines - maxLines - offset);
145                 }
146 
147                 StringBuilder final = new StringBuilder();
148 
149                 for (int i = 0, imax = mParagraphs.Count; i < imax; ++i) {
150                     Paragraph p = mParagraphs[i];
151 
152                     for (int b = 0, bmax = p.lines.Length; b < bmax; ++b) {
153                         string s = p.lines[b];
154 
155                         if (offset > 0) {
156                             --offset;
157                         } else {
158                             if (final.Length > 0) final.Append("\n");
159                             final.Append(s);
160                             ++lines;
161                             if (lines >= maxLines) break;
162                         }
163                     }//end for(b)
164                     if (lines >= maxLines) break;
165                 }//end for(i)
166                 textLabel.text = final.ToString();
167             }
168         }
169     }
170 
171     /// <summary>
172     /// Allow scrolling of the text list.
173     /// </summary>
174     public UIScrollBar verticalScrollBar;
175 
176     /// <summary>
177     /// just showed while the msgs more than one page.
178     /// </summary>
179     public GameObject downBtnGo;
180     /// <summary>
181     /// just showed while the msgs more than one page.
182     /// </summary>
183     public GameObject upBtnGo;
184     
185     /// <summary>
186     /// the screen is locked or not.
187     /// </summary>
188     private bool isScreenLocked = false;
189 
190     /// <summary>
191     /// while the user don't wanna scroll the screen.
192     /// </summary>
193     /// <param name="sender"></param>
194     public void lockScreenBtnClick(GameObject sender) {
195         isScreenLocked = !isScreenLocked;
196         if (isScreenLocked) {
197             verticalScrollBar.enabled = false;
198             foreach (BoxCollider bc in verticalScrollBar.GetComponentsInChildren<BoxCollider>())
199                 bc.enabled = false;
200             downBtnGo.GetComponent<UIButton>().isEnabled = false;
201             upBtnGo.GetComponent<UIButton>().isEnabled = false;
202         } else {
203             verticalScrollBar.enabled = true;
204             foreach (BoxCollider bc in verticalScrollBar.GetComponentsInChildren<BoxCollider>())
205                 bc.enabled = true;
206             downBtnGo.GetComponent<UIButton>().isEnabled = true;
207             upBtnGo.GetComponent<UIButton>().isEnabled = true;
208         }
209     }//end lockScreenBtnClick()
210 
211     void OnScroll(float val) {
212         if (isScreenLocked) return;
213         else {
214             if (mSelected && supportScrollWheel) {
215                 val *= (style == Style.Chat) ? 10f : -10f;
216                 mScroll = Mathf.Max(0f, mScroll + val);
217                 UpdateVisibleText();
218 
219                 isNotOnScroll = false;
220 
221                 //add by ljj.
222                 //Debug.Log("scroll value on text list: " + mScroll + "total lines: " + mTotalLines + " max lines: " + maxLines);
223                 if (null != verticalScrollBar && mTotalLines > maxLines) {
224                     verticalScrollBar.scrollValue = (1 - (mScroll) / (mTotalLines - maxLines));
225                 }
226             }
227         }//end else.
228     }
229 
230     /// <summary>
231     /// the left-down position where the textlist located.
232     /// </summary>
233     public Vector2 leftDownPosi = new Vector2(0, 60);
234 
235     /// <summary>
236     /// This script may use at everywhere, but not everyone need get one name from the list.
237     /// </summary>
238     public bool isNeedGetName = false;
239 
240     /// <summary>
241     /// this is the context menu after the user select one name.
242     /// </summary>
243     public GameObject contextMenuGo;
244 
245     /// <summary>
246     /// while the user press the text, get one name from the label, 
247     /// popup function box, like add friends or add to black list.
248     /// </summary>
249     void OnClick() {
250         return; //does not supported by the server from now on. 2014-3-19 16:54:57
251         /*
252         if (!isNeedGetName) return;
253 
254         Debug.Log("world list on click");
255 
256         int crtClkNameIndex = maxLines -
257             ((int)((UICamera.lastTouchPosition.y - leftDownPosi.y) / (textLabel.cachedTransform.localScale.y * 1.375f)));
258 
259         string[] eachLines = textLabel.text.Split('\n');
260 
261         if (crtClkNameIndex >= eachLines.Length) { //clicked the blank area
262             contextMenuGo.SetActive(false);
263             return; 
264         } 
265 
266         string otherPlayerName;
267         try { 
268             otherPlayerName = (eachLines[crtClkNameIndex].Split(']')[1]).Split('说')[0].Trim(); 
269         } catch {
270             otherPlayerName = "";
271         }
272 
273         if (!string.IsNullOrEmpty(otherPlayerName) && "你" != otherPlayerName && "您" != otherPlayerName) {
274             contextMenuGo.SetActive(true);
275             contextMenuGo.transform.FindChild("otherNameLabel").GetComponent<UILabel>().text = otherPlayerName;
276         }//end if.
277         else {
278             contextMenuGo.SetActive(false);
279         }
280 
281         Debug.Log(otherPlayerName);*/
282     }//end OnClick()
283 
284     /// <summary>
285     /// to keep drag is safe. means while the user is scrolling. he can't drag the scrollBar.
286     /// </summary>
287     private bool isNotOnScroll = true;  
288     /// <summary>
289     /// while the user drag the scrollBar, update the text list. add by ljj.
290     /// </summary>
291     /// <param name="sb"></param>
292     void OnVerticalBar(UIScrollBar sb) {
293         if (isScreenLocked) return;
294 
295         float y = (verticalScrollBar != null) ? verticalScrollBar.scrollValue : 0f;
296         //Debug.Log("scroll value: " + y);
297         //Debug.Log("scroll value on text list: " + mScroll + "total lines: " + mTotalLines + " max lines: " + maxLines);
298 
299         if (isNotOnScroll) {
300             mScroll = (mTotalLines - maxLines) * (1 - y);
301             //Debug.Log("mScroll: " + mScroll + " max lines: " + maxLines + " scroll value: " + y);
302             UpdateVisibleText();
303         }
304     }
305 
306     /// <summary>
307     /// for the down btn which while pressed will take the text to down for one line. add by ljj.
308     /// </summary>
309     /// <param name="sender"></param>
310     public void downBtnClick(GameObject sender) {
311         Debug.Log("down btn");
312         if (mScroll > 0)
313             --mScroll;
314 
315         isNotOnScroll = false;
316         if (null != verticalScrollBar && mTotalLines > maxLines) {
317             verticalScrollBar.scrollValue = (1 - (mScroll / (mTotalLines - maxLines)));
318         }
319         UpdateVisibleText();
320         isNotOnScroll = true;
321     }//end downBtnClick()
322 
323     /// <summary>
324     /// while the user press the up btn, move the text to up for one line.
325     /// similar with the downBtnClick(). add by ljj.
326     /// </summary>
327     /// <param name="sender"></param>
328     public void upBtnClick(GameObject sender) {
329         Debug.Log("up btn");
330         //Debug.Log("mScroll: " + mScroll + " max lines: " + maxLines + " scroll value: " + verticalScrollBar.scrollValue);
331         if (mScroll < mTotalLines - maxLines)
332             ++mScroll;
333 
334         isNotOnScroll = false;
335         if (null != verticalScrollBar && mTotalLines > maxLines) {
336             verticalScrollBar.scrollValue = (1 - (mScroll / (mTotalLines - maxLines)));
337         }
338         UpdateVisibleText();
339         isNotOnScroll = true;
340     }//end upBtnClick()
341 
342     /// <summary>
343     /// while the user wanna see the next page's text, he will press this btn. add by ljj.
344     /// </summary>
345     /// <param name="sender"></param>
346     public void downPageBtnClick(GameObject sender) {
347         Debug.Log("down page btn");
348         if (mScroll > maxLines) {
349             mScroll -= maxLines;
350         } else {
351             mScroll = 0;
352         }
353 
354         isNotOnScroll = false;
355         if (null != verticalScrollBar && mTotalLines > maxLines) {
356             verticalScrollBar.scrollValue = (1 - (mScroll) / (mTotalLines - maxLines));
357         }
358         UpdateVisibleText();
359         isNotOnScroll = true;
360     }//end downPageBtnClick()
361 
362     /// <summary>
363     /// the previous page. add by ljj.
364     /// </summary>
365     /// <param name="sender"></param>
366     public void upPageBtnClick(GameObject sender) {
367         Debug.Log("up page btn");
368         if (mScroll < mTotalLines - maxLines - maxLines) {
369             mScroll += maxLines;
370         } else {
371             mScroll = mTotalLines - maxLines;
372         }
373 
374         isNotOnScroll = false;
375         if (null != verticalScrollBar && mTotalLines > maxLines) {
376             verticalScrollBar.scrollValue = (1 - (mScroll) / (mTotalLines - maxLines));
377         }
378         UpdateVisibleText();
379         isNotOnScroll = true;
380     }//end upPageBtnClick()
381 }
UiTextList

 第一个正式且将上线供客户使用

  值得提提的是,在接手做这个事情的时候,在对人做事上犯了一个错误。这个东东本来之前是公司另外一哥们儿做的,一个月了,中间他又家里有事儿请了几天假。老大就把这个东东给我弄了,然后我全部重新做,用了一周时间把这个(界面显示部分,此时还未连服务器)给弄完了。没过几天他就撤了。感觉甚是对他不起。

夭折的斗地主服务器

  算下来,这个也折腾了一个月吧!因为当时的我对Linux一点不了解,只会在windows上使用C++写点控制台程序。于是在那里使劲的研究IOCP,研究来研究去,倒是对服务器有了一些基本认识,多线程、线程池、共享数据、框架;对Linux有了一丢丢的认识。

  现在想想,没做成的主要有这几个方面(不组合,从多种情况考虑)原因:

    1、大方向没有选择正确,应该选择Linux下的C++框架or Java框架(公司服务器就是用的这个)。

    2、使用C++的话,没人带,基本方向只是我自己在撞。应该多问问周围人的,比如总监,比如老大,比如服务器主程。

  然后,这也只是在学校的那种学习模式,学了不用!

项目的中心——主要场景MS

  MS是在我来之前外包出去的,外包需要做的东西完了之后,由我接手。回来之后由于需求变更、bug调整,直到项目上线,除了基本的背景没变之外,其他地方都被改变了。

  后面加的东西,大致罗列一下:新手教学、进程间通信(socket)、活动抽奖等其他很多内容。

  整个做下来,倒是对NGUI挺熟悉了,不过3D方面的内容了解的就不会太多。

登录器

   使用VS2010的MFC搞定。其实算算呢,只是在网上copy了几个例子,然后把他们结合在一起形成了最后这个东西。对整个MFC的认识不会太深刻,倒是有时候会沾沾自喜——我也能用MFC做(拼)东西。

  警醒自己:如果要快且好的做东西,还是需要知道底层是如何实现和制作的。

DEBUGING

  这个阶段主要和公司的功能测试两个合作,主要的模式:我把产品交过去,她找问题,直接反馈给我,如果是我这里的问题我就直接改掉,或者请(在这里似乎快达到协调高度了)另外客户端程序改掉。

  觉得这个阶段里面有很多地方值得改进下。可能需要我做过更多项目的时候才能总结出来点东西。

内测、公测

  其时我们公司只有一个搞运营的,在上线的前几天,往往我们一大堆客户端研发去做客服和技术支持,整体感觉是有点乱,但似乎我倒是比较喜欢这种感觉,因为给别人讲解别人自己做的东西如何用,还是有那么点(真的只有一丢丢)傲娇的感觉。

  这个阶段因为对MFC开发的不了解,拼出来之后,给客户用的时候,便出问题了。出现的最大的问题就是登录器的兼容问题、安全问题。

  因为是使用的VS2010开发,所以经常客户电脑上出现“找不到MFCxxxx.dll”这个错误。现在想起来,当时老大确实是不容易的,给我们挡了许多事情。这个问题也找了许久,但是一直没有找出个所以然来,如果有大神知道的话,还望指点。PS:我们最后的解决方式,1、让安装登录器之前直接装一遍vcredist2010_x86.exe这个,但是很多时候会被360阻止;2、以绿色版的形式给用户,出现问题,提示用户先安装vcredist2010_x86.exe,所以这个问题就跑到客服那里去了。

  有许多需要改进的地方哩!

综述:

  想想看,在项目公测一个月之后的离开是不对的。当时没理解到老大说的“一个事情是需要做完的”的意思!在此抱歉!

  我还是太年轻,没想清楚自己真正想要的是什么!很严重的一个问题。

 

最后,附上产品网站地址哈!虽然在很多地方的优化做的还不够好,但是真的可以用的,真的可以中奖的哦!

posted on 2014-06-06 20:41  我要改名叫嘟嘟  阅读(726)  评论(0编辑  收藏  举报