From 8bc3090d6922ea06c79e77bd5a8b349b80943e1c Mon Sep 17 00:00:00 2001 From: William Moorehouse Date: Tue, 23 Jun 2015 15:49:21 -0400 Subject: [PATCH] Refactored game interface a bit, misc features --- TrueCraft.Client/Content/Fonts/Pixel_Bold.fnt | 328 +++++++++++++++++ .../Content/Fonts/Pixel_Bold_0.png | Bin 0 -> 6655 bytes .../Content/Fonts/Pixel_Italic.fnt | 329 ++++++++++++++++++ .../Content/Fonts/Pixel_Italic_0.png | Bin 0 -> 9396 bytes .../Content/Fonts/Pixel_Italic_1.png | Bin 0 -> 2348 bytes .../Content/Fonts/Pixel_Regular.fnt | 328 +++++++++++++++++ .../Content/Fonts/Pixel_Regular_0.png | Bin 0 -> 6290 bytes .../Content/Fonts/pixel-license.txt | 4 + TrueCraft.Client/Interface/ChatInterface.cs | 181 +++++----- TrueCraft.Client/Interface/Control.cs | 115 ++++++ TrueCraft.Client/Interface/DebugInterface.cs | 56 +++ TrueCraft.Client/Interface/IGameInterface.cs | 2 + TrueCraft.Client/Interface/InterfaceScale.cs | 13 + TrueCraft.Client/TrueCraft.Client.csproj | 27 ++ TrueCraft.Client/TrueCraftGame.cs | 97 ++++-- 15 files changed, 1341 insertions(+), 139 deletions(-) create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Bold.fnt create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Bold_0.png create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Italic.fnt create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Italic_0.png create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Italic_1.png create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Regular.fnt create mode 100644 TrueCraft.Client/Content/Fonts/Pixel_Regular_0.png create mode 100644 TrueCraft.Client/Content/Fonts/pixel-license.txt create mode 100644 TrueCraft.Client/Interface/Control.cs create mode 100644 TrueCraft.Client/Interface/DebugInterface.cs create mode 100644 TrueCraft.Client/Interface/InterfaceScale.cs diff --git a/TrueCraft.Client/Content/Fonts/Pixel_Bold.fnt b/TrueCraft.Client/Content/Fonts/Pixel_Bold.fnt new file mode 100644 index 0000000..22cd524 --- /dev/null +++ b/TrueCraft.Client/Content/Fonts/Pixel_Bold.fnt @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrueCraft.Client/Content/Fonts/Pixel_Bold_0.png b/TrueCraft.Client/Content/Fonts/Pixel_Bold_0.png new file mode 100644 index 0000000000000000000000000000000000000000..28d52c9c7767cee992bfe9025cd975cacb1229e6 GIT binary patch literal 6655 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 JPDHLkV1jdy>4X3P literal 0 HcmV?d00001 diff --git a/TrueCraft.Client/Content/Fonts/Pixel_Italic.fnt b/TrueCraft.Client/Content/Fonts/Pixel_Italic.fnt new file mode 100644 index 0000000..f2cf770 --- /dev/null +++ b/TrueCraft.Client/Content/Fonts/Pixel_Italic.fnt @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrueCraft.Client/Content/Fonts/Pixel_Italic_0.png b/TrueCraft.Client/Content/Fonts/Pixel_Italic_0.png new file mode 100644 index 0000000000000000000000000000000000000000..abe0c92da5e8bd0ffa8ce966b52dee8241a5910c GIT binary patch literal 9396 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 B^dtZP literal 0 HcmV?d00001 diff --git a/TrueCraft.Client/Content/Fonts/Pixel_Regular.fnt b/TrueCraft.Client/Content/Fonts/Pixel_Regular.fnt new file mode 100644 index 0000000..e011a9a --- /dev/null +++ b/TrueCraft.Client/Content/Fonts/Pixel_Regular.fnt @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrueCraft.Client/Content/Fonts/Pixel_Regular_0.png b/TrueCraft.Client/Content/Fonts/Pixel_Regular_0.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed79fac7619835f7d880e5aed15191e40cdcfef GIT binary patch literal 6290 zcmciH`#%%j{{Zm0<(AyG+?z3>*ix3L{0APDyY+wZd&|GY308E!I z7N>wJPXIsw^1$GpO<2)Z@oesQV4cA{e1+%2?XkrRmZ$ooW3;>YyaJ6*>JPf{s%`@*J{nATo{PS|Y?6uhy4f5VXPf>aS9A^~S#P88Yo;`zU#Xd~_^sTOwnt$~LMM>o-- zybXtfzi@fX?WI+3RQFh-3f;-KY+U-n+QLVH{kqGR@*z^|NrA~6toZ-5&60bns>JG|a% z`8qlD@?+14`C%Bhm7N)$u53lQc{4=5lTtOOD8k9aq+%tb$cLCfnIf1YJ*S#7HxW3yqpkg!DSK8Pg(oo`17}w zVJyRt{o7)`y&KGZ3KN~=`8~Ur+krzzgLE7}`&5+az&^Fs8X=zIsD?c}t8S-%u94k- z0N$%)<%#EkI~anb*dI-=v`%~UkY~=*8L##xU1WVh`IWtc*iZyWnA_$vH zx|9t95tts_c?6b7Z+T|pA5MX%_zbz|`T>ztMJ&M~t@>mp;L*23SSSfo4Y2z}T#%|B zV3tVy=*y7mP0T2&CZIA?$Oy2bS&*}zceTCQEfiC%H0iok$qa-_#W)_(ci&25`Y zJerlU03}=gpI_~#1q$GSUy+TL~MPU(pjXS3Su&2Iy1O9~|u zw@^X-7U0PGgI_5%9qe1jA8$%Z^kgYLVE@};r8CQl_#MebgXSo!1~&~b=l&XT))CtP z+B(Xx2F>H66lcNHj4(FTEGlvGB<}$&d5cvl#!K(ar`{4l2;XWPxbgN@dFRe0pC|d0 znpRDPkuJ{hHRNFfPtN>&q01$%pM9r6i zZwBH0VAr?5DSBhvI3h7Bo#k~?ZWAcfZx0X?rmDlf$jXfZ+rPAi-ji_oV(s`6656l^ zdbc9ge3q7cc<@@py&sc+^F~zQyaeL5M;uVlIYr#W$&WZu9R`k}ZFqr)y`X-)WS+EJ zT-7CN=EUCM-P(;B8-oezru>H*`xbrA>8@&>3dqvuqCaZs98hjM_UM$(vkVWB5iek` zuwK<)fezL7?`5-G|7kswei5=Q(WaYL*+KYO{3g6ao{nV~3hHKY`oQd1SN>Gt8Rnb9 z#BPO-{eWkYvih~}b7}?F8AU0{X{#)tfmy0yVL6DfR_$3?z1pyYXeGJ+uTuSYSQyQV z0h%;3WQw*ZByDe1=xAb%E4L`&czFp|LS^SdJNCd%jlf(mqPG*cdfOrpev>xk*`NJ| zP?J`s-CJfG^l0p$@8$Sax$R58A*y2b44aW4_qFPiVWe71WQnH&V5FviMm~I1%(niR zbp*R{Y+Kj9fq?G#`9-eh>+u2#M+uqx^kygen^0R`x0{taJIyxXfI)uEy_Ex=D=0bJ z@N3gWXR$NEktmYkN{v0gsCi8|Qt;1TM(23PB?O=nPBEYPQi#hUE$Bj{_%sq zZAJ&G-^~47OXgnOJ-P2&Ro(|$Ns`sorZBQ}htLi+0G+Hnc!M|Hk;iHSOR zMc1t{8k;}O^!~>YM!L+`Vs0f}cYeF6OuOIjft?`{96)=L`6N@*!l&eT&)D#Q^nYDi zbx=RAXEG0)1-)(gsM))6Q-?c49(w*_*65ip_qxU(BPH}SlTto=YN6_}|46|T)OSl3 zY1a!pjH(%@oAwh=Y>HP(WL}W|ecY6z8_U)D4(8P)Q!)BnyUO_e_oe=;-IwmWv%s5yDkE#M4Jj0=JjogZEdANKfwx zTh36@rU(kD9<@!a*UedIdc|zzR>`f(HC&Y2O0$uerHT#1%lZaqt`xX5O~vlWdRX>E zgvqlV`~Rvr1PR-I{i=|&w|@-SqniNW0&&p+2bJtWgl!BEOwx8(eX2`vIGbI2nM%>0 zZpMrjl5Vyp)9NXOWiMV7`4fd? zt*J$u<&vR4kdd9@^uKo1|Fv-Z>^BGiOazeP!K&8bzC2PXdOCE?MV>jo?iRa~yJovN z(LTRZYJ}b()m%33_`F!ZwR19_rJb@-N6RYV61QI%ZK^mu@(_z*_0~p>oefE1lqjKzJa^f@!CrMK7ey6dm|y@@%Ew;cI~Ch`EUPx zgh#^YpdW3yjpLX+qCo>0e1QA*btvpvrQAn?tevLkSVbE!5{A3;lV$%JR%hC=J^B=K8Kv*4wR$yZRY4mG!%3OrlC zY&3p^Esf)>*;pr;g7zNiBK-742+5%|pce}-y+=!nxdlr{^&9w}1a%-qhHI%9k14|9 z&W627i7fx^C@Rs1hbCSpnTNl8oFlex3{I@iR&LiKgc)8I_vX+!%P%}KEc2xX*e18O*CzFktCQ~Q zqU>Gg@??>KiOeK88!#y*PJem{v}6g%P;>Vi^AeL}$JyoZbuc{X{XMix{59INeb4r2 zG62Zn#{5?dKc8#Q^h4zf-HeBJg{s$bSl#Vc4&IuxYcfwNa=Yiv4a5Qzg-TnlK4ud> zRvD;fOAltx^{47YdmY&2LTp|MU9r@QW$fwqwH%opewxrk@)5 zPZdqdk|?0l1G?RM@%~)Irs$z`HivXBV|q%l-CIIeeTpW;PQ8HQbq^?^5U!iKHq;>n zM#N@8usgE3G=^-+*nG^hqz@bo?q;wA+Ko=uaq>S+&vT8X3UqVP7NSg>g~wd1U6-Ap zo&=SNH9y)5OYjN8Z)7n35vdjnYJBIxhj%b8S^S8jf8V%Kf;vpn%k4u4)Yv+XDNnmR z0=cYw2|HwTR5TFlxs9drNo~U>3MB zd$5|zSqub+WOQh(gY8b6W1tcK?}i1Be~te$0!VZGU;X z)5GK&Q4$G|d|EDN{77im44bQUTYT3kMD8F_=y*7o6K5Bq*%nIzYBT@Sh+;fHi@0Ss zcZ^5QOdM6X&r<8kt9M|UHPDhRLAF3Z!$zhrC2<9-!atlSqYm@4iZx71UJ&w0RL5m8 zKIdnhQme2T(5SAbILePa&-jxJ&Xv_=EoHYocFqN&Z2*Giuc(>8o1dh5t+p3wu3{z= zwzm?kia#(_Q0$ycMgkx236XZKGhwml=IwDO8=ASH6+Zn_6FXH~BtUA*Bj=rMw*cnV zVArfwan2%s%t#>R+@H9A@F_y`c3f@gyzCv%eI!Q}ZR_{97DXnp(7N@fdTS{iu2W%# z+#O1@^)2l?+<}0MYo%5F=*i&;E7@?gH+4Ni@YNgta$0*f2U?$j3T9#3E(WNoMN(XC zN;aodKqxoPtW!FuQL-=Yi?vX!=b8NTMlw$EjPvJK(I$JwW~RrCy~k%JFJrm}uh)XN z@&@M?G(9Jd=xxElkWC+S5>gF<*lOk6j2b_JSnd67Sk#}fX(_hbPsn~ADO@k(*aCwY zEW>&Egt;5|V9olY*#>ogzxjvnO(dUhZm1t~!D>UV?Iy1R(k;TZWo2nfSvJ&c(Xn^m zS4v+pmn;y0tsq!vMGv2(7M^U$(5M$^HzvGHo(;A<=zvFDH8Dnl4AKWbtkSbn6Ai1B7k9^`!!P(XVtp(<8SiD)e5^UI#~ zN6j6{+heS6%Bf=L74eiqqQ~J{a9(+$+IIv?O+&?HFCF6sMZN&jc#=OOJ0K;$ocR_Z z)8@(I?=g^#3o#Qm;1MquI5J6?D_!wdS?O9Q>+d0z>GtQ;4Fnw1vTyQ1)n!k`dM2?0 z1~|c#R5_yHnyxi-8g!=}oRYq*Cch*a~OZ>_&Uw_GLM3v z^x84bu5W0Qf%+3|VZlq4wT_pIc2>QUl@41T?cy|=TQ?_XZeru1lIDK_mo#WJ!GC$yB)zKr zo|+aH#ybSpVBG=BVo%(bA3bUdKUXyl76irfHL}ODdCb7X3V~u<%v)K4*F773RNA_` zTeBD~cuz37SviHGp~r2OeK%e|zZz-bt%2-1lvB zZ*$y7cbe!LhVaIUuD{-usR6Z(#UyU`J7-w}re|RgHwn$aSB&*-MH-phk)*O5_2Hkk z3c#TGsyRLaSDiN!N}??PjgJwxq)S+4D0g=_6BItuiTUS}+OH7k2)>VBO)=2`A~Uow)ZYR+rFEb(^{qtv;9yiSreSHbz_Rt(2tEsS?c z(Ijgn`^|L4H+O*{jD9bKRDC=bx0mipe|&e{7oR;F6q{4kJQE+9m9vr3KJwOjF6N>Y zsZf64gPHK3F4|TjnAv&`G)3@Mgf5^@QqbYQsnCA|+*K9;a4~!ukDbv6#&H9qrz07> z=pF>G=H%Fw>^|ba@wEd*H9W=VOH0uBHcm(hUX2c^M28jbemx=;qw?><$wr&U)lzPE z+L~(G4A$QHob~-@iVp$PmYi5yn4={`N;O)!s@5mzd3G@@St`oJ$jQAQ;r2)6Pl{8h zf`W`hy$?CTt48e*f&R>hL0mPDd_+5iH+?mm`>XVZt2V-&IhBXO3 zEFgD2jq<1%0oEahfnfw0KIBP8?vRP(v-N6WryTUJ_7Rx8Xt5j_p(<7^Roz;i(SxJ{{tr6lL^mp4&5)f9a4 z@-|>XE;ckO>=V!IHcf)W+YgIBAyu{`T%cTgfK`XV#FCi!WQc1>Gc6C>f?C4JdV~g? zmpM?r9~1tv?>3o(s7b8G*R!2RI=R?1;aS|24e1bJ!9;=B%{j|5Q-g= zyB0UEy>ojYoT=hOaMXyq2ddf$Dnoxq7RX-Rz7Nt)E?GL*nGoufcHGI65yza8qmax? zUR<~qva5j(pw|$|YRZZk_>CZ+KE$C)IRzyFv49OX_o>+>Ni3T1&As%KfMy)LozpUn z&yvIVBlaPtCi`#!ZUxYkVr~A4Wfmr^blsWgFy+4<4V=g%)iP#9rqMK=iZ9OWhbi-I z-_%i^jiT@WTAyvad>nb+RRVv{@&+*4!UI^=HwECXPUv`u%}pmOLTp`vL{1QCi5%|q z$FUa!4K~jmB`^8`Te?gG+vu@F`|ea8bqMXScK50YELD$vAAVlvH8w0?ix<(1Df-U> z=|@*P4kdnxERcy}S*MP+t;8u=uPO&ug%?cKUi zFJJtN#5mae;B2tF%{|1DP6uT$jCOGDw^~`A@y-iIke?gt?OM@|A&OXYhKW#Q8OYT@ zLTsQ|KN^C^0#Q1N8*4c}cKrmR|MhQdVckqqC_7~CEo=DpP{a6rDT7xR^RQu6I)uc^ zP%V7J!UP{Dkg;T(+a;N${4DjbqAdRyevm}XePcDGj7iBC0~9tUMR$x(66=hL62;Ql>Db#Cl>VMr9*cC>60bXp9B(cAD;Iv;m+jb9`5tYofx9R%$?)ypq;FXo&P0t zz3>ygzvN4g`eaOWioX)dOrtpEc*7vQbYbEAvJ7-Z0r)a8lp%(L;dEh}jY;C*#|j`l zbR*n-+?B|w@4LJ#63r9Kk%e0Y#BeCz*S;X=WS$Fk0kK>Vw-mz#+GfyRXs_}AsQmr^ l2+j&{VWQXnpO2lhCjfQVgcBvAF8&$-4-Cx=YW3Y-{U3fYJ7fR= literal 0 HcmV?d00001 diff --git a/TrueCraft.Client/Content/Fonts/pixel-license.txt b/TrueCraft.Client/Content/Fonts/pixel-license.txt new file mode 100644 index 0000000..50911a7 --- /dev/null +++ b/TrueCraft.Client/Content/Fonts/pixel-license.txt @@ -0,0 +1,4 @@ +The FontStruction “Pixel UniCode” +(http://fontstruct.com/fontstructions/show/908795) by “ivancr72” is licensed +under a Creative Commons Attribution license +(http://creativecommons.org/licenses/by/3.0/). diff --git a/TrueCraft.Client/Interface/ChatInterface.cs b/TrueCraft.Client/Interface/ChatInterface.cs index 14bbc0f..d4460ef 100644 --- a/TrueCraft.Client/Interface/ChatInterface.cs +++ b/TrueCraft.Client/Interface/ChatInterface.cs @@ -1,15 +1,15 @@ using System; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using TrueCraft.Client.Events; +using System.Collections; using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Graphics; using TrueCraft.Client.Rendering; using TrueCraft.Client.Input; -using Microsoft.Xna.Framework.Input; namespace TrueCraft.Client.Interface { - public class ChatInterface : IGameInterface + public class ChatInterface : Control { private static bool TryParseKey(Keys key, bool shift, out char value) { @@ -100,111 +100,37 @@ namespace TrueCraft.Client.Interface } } - public event EventHandler FocusChanged; + public bool HasFocus { get; set; } - private readonly object _syncLock = - new object(); - private bool _hasFocus; - - public bool HasFocus - { - get { return _hasFocus; } - private set - { - if (value != _hasFocus) - { - _hasFocus = value; - - var args = EventArgs.Empty; - if (FocusChanged != null) - FocusChanged(this, args); - } - } - } public MultiplayerClient Client { get; set; } public KeyboardComponent Keyboard { get; set; } public FontRenderer Font { get; set; } + private readonly object Lock = new object(); private string Input { get; set; } private List Messages { get; set; } + private Texture2D DummyTexture { get; set; } public ChatInterface(MultiplayerClient client, KeyboardComponent keyboard, FontRenderer font) { Client = client; Keyboard = keyboard; Font = font; + Input = string.Empty; - HasFocus = false; Messages = new List(); + DummyTexture = new Texture2D(keyboard.Game.GraphicsDevice, 1, 1); + DummyTexture.SetData(new Color[] { Color.White }); - keyboard.KeyUp += HandleKeyDown; - client.ChatMessage += HandleChatMessage; + Client.ChatMessage += OnChatMessage; + Keyboard.KeyDown += OnKeyDown; } - public void AddMessage(string message) + protected override void OnShow() { } + + protected override void OnUpdate(GameTime gameTime) { - lock (_syncLock) - { - Messages.Add(new ChatMessage(message)); - Console.WriteLine(message); - } - } - - private void HandleKeyDown(object sender, KeyboardKeyEventArgs e) - { - if (HasFocus) - { - if (e.Key == Keys.Enter) - { - HasFocus = false; - if (Input.Length != 0) - { - Client.SendMessage(Input); - Input = string.Empty; - } - return; - } - else if (e.Key == Keys.Back) - { - Input = Input.Substring(0, Input.Length - 1); - } - else if (e.Key == Keys.Escape) - { - HasFocus = false; - Input = string.Empty; - return; - } - - var shift = (Keyboard.State.IsKeyDown(Keys.LeftShift) || Keyboard.State.IsKeyDown(Keys.RightShift)); - var value = default(char); - - if (TryParseKey(e.Key, shift, out value)) - Input += new string(new char[] { value }); - } - else - { - switch (e.Key) - { - case Keys.T: - HasFocus = true; - break; - - case Keys.OemQuestion: - HasFocus = true; - Input += "/"; - break; - } - } - } - - void HandleChatMessage(object sender, ChatMessageEventArgs e) - { - AddMessage(e.Message); - } - - public void Update(GameTime gameTime) - { - lock (_syncLock) + lock (Lock) { for (int i = 0; i < Messages.Count; i++) { @@ -218,25 +144,78 @@ namespace TrueCraft.Client.Interface } } - public void DrawSprites(GameTime gameTime, SpriteBatch spriteBatch) + protected override void OnDrawSprites(GameTime gameTime, SpriteBatch spriteBatch) { - lock (_syncLock) + // UI scaling + var scale = GetScaleFactor(); + var xOrigin = (int)(10 * scale); + var yOffset = (int)(25 * scale); + var yOrigin = (int)(5 * scale) + (spriteBatch.GraphicsDevice.Viewport.Height - (yOffset * 7)); + + var color = Color.Lerp(Color.Transparent, Color.Black, 0.6f); + + lock (Lock) { + if ((Messages.Count == 0) && !HasFocus) return; + spriteBatch.Draw(DummyTexture, new Rectangle(xOrigin - 2, yOrigin - 2, (int)(600 * scale) + 4, (yOffset * 5) + 4), color); + + var total = 5; for (int i = (Messages.Count - 1); i >= 0; i--) { - if (Messages.Count == 0) - break; - - var invi = (Messages.Count - i); - var message = Messages[i]; - Font.DrawText(spriteBatch, 0, i * 30, message.Message); - if (invi >= 5) break; + total--; + + Font.DrawText(spriteBatch, xOrigin , yOrigin + (yOffset * total), message.Message, scale); + if (total == 0) break; + } + + if (HasFocus) + { + spriteBatch.Draw(DummyTexture, new Rectangle(xOrigin - 2, yOrigin + (yOffset * 5) + xOrigin - 2, (int)(600 * scale) + 4, yOffset + 4), color); + Font.DrawText(spriteBatch, xOrigin, yOrigin + (yOffset * 5) + xOrigin, "> " + Input, scale); } } + } + private void OnChatMessage(object sender, Events.ChatMessageEventArgs e) + { + AddMessage(e.Message); + } + + private void OnKeyDown(object sender, KeyboardKeyEventArgs e) + { if (HasFocus) - Font.DrawText(spriteBatch, 0, (6 * 30) + 15, "> " + Input); + { + if (e.Key == Keys.Back) + Input = Input.Substring(0, Input.Length - 1); + else + { + var shift = (Keyboard.State.IsKeyDown(Keys.LeftShift) || Keyboard.State.IsKeyDown(Keys.RightShift)); + var value = default(char); + + if (TryParseKey(e.Key, shift, out value)) + Input += new string(new char[] { value }); + } + } + else + { + if (Input != string.Empty) + { + Client.SendMessage(Input); + Input = string.Empty; + } + } + } + + protected override void OnHide() { } + + public void AddMessage(string message) + { + lock (Lock) + { + Messages.Add(new ChatMessage(message)); + Console.WriteLine(message); + } } } } \ No newline at end of file diff --git a/TrueCraft.Client/Interface/Control.cs b/TrueCraft.Client/Interface/Control.cs new file mode 100644 index 0000000..af3199b --- /dev/null +++ b/TrueCraft.Client/Interface/Control.cs @@ -0,0 +1,115 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace TrueCraft.Client.Interface +{ + ///

+ /// Abstract base class for uniformly-implemented game interfaces. + /// + public abstract class Control + : IGameInterface + { + private bool _isVisible; + + /// + /// Gets or sets whether the control is visible. + /// + public bool IsVisible + { + get { return _isVisible; } + set + { + if (_isVisible == value) + return; + + _isVisible = value; + if (_isVisible) OnShow(); + else OnHide(); + } + } + + /// + /// Gets or sets the scale for the control. + /// + public InterfaceScale Scale { get; set; } + + /// + /// Creates a new control. + /// + protected Control() { Scale = InterfaceScale.Medium; } + + /// + /// Shows the control. + /// + public void Show() { IsVisible = true; } + + /// + /// Hides the control. + /// + public void Hide() { IsVisible = false; } + + /// + /// Called when the control's visibility is set to true. + /// + protected abstract void OnShow(); + + /// + /// Called when the control is updated. + /// + /// + protected abstract void OnUpdate(GameTime gameTime); + + /// + /// Called when the control is drawn. + /// + /// + /// + protected abstract void OnDrawSprites(GameTime gameTime, SpriteBatch spriteBatch); + + /// + /// Called when the control's visibility is set to false. + /// + protected abstract void OnHide(); + + /// + /// Updates the control. + /// + /// + public void Update(GameTime gameTime) + { + OnUpdate(gameTime); + } + + /// + /// Draws the control. + /// + /// + /// + public virtual void DrawSprites(GameTime gameTime, SpriteBatch spriteBatch) + { + if (IsVisible) + OnDrawSprites(gameTime, spriteBatch); + } + + /// + /// Returns the preferred scale factor for the control. + /// + /// + protected float GetScaleFactor() + { + switch (Scale) + { + case InterfaceScale.Small: + return 0.75f; + + default: + case InterfaceScale.Medium: + return 1.0f; + + case InterfaceScale.Large: + return 1.25f; + } + } + } +} diff --git a/TrueCraft.Client/Interface/DebugInterface.cs b/TrueCraft.Client/Interface/DebugInterface.cs new file mode 100644 index 0000000..1255a2b --- /dev/null +++ b/TrueCraft.Client/Interface/DebugInterface.cs @@ -0,0 +1,56 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using TrueCraft.Client.Rendering; +using TrueCraft.Client.Input; + +namespace TrueCraft.Client.Interface +{ + public class DebugInterface : Control + { + public MultiplayerClient Client { get; set; } + public FontRenderer Font { get; set; } + + public int Vertices { private get; set; } + public int Chunks { private get; set; } + + public DebugInterface(MultiplayerClient client, FontRenderer font) + { + Client = client; + Font = font; + } + + protected override void OnShow() { } + + protected override void OnUpdate(GameTime gameTime) { } + + protected override void OnDrawSprites(GameTime gameTime, SpriteBatch spriteBatch) + { + // UI scaling + var scale = GetScaleFactor(); + var xOrigin = (int)(10 * scale); + var yOrigin = (int)(5 * scale); + var yOffset = (int)(25 * scale); + + var fps = (int)(1 / gameTime.ElapsedGameTime.TotalSeconds) + 1; + var position = Client.Position; + + Font.DrawText(spriteBatch, xOrigin, yOrigin, string.Format("§lRunning at {0} FPS", GetFPSColor(fps) + fps.ToString()), scale); + Font.DrawText(spriteBatch, xOrigin, yOrigin + (yOffset * 1), string.Format("§o{0} vertices", Vertices), scale); + Font.DrawText(spriteBatch, xOrigin, yOrigin + (yOffset * 2), string.Format("§o{0} chunks", Chunks), scale); + Font.DrawText(spriteBatch, xOrigin, yOrigin + (yOffset * 3), string.Format("§o<{0:N2}, {1:N2}, {2:N2}>", Client.Position.X, Client.Position.Y, Client.Position.Z), scale); + } + + protected override void OnHide() { } + + private string GetFPSColor(int fps) + { + if (fps <= 16) + return "§c"; + else if (fps <= 32) + return "§e"; + else + return "§a"; + } + } +} diff --git a/TrueCraft.Client/Interface/IGameInterface.cs b/TrueCraft.Client/Interface/IGameInterface.cs index 8f32498..27fb8a5 100644 --- a/TrueCraft.Client/Interface/IGameInterface.cs +++ b/TrueCraft.Client/Interface/IGameInterface.cs @@ -6,6 +6,8 @@ namespace TrueCraft.Client.Interface { public interface IGameInterface { + InterfaceScale Scale { get; set; } + void Update(GameTime gameTime); void DrawSprites(GameTime gameTime, SpriteBatch spriteBatch); } diff --git a/TrueCraft.Client/Interface/InterfaceScale.cs b/TrueCraft.Client/Interface/InterfaceScale.cs new file mode 100644 index 0000000..d33992c --- /dev/null +++ b/TrueCraft.Client/Interface/InterfaceScale.cs @@ -0,0 +1,13 @@ +using System; + +namespace TrueCraft.Client.Interface +{ + public enum InterfaceScale + { + Small = 0, + + Medium = 1, + + Large = 2 + } +} diff --git a/TrueCraft.Client/TrueCraft.Client.csproj b/TrueCraft.Client/TrueCraft.Client.csproj index 6cafb2f..aab8588 100644 --- a/TrueCraft.Client/TrueCraft.Client.csproj +++ b/TrueCraft.Client/TrueCraft.Client.csproj @@ -65,6 +65,9 @@ + + + @@ -142,6 +145,21 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -154,6 +172,15 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/TrueCraft.Client/TrueCraftGame.cs b/TrueCraft.Client/TrueCraftGame.cs index 3d8b684..e16b68e 100644 --- a/TrueCraft.Client/TrueCraftGame.cs +++ b/TrueCraft.Client/TrueCraftGame.cs @@ -23,7 +23,7 @@ namespace TrueCraft.Client private MultiplayerClient Client { get; set; } private GraphicsDeviceManager Graphics { get; set; } private List Interfaces { get; set; } - private FontRenderer DejaVu { get; set; } + private FontRenderer Pixel { get; set; } private SpriteBatch SpriteBatch { get; set; } private IPEndPoint EndPoint { get; set; } private ChunkRenderer ChunkConverter { get; set; } @@ -32,6 +32,7 @@ namespace TrueCraft.Client public ConcurrentBag PendingMainThreadActions { get; set; } private ConcurrentBag IncomingChunks { get; set; } public ChatInterface ChatInterface { get; set; } + public DebugInterface DebugInterface { get; set; } private RenderTarget2D RenderTarget; private BoundingFrustum CameraView; private Camera Camera; @@ -129,14 +130,17 @@ namespace TrueCraft.Client if (UserSettings.Local.SelectedTexturePack != TexturePack.Default.Name) TextureMapper.AddTexturePack(TexturePack.FromArchive(Path.Combine(TexturePack.TexturePackPath, UserSettings.Local.SelectedTexturePack))); - DejaVu = new FontRenderer( - new Font(Content, "Fonts/DejaVu", FontStyle.Regular), - new Font(Content, "Fonts/DejaVu", FontStyle.Bold), + Pixel = new FontRenderer( + new Font(Content, "Fonts/Pixel", FontStyle.Regular), + new Font(Content, "Fonts/Pixel", FontStyle.Bold), null, // No support for underlined or strikethrough yet. The FontRenderer will revert to using the regular font style. null, // (I don't think BMFont has those options?) - new Font(Content, "Fonts/DejaVu", FontStyle.Italic)); - Interfaces.Add(ChatInterface = new ChatInterface(Client, KeyboardComponent, DejaVu)); - ChatInterface.FocusChanged += ChatInterface_FocusChanged; + new Font(Content, "Fonts/Pixel", FontStyle.Italic)); + Interfaces.Add(ChatInterface = new ChatInterface(Client, KeyboardComponent, Pixel)); + Interfaces.Add(DebugInterface = new DebugInterface(Client, Pixel)); + + ChatInterface.IsVisible = true; + DebugInterface.IsVisible = true; OpaqueEffect = new BasicEffect(GraphicsDevice); OpaqueEffect.EnableDefaultLighting(); @@ -160,23 +164,6 @@ namespace TrueCraft.Client base.LoadContent(); } - private bool MouseCapturedBackup; - - void ChatInterface_FocusChanged(object sender, EventArgs e) - { - //if (ChatInterface.HasFocus) - //{ - // MouseCapturedBackup == MouseCaptured; - // MouseCaptured = false; - //} - - //MouseCapturedBackup = MouseCaptured; - - //if (MouseCaptured && ChatInterface.HasFocus) - // MouseCaptured = false; - //else - } - protected override void OnExiting(object sender, EventArgs args) { ChunkConverter.Stop(); @@ -188,14 +175,32 @@ namespace TrueCraft.Client // TODO: Rebindable keys // TODO: Horizontal terrain collisions - if (ChatInterface.HasFocus) - return; - switch (e.Key) { - // Quit the game. + // Close game (or chat). case Keys.Escape: - Exit(); + if (ChatInterface.HasFocus) + ChatInterface.HasFocus = false; + else + Exit(); + break; + + // Open chat window. + case Keys.T: + if (!ChatInterface.HasFocus) + ChatInterface.HasFocus = true; + break; + + // Open chat window. + case Keys.OemQuestion: + if (!ChatInterface.HasFocus) + ChatInterface.HasFocus = true; + break; + + // Close chat window. + case Keys.Enter: + if (ChatInterface.HasFocus) + ChatInterface.HasFocus = false; break; // Take a screenshot. @@ -203,27 +208,45 @@ namespace TrueCraft.Client TakeScreenshot(); break; + // Toggle debug view. + case Keys.F3: + DebugInterface.IsVisible = !DebugInterface.IsVisible; + break; + + // Change interface scale. + case Keys.F4: + foreach (var item in Interfaces) + { + item.Scale = (InterfaceScale)(item.Scale + 1); + if ((int)item.Scale > 2) item.Scale = InterfaceScale.Small; + } + break; + // Move to the left. case Keys.A: case Keys.Left: + if (ChatInterface.HasFocus) break; Delta += Microsoft.Xna.Framework.Vector3.Left; break; // Move to the right. case Keys.D: case Keys.Right: + if (ChatInterface.HasFocus) break; Delta += Microsoft.Xna.Framework.Vector3.Right; break; // Move forwards. case Keys.W: case Keys.Up: + if (ChatInterface.HasFocus) break; Delta += Microsoft.Xna.Framework.Vector3.Forward; break; // Move backwards. case Keys.S: case Keys.Down: + if (ChatInterface.HasFocus) break; Delta += Microsoft.Xna.Framework.Vector3.Backward; break; @@ -237,32 +260,33 @@ namespace TrueCraft.Client private void OnKeyboardKeyUp(object sender, KeyboardKeyEventArgs e) { - if (ChatInterface.HasFocus) - return; - switch (e.Key) { // Stop moving to the left. case Keys.A: case Keys.Left: + if (ChatInterface.HasFocus) break; Delta -= Microsoft.Xna.Framework.Vector3.Left; break; // Stop moving to the right. case Keys.D: case Keys.Right: + if (ChatInterface.HasFocus) break; Delta -= Microsoft.Xna.Framework.Vector3.Right; break; // Stop moving forwards. case Keys.W: case Keys.Up: + if (ChatInterface.HasFocus) break; Delta -= Microsoft.Xna.Framework.Vector3.Forward; break; // Stop moving backwards. case Keys.S: case Keys.Down: + if (ChatInterface.HasFocus) break; Delta -= Microsoft.Xna.Framework.Vector3.Backward; break; } @@ -412,15 +436,12 @@ namespace TrueCraft.Client } } + DebugInterface.Vertices = verticies; + DebugInterface.Chunks = chunks; + SpriteBatch.Begin(); for (int i = 0; i < Interfaces.Count; i++) - { Interfaces[i].DrawSprites(gameTime, SpriteBatch); - } - - int fps = (int)(1 / gameTime.ElapsedGameTime.TotalSeconds); - DejaVu.DrawText(SpriteBatch, 0, GraphicsDevice.Viewport.Height - 30, - string.Format("{0} FPS, {1} verticies, {2} chunks, {3}", fps + 1, verticies, chunks, Client.Position)); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null);