从一个云服务器到一款十年后的游戏之第一年
背景
累觉不爱,追求流浪,只信猫咪与游戏。与QQ三国结缘多年,却因为对物理的愧疚大学没有读计算机而选了物理系。因此丢失了几年对QQ三国未来发展的憧憬,没事,我们还有青春去幻想去设计去定义这游戏的未来,希望多年之后,游戏未倒,焕发二春,又有怀着梦想的少年进入了这个有爱的三国世界。我有满腔对这游戏未来发展的热情,希望十年后该游戏的策划组愿意倾听。
十年计划
在你好棒棒啊的腾讯云服务器(参赛就是来拿优惠券续费的,这个广告应打)建设一个帮助某游戏新玩家快速熟悉游戏,让老玩家重新热爱起游戏的社区网站QQ三国爱。
开发与该游戏相关的在线攻略功能,运营网站期间收集玩家们的偏好、问题、建议、如何良好体验游戏等。
学习怎么制作游戏,从一个玩家体验友好的角度来策划新游戏。
开发一个个实现小功能的框架,最终整合成自己的游戏引擎。
做一款页游版本的游戏,把策划和源码送到QQ三国工作室,也许其中某个观点和建议可以被接纳,被相信这游戏还有未来,告诉策划组我爱QQ三国,谢谢它陪我度过的青春,希望你们别放弃这游戏,我们选择相信在等着。
接入服务器
不想说搭建的细节,因为老手不需要教,而新手让自己去摸索会更有趣,毕竟腾讯云管理中心的指引后详细了,简单说下会遇到的一些问题,新手遇到时可以查看。
问题基于的环境:IIS、windows、php
遇到json、jpeg等“新”扩展名文件,无法访问,去添加mime类型。
某非关键进程cpu利用率太大,但不确定是否可以关闭,而且是系统程序无法删除,去强行限制该帐号的权限。
网站随着访问数量增多,崩溃概率增大,排查后发现问题只可能在云服务器上,去设置IIS应用池回收时间,在更短周期内回收。
从一开始就养成用绝对路径的习惯,以后代码就可以少修改。
定期访问云主机检查有无中毒或异常进程。
网站设置单入口,权限页面可设置session,避免被非法访问。
多思考运用或不运用缓存。
网站设计
背景
不知从哪一年起,大概是最高等级开放到100+开始吧,享受玩三国乐趣的玩家,要么就是已经坚持很多年了的,所以有一定装备和等级基础,要么就是冲堆钱进来的。而达不到这两个要求的新玩家,甚至这几年挂机的老玩家,都跟不上一直新出的副本、道具、市场等,打开官网,又发现官网的资料一直停滞不前,论坛和三国吧的精品资料不错,可惜好帖很容易匿贴,新手也不知道该怎么搜索出想要的资料。
因为对三国九年的热爱,想搭个三国非官方玩家交流平台,帮助新手玩家去快速上手和融入三国这个可爱的世界中。
整体框架
部分功能展示
分别选取一个前端、后台和游戏例子。
副职产品计算器
网站上线后最受欢迎的单页面,利用ag的数据双向绑定计算副职产品成本和利润。
物品交易平台
访客查看发布+访客发布(图一)+统计搜索记录(图二)+后台管理(图三)
实现关键:
获取用户当前搜索所在的大区、物品类型,合理用好该游戏的特色分类。
拼图游戏
模拟客户端该游戏,帮助不熟悉的玩家训练出游戏技巧。
源码(另需引入jq和bootcss):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
*{ padding: 0; margin: 0; } #main{ width: 900px; margin: auto; } #twoboxes{ position: relative; } .box{ width: 420px; height: 420px; position: relative; float : left; margin-left: 30px; } .msg{ width: 420px; margin: auto; position: absolute; } #leftmsg{ top:420px; left: 30px; } #rightmsg{ top:420px; left: 480px; } .each{ position: absolute; border: 2px solid gray; /*background: url(images/1.jpg);*/ } #emptyl,#emptyr{ background: gray; z-index: 10; } #rule{ width: 500px; margin: auto; }
$(function(){ $( "#ruletoggle" ).click(function(){ $( "#rule" ).toggle(); }); }); var stepsl=0; var stepsr=0; var isl=0; var isr=0; var secsObj= new Date(); var secs=secsObj.getTime(); var sort= "" ; function calc(size){ //清空元素,还有计时器,名次 $( "#rule" ).hide(); stepsl=0; stepsr=0; isl=0; isr=0; $( "#leftbox" ).empty(); $( "#rightbox" ).empty(); $( "#leftmsg p" ).empty(); $( "#rightmsg p" ).empty(); sort= "" ; //size取值:3,4,5 //正方形的长宽后缀用大写X,count var picName=(Math.floor(Math.random()*16)+1)+ ".jpg" ; var X=420/size; var count=size*size; var boxArray=[]; for (var i=0;i boxArray.push(i); } //记录初始顺序,之后判断是否胜利 //循环,格子越多,交换次数越多,得到交换后的一个数组 var times=0; while (times<(size*4)){ var i=times%(count-1)+1; var randNum=Math.floor(Math.random()*(count-1))+1; if (randNum!=i){ var tempArray=boxArray[i-1]; boxArray[i-1]= boxArray[randNum-1]; boxArray[randNum-1]=tempArray; times++; } } sort=boxArray.join( "" ); //创建格子元素,左盒子的id是数字+l,右是数字+r for (var j=0;j var tempL=$( ' ); tempL.attr({ "numTop" :Math.floor(j/size), "numLeft" :Math.floor(j%size) }); var eachTop=Math.floor(j/size)*X; var eachLeft=Math.floor(j%size)*X; var eachY=Math.floor((boxArray[j])/size)*X; var eachX=Math.floor((boxArray[j])%size)*X; // console.log(j,obj[j],eachTop,eachLeft); tempL.css({ width:X+ "px" , height:X+ "px" , top:eachTop+ "px" , left:eachLeft+ "px" , backgroundPositionX:-eachX+ "px" , backgroundPositionY:-eachY+ "px" }); $( "#leftbox" ).append(tempL); } var tempEmptyL=$( '' ); tempEmptyL.attr({ "numTop" :size-1, "numLeft" :size-1 }); tempEmptyL.css({ width:X+ "px" , height:X+ "px" , top:X*(size-1)+ "px" , left:X*(size-1)+ "px" , }); $( "#leftbox" ).append(tempEmptyL); for (var j=0;j var tempR=$( ' ); tempR.attr({ "numTop" :Math.floor(j/size), "numLeft" :Math.floor(j%size) }); var eachTop=Math.floor(j/size)*X; var eachLeft=Math.floor(j%size)*X; var eachY=Math.floor((boxArray[j])/size)*X; var eachX=Math.floor((boxArray[j])%size)*X; // console.log(j,obj[j],eachTop,eachLeft); tempR.css({ width:X+ "px" , height:X+ "px" , top:eachTop+ "px" , left:eachLeft+ "px" , backgroundPositionX:-eachX+ "px" , backgroundPositionY:-eachY+ "px" }); $( "#rightbox" ).append(tempR); } var tempEmptyR=$( '' ); tempEmptyR.attr({ "numTop" :size-1, "numLeft" :size-1 }); tempEmptyR.css({ width:X+ "px" , height:X+ "px" , top:X*(size-1)+ "px" , left:X*(size-1)+ "px" , }); $( "#rightbox" ).append(tempEmptyR); //计时器 secsObj= new Date(); secs=secsObj.getTime(); //捕获键盘按下事件 document.onkeyup = function ( event ) { var e = event || window. event ; var keyCode = e.keyCode || e.which; var el=$( "#emptyl" ); var elTop=parseInt(el.attr( "numTop" )); var elLeft=parseInt(el.attr( "numLeft" )); var er=$( "#emptyr" ); var erTop=parseInt(er.attr( "numTop" )); var erLeft=parseInt(er.attr( "numLeft" )); switch (keyCode) { case 37: // console.log("左"); if (erLeft var changeId=erTop*size+erLeft+1; var changeObj=$( "#" +changeId+ "r" ); changeObj.css( "left" ,erLeft*X+ "px" ); changeObj.attr( "numLeft" ,erLeft); changeObj.attr( "id" ,erTop*size+erLeft+ "r" ); er.css( "left" ,(erLeft+1)*X+ "px" ); er.attr( "numLeft" ,erLeft+1); isWinr(size); } break ; case 38: // console.log("上"); if (erTop var changeId=(erTop+1)*size+erLeft; var changeObj=$( "#" +changeId+ "r" ); changeObj.css( "top" ,erTop*X+ "px" ); changeObj.attr( "numTop" ,erTop); changeObj.attr( "id" ,erTop*size+erLeft+ "r" ); er.css( "top" ,(erTop+1)*X+ "px" ); er.attr( "numTop" ,erTop+1); isWinr(size); } break ; case 39: // console.log("右"); if (erLeft>0){ var changeId=erTop*size+erLeft-1; var changeObj=$( "#" +changeId+ "r" ); changeObj.css( "left" ,erLeft*X+ "px" ); changeObj.attr( "numLeft" ,erLeft); changeObj.attr( "id" ,erTop*size+erLeft+ "r" ); er.css( "left" ,(erLeft-1)*X+ "px" ); er.attr( "numLeft" ,erLeft-1); isWinr(size); } break ; case 40: // console.log("下"); if (erTop>0){ var changeId=(erTop-1)*size+erLeft; var changeObj=$( "#" +changeId+ "r" ); changeObj.css( "top" ,erTop*X+ "px" ); changeObj.attr( "numTop" ,erTop); changeObj.attr( "id" ,erTop*size+erLeft+ "r" ); er.css( "top" ,(erTop-1)*X+ "px" ); er.attr( "numTop" ,erTop-1); isWinr(size); } break ; case 65: // console.log("a"); if (elLeft var changeId=elTop*size+elLeft+1; var changeObj=$( "#" +changeId+ "l" ); changeObj.css( "left" ,elLeft*X+ "px" ); changeObj.attr( "numLeft" ,elLeft); changeObj.attr( "id" ,elTop*size+elLeft+ "l" ); el.css( "left" ,(elLeft+1)*X+ "px" ); el.attr( "numLeft" ,elLeft+1); isWinl(size); } break ; case 87: // console.log("w"); if (elTop var changeId=(elTop+1)*size+elLeft; var changeObj=$( "#" +changeId+ "l" ); changeObj.css( "top" ,elTop*X+ "px" ); changeObj.attr( "numTop" ,elTop); changeObj.attr( "id" ,elTop*size+elLeft+ "l" ); el.css( "top" ,(elTop+1)*X+ "px" ); el.attr( "numTop" ,elTop+1); isWinl(size); } break ; case 68: // console.log("d"); if (elLeft>0){ var changeId=elTop*size+elLeft-1; var changeObj=$( "#" +changeId+ "l" ); changeObj.css( "left" ,elLeft*X+ "px" ); changeObj.attr( "numLeft" ,elLeft); changeObj.attr( "id" ,elTop*size+elLeft+ "l" ); el.css( "left" ,(elLeft-1)*X+ "px" ); el.attr( "numLeft" ,elLeft-1); isWinl(size); } break ; case 83: // console.log("s"); if (elTop>0){ var changeId=(elTop-1)*size+elLeft; var changeObj=$( "#" +changeId+ "l" ); changeObj.css( "top" ,elTop*X+ "px" ); changeObj.attr( "numTop" ,elTop); changeObj.attr( "id" ,elTop*size+elLeft+ "l" ); el.css( "top" ,(elTop-1)*X+ "px" ); el.attr( "numTop" ,elTop-1); isWinl(size); } break ; default : break ; } } }; function isWinl(size){ stepsl++; var sort2=[]; for (var i=0;i sort2.push(parseInt($( "#leftbox .each:eq(" +i+ ")" ).attr( "id" ))); } var sort3=sort2.join( "" ); sort3+=size*size-1; if (sort3==sort){ var secsObj2= new Date(); var secs2=secsObj2.getTime(); if (isr==0&&isl==0){ $( "#leftmsg p" ).html( "恭喜你第一名!通过" +(secs2-secs)/1000+ "秒," +stepsl+ "步完成!" ); } else if (isr==1&&isl==0){ $( "#leftmsg p" ).html( "恭喜你第二名!通过" +(secs2-secs)/1000+ "秒," +stepsl+ "步完成!" ); } isl=1; } } function isWinr(size){ stepsr++; var sort2=[]; for (var i=0;i sort2.push(parseInt($( "#rightbox .each:eq(" +i+ ")" ).attr( "id" ))); } var sort3=sort2.join( "" ); sort3+=size*size-1; if (sort3==sort){ var secsObj2= new Date(); var secs2=secsObj2.getTime(); if (isl==0&&isr==0){ $( "#rightmsg p" ).html( "恭喜你第一名!通过" +(secs2-secs)/1000+ "秒," +stepsr+ "步完成!" ); } else if (isl==1&&isr==0){ $( "#rightmsg p" ).html( "恭喜你第二名!通过" +(secs2-secs)/1000+ "秒," +stepsr+ "步完成!" ); } isr=1; } }
|