Js版游戏打砖块开发过程详细
最近对js的小游戏开发来了兴趣,前段时间由于回答度娘知道的提问写了个贪吃蛇,虽然难度不大并不复杂,感觉还挺有意思。感觉小时候玩过的什么俄罗斯方块,坦克大战什么的都可以试着用js实现下,这天来了兴致又想写一个,其实我小时候最喜欢玩的游戏就是打砖块了,当时五年级时在学校上微机课时总是在那偷偷玩打砖块还有个雪地的保龄球还有个潜艇在深海的游戏,都忘了名字了,玩儿的不亦乐乎。可能叫法不一样,就是下图这种,想必大家都玩儿过,这里就不废话了
了解需求
大家玩打砖块都是一关一关过的,每一关(这里就打算做一关)砖块码成一个图形保持不变,飞球起于挡板弹起按直线远动,不受重力约束,遇到墙壁则按反射角方向反弹。遇到砖块则砖块消失继续反弹,同时计分,下落回来时需控制下方的挡板左右移动去接住飞球,继续弹起,砖块被打完或者飞球没接住则游戏结束。再复杂点打掉砖块时偶尔还会有道具下落,用平台接住后道具作用生效。还有那个底部的挡板有点特殊,我记得小时候玩的时候如果球打在了挡板的左方,不管球从哪个方向飞回来的都会继续反弹回左方,越偏左反弹的越厉害,右边同理。游戏的运行需求大概就是这些。
这里用js去写的话我还真没写过,但可以试试,本文算是边写代码边记录博客,如果觉得废话太多可以直接看最后的完整代码。
开发思路
首先我想到的运行原理大概是砖块都是一个个的div,飞球是会移动的div,如果飞球的div与砖块的div有重合,则砖块消失即消除掉这个html元素,砖块的坐标,飞球的坐标应该都是用div的position设为absolute,控制left,top坐标来操作的。具体飞球的移动位置应该是用向量去计算。大概就是这个思路,感觉应该不是太难。不知道是否有更好的方法去实现,也查阅过一些其它人的代码,基本都是黑色一片,绿色注释一句没有,让人有点费解。干脆先自己做一个再说。
搭建模型
首先先做个不会动的模型出来,四壁,砖块,球,挡板,计分板,首先就是四壁,画个div,这里div的width,height取值上我是这样想,既然这个游戏按坐标去运行会涉及到很多的计算。长宽最好取个整数,而不是用百分数。当然不要设的太大,最好打开网页就能全部显示没有滚动条,这样方便玩。这里我设的是600*600居中显示。代码如下:
<body style="background-color:grey;">
<div align="center">
<div style="width:600px;height:600px;background-color:#BFEFFF;border:5px groove #87CEFA;position:relative;" id="mainDiv"> </div>
</div>
<body>
运行一下如下:
然后是砖块,就是一个个div用固定位置拼上去,但得先想好个形状。记得小时候玩的时候最大的乐趣就是努力让飞球能从一个缺口上去在上面自己飞行。想来想去大盖想到这么个形状:
上面是两个对称的三角形,中间是两个竖排,下面是大个的倒三角,有点笑脸的感觉,这样可以让玩者努力将飞球从笑脸的嘴角处飞上去,如果幸运点能探入两个竖排中间来回打击。再网上飞到眼镜处就不弄那么容易了,眼镜是向下斜坡的飞球不好在上面占时间太长,不管理论能不能实现就这样写吧,依旧使用了贪吃蛇的风格,用js去自己加载这些div.
这些div都是固定的,用left top来固定坐标。为了实现对称居中效果,四壁的宽是600,那左眼处的最上方第一个div中心距离应该是四分之一处,取150.至于砖块的长宽,我取的是width:28px;height:13px;因为左右上下我都加了1px做缝隙,这样可以让每个砖块能独立出来显示分明,有人说给每个div加上border不用行了么。这里我试了有的浏览器默认border算在宽度里,即加了border宽度还是28,有的浏览器加了border则宽度变为了30.所有这里就不用border了。这样加上缝隙的话每个砖块站位刚好为整数30*15;每下一层比上一层多一个。第一层的左侧距离左壁是150 - (30/2)等于145,每下一层靠近左侧15。到第九层时靠左侧10.刚好留了个空隙。下面的排列基本都是边写变推算。不再傲述。
画完砖块再画两个div,一个挡板,一个飞球。均居中底部显示,还有一个计分板放最上面居中,坐标left,top可以自己算出代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
<style>
#mainDiv div{
width:28px;height:13px;background-color:blue;position:absolute;
}
</style>
<script>
var $ = function (id) {//方便按id提取
return document.getElementById(id);
};
window.onload=function(){
var x =150;var y = 15;
var m = $("mainDiv"); for(var i=1;i<=9;i++){ for(var j=0;j<i;j++){//左眼媚
var di = document.createElement("div");
di.style.top = y+(i-1)*15;//每列向下移动一行
di.style.left= x-i*15+j*30;//每列向左移动15,同行的每一个向右移动一个div宽度30
m.appendChild(di);//即i控制列的换行,j控制每行的输出这里写了个x,y其实就是从上向下画图时的起点,下面加150,加450等其实是换位置画图的意思,完全可以直接用算好的数字而不用x,y。只为清楚计算过程
//右眼媚
var di1 = document.createElement("div");
di1.style.top = y+(i-1)*15;
di1.style.left= x+300-i*15+j*30;
m.appendChild(di1);
} } for(var i=1;i<=10;i++){//左眼眼睛处不用j去控制每行,因为每行的个数位置是一样的
var di = document.createElement("div");
di.style.top = y+150+(i-1)*15;
di.style.left= x-15;
m.appendChild(di);
//右眼
var di1 = document.createElement("div");
di1.style.top = y+150+(i-1)*15;
di1.style.left= x-15+300;
m.appendChild(di1);
} for(var i=1;i<=10;i++){//大嘴
for(var j=0;j<i*2-1;j++){
var di = document.createElement("div");
di.style.top = y+450-(i-1)*15;
di.style.left= x+165-i*30+j*30;
m.appendChild(di);
}
}
}
</script>
</head>
<body style="background-color:grey;">
<div align="center">
<div style="width:600px;height:600px;background-color:#BFEFFF;border:5px groove #87CEFA;position:relative;" id="mainDiv">
<div id="markDiv" style="width:60px;height:25px;top:0;left:270;border:1px dotted blue;background-color:#BFEFFF"></div>
<div id="qiuDiv" style="width:10px;height:10px;top:580;left:295;background-color:red;"></div>
<div id="bangDiv" style="width:150px;height:10px;bottom:1;left:225;background-color:black;"></div>
</div>
</div>
<body>
运行结果如下
火狐,IE,谷歌,360,显示结果基本一样。如果大家有更好的图形画法可以自己设计。
加入控制
游戏开始前是可以先找个好位置出击的,即飞球飞起前可以随挡板左右移动,就先做个左右的移动。这里就用在body上加键盘监听事件了。用左右箭头控制好了。同时还得有一个boolean值来确定当前游戏是否已经开始,如果已经开始了飞球就不要随挡板移动了,代码如下:
var bangleft = 225;//取挡板当前的左坐标,就是left距离
var qiuleft = 295;//取飞球当前的左坐标
var bs = 10;//按一次键移动多少,
var kflag = false;//标记游戏是否已经开始
//键盘处理事件
function keydownEvent(event){
var bang = $("bangDiv");//取挡板div
var qiu = $("qiuDiv");//取飞球的div
if(event.keyCode==37){//如果是左箭头
for(var i = 0;i<bs;i++){
if(bangleft-1!=0){//0即left为0,即已经到左移动到了墙壁,就不再起作用。
bangleft-=1;//每一次向左移动1,其实上面做了for循环,结果就是每按一次向左移动了bs=10,为什么要循环着去加而不一次性去加,原因很简单就是为了防止一次就加过了超出了范围,同时我们可以通过设定bs参数的值来改变挡板移动的快慢
bang.style.left = bangleft+"px";//改变挡板位置
if(!kflag){//如果游戏没开始
qiuleft-=1;
qiu.style.left = qiuleft+"px";//改变飞球位置
}
}
}
}
if(event.keyCode==39){//如果是右箭头同理
for(var i = 0;i<bs;i++){
if(bangleft+1!=450){//检测是否碰右壁
bangleft+=1;
bang.style.left = bangleft+"px";
if(!kflag){
qiuleft+=1;
qiu.style.left = qiuleft+"px";
}
}
}
} }
body要加上<body style="background-color:grey;" onkeydown="keydownEvent(event)">
飞球的运行
然后先不考虑打砖块,先让飞球可以飞起来,无视砖块自由在四壁内运动,这里还有一点我们应该都知道,小时候玩的时候飞球飞起时并不是直线飞起的,总是偏左或偏右那么一点,因为如果设定直线向上的话挡板也保持不动,游戏开始后飞球就回一直来回上下做运动。
先不管角度问题,先想怎么移动,这里要复习一下中学的课程了看下图:
假设球在x轴y轴的(0,0)为起点,以α角移动,假设每个单位时间内移动了s(速度).就是图中的斜线距离。到了坐标(x1,y1).那已知s的值和α的值就可求出移动的距离x1,y1。赋值给球的坐标做为新坐标,球就移动了,这样我们用setTimeout函数不断去调用这个方法球就可以以直线自己前进了。也先不考虑撞不撞强,假设α=30度,s=1;那单位时间内飞球的新坐标就是(s/sin30,s/cos30)如果忘了正弦余弦的用法可以去百度,我确实忘了。。所以飞球按30度角直线运行的方法就是如下代码:
var qx = 295;//飞球初始坐标left
var qy = 580;//飞球初始坐标top
function go(){
var qiu = $("qiuDiv");
qx = qx +1*Math.cos((2*Math.PI/360)*30);
qy = qy -1*Math.sin((2*Math.PI/360)*30);
qiu.style.left = qx+"px";
qiu.style.top = qy+"px"; setTimeout("go()",10)
}
这里要说明js里cos,sin的用法,Math.sin(x) 表示的是x 的正弦值。Math.cos(x) 是 x 的余弦值。但js里的这个x是弧度而不是角度,假设角度是α,转化为弧度就是
2*Math.PI/360*α我们这里假设的是α=30度。直角三角形里知道一个锐角α和斜边长s=1,求α的对边y1的长就是s*sin(α)在此例中即为
1*Math.sin((2*Math.PI/360)*30);
求a的邻边x1就是cos....同理
由于我们现在假想的是左上飞,所以是x取加值,y取减。然后循环调用go(),10是间隔时间,即0.01秒。s=1相当于限制了每次移动的位移,如果s设的过大,则球会变快而且平滑效果很差几乎是瞬移,所以是s设的小,然后让间隔时间变短,这样平滑效果好点,大家可以自己更改调试。现在大概飞行的原理知道。然后就考虑撞墙了。
一开始我钻了牛角尖(此段为本人的一段傻瓜笨蛋推理,容易严重误导人,不愿看的可以直接看下面的红字‘最终其实原理是这样的’),总是考虑要是碰的是左壁,或者右壁,去区分这些,然后去改变角度什么的,后来一些如果详细区分的话后面还要考虑砖块,那就要去考虑碰的是砖块的上下左右,太麻烦了,就好像那个故事有个皇帝要在每条街铺上地毯防止脚踩伤,而大臣建议何不让脚去穿个鞋呢,忘了故事大概了就是这样。我们应该考虑的是这个飞球是上下左右哪个边碰壁了。这样需要考虑的就少了。
如何判断碰壁呢,这里不考虑砖块的情况下很简单。就是去计算坐标罢了。那角度是怎么改变的呢,原理那提到是反射角,飞球的右边如下图:
后来我又继续画图上边碰壁右边碰壁画完我发现
最终其实原理是这样的其实折腾来折腾去这里都是四方形,α的值是不会变的,角度的改变都是在围绕α在做文章。同样单位时间内的移动距离s也是不会变的,x方向y方向的移动距离的绝对值也是不会边的,其实撞墙就是改变x,或y位移的正负而已,至于角度我们没必要去考虑。添加代码如下:
var qx = 295;//飞球初始坐标left
var qy = 580;//飞球初始坐标top
var jiao = 89;//初始飞行角度
var zx = 1;//控制left位移的正负
var zy = -1;//控制top位移的正负
var rp = null;//控制游戏进程
function go(){
var qiu = $("qiuDiv"); qx = qx +zx*Math.cos((2*Math.PI/360)*30);
qy = qy +zy*Math.sin((2*Math.PI/360)*30);
qiu.style.left = qx+"px";
qiu.style.top = qy+"px";
if(qy>=580){
//alert(qx)
//alert(qx<bangleft||qx>bangleft+150)
if(qx<bangleft||qx>bangleft+150){//判断是否接住
clearTimeout(rp);
}else{
zy=-1;
rp = setTimeout("go()",1);
}
}else{
if(qx>=600)zx=-1;
if(qx<=0)zx=1;
if(qy<=0)zy=1;
rp = setTimeout("go()",1);
}
}
判断与砖块碰撞
这样基本实现了接球并移动。但不管怎么接球都是按原来的角度走的,运行起来球是一直走一条轨道。这里就用到开始需求那里说的。
如果球打在了挡板的左方,不管球从哪个方向飞回来的都会继续反弹回左方,越偏左反弹的越厉害,右边同理。而且碰到砖块虽然不会改变虽然α没变都轨迹会变。这里要解决两个问题了。一个是改变角度,一个是碰撞砖块。貌似后一个更难点,但刚写完撞墙顺思路可以继续想如何判断撞砖块。
我又一次想到了数组。就是生成砖块的同时把每个砖块放入数组中去,然后飞球每移动就与所有砖块进行比较是否碰撞。则开始的加载代码改为:
var zdivs = new Array();//用于存储所有的砖块。 window.onload=function(){
var x =150;var y = 15;
var m = $("mainDiv"); for(var i=1;i<=9;i++){ for(var j=0;j<i;j++){
var di = document.createElement("div");
di.style.top = y+(i-1)*15;
di.style.left= x-i*15+j*30;
m.appendChild(di); var di1 = document.createElement("div");
di1.style.top = y+(i-1)*15;
di1.style.left= x+300-i*15+j*30;
m.appendChild(di1); zdivs[zdivs.length]=di;
zdivs[zdivs.length]=di1;
} } for(var i=1;i<=10;i++){
var di = document.createElement("div");
di.style.top = y+150+(i-1)*15;
di.style.left= x-15;
m.appendChild(di); var di1 = document.createElement("div");
di1.style.top = y+150+(i-1)*15;
di1.style.left= x-15+300;
m.appendChild(di1); zdivs[zdivs.length]=di;
zdivs[zdivs.length]=di1;
} for(var i=1;i<=9;i++){
for(var j=0;j<i*2;j++){
var di = document.createElement("div");
di.style.top = y+450-(i-1)*15;
di.style.left= x+150-i*30+j*30;
m.appendChild(di); zdivs[zdivs.length]=di;
}
} }
然后在飞球移动的js后面加上循环判断,如果相碰则将此砖块在数组中移除同时设置display为none;然后难点就是如何判断飞球与某一个div相碰,相碰又是以何种方式反弹。想想就这几种情况,飞球的右边与砖块左边碰,或者下边与砖块上边碰等等
判断两个div是否相碰,即有重合点的方法其实是数学上判断两个矩形是否重叠。
假设两个矩形的位置如图,两个矩形a和b,分别有4个边,ax1是左边的x坐标,ay1是上班的y坐标,ax2是右边的x坐标,。。。。。我们取a,b的同侧边最大的那一边组成的新坐标sx,sy,如果这个坐标同时存在与两个矩形内就说明两个矩形重合。即ax1与bx1比较取最大的bx1,ay1与by1取最大的by1。因为这里是用的top,left所以越靠左left越大,越靠下top越大。这个的具体道理就不好说了,好好看几何吧。
相碰的问题解决了,那飞球是从哪侧碰撞的呢?该反弹回哪边?这里我的思路是飞球a,砖块b,可能的撞击方式是a左碰b右,a右碰b左,a上碰b下,a下碰b上四种,这里暂不考虑角碰角原路返回。按四种情况的话a左碰b右的话,a左与b右的left差值,与后面三个a右b左的left差值,a上b下的top差值,a下b上的top差值,这四个差值的绝对值应该是哪个最小判定为是哪种情况相撞。个人是这么理解,如有异议欢迎提出。所以知道了是那种情况的碰撞,也就明白了该如何去改变方向即zx,zy的值。
然后有了思路则飞球每走一步就去与数组里的div遍历去对比是否相碰。继续写在上面top<=580后面
function go(){
var qiu = $("qiuDiv"); qx = qx +zx*Math.cos((2*Math.PI/360)*jiao);
qy = qy +zy*Math.sin((2*Math.PI/360)*jiao); if(qy>=580){
if(qx<bangleft||qx>bangleft+150){//判断是否接住
clearTimeout(rp);
}else{
zy=-1;
rp = setTimeout("go()",1);
}
}else{
for(var i=0;i<zdivs.length;i++){
var io = checkIsP(qx,qy,zdivs[i].offsetLeft,zdivs[i].offsetTop);
if(io!=0){
zdivs[i].style.display = "none";
zdivs.splice(i,1);
if(io==1){
zx=1;
}
if(io==2){
zx=-1;
}
if(io==3){
zy=1;
}
if(io==4){
zy=-1;
}
break;
}
} if(qx>=600)zx=-1;
if(qx<=0)zx=1;
if(qy<=0)zy=1;
qiu.style.left = qx+"px";
qiu.style.top = qy+"px";
rp = setTimeout("go()",1);
}
}
function checkIsP(qx,qy,zx,zy){
var f = {
x:qx,
y:qy,
x1:qx+10,
y1:qy+10
}
var z = {
x:zx,
y:zy,
x1:zx+30,
y1:zy+15
}
var sx;var sy;
sx = f.x>=z.x?f.x:z.x;
sy = f.y>=z.y?f.y:z.y;
if(sx >= f.x && sx <= f.x1 && sy >= f.y && sy <= f.y1 && sx >= z.x && sx <= z.x1 && sy >= z.y && sy <= z.y1){ return seSmall(Math.abs(f.x-z.x1),Math.abs(f.x1-z.x),Math.abs(f.y-z.y1),Math.abs(f.y1-z.y)); }else{
return 0;
}
} function seSmall(a,b,c,d){ if(a<b&&a<c&&a<d){
return 1;
}
if(b<a&&b<c&&b<d){
return 2;
}
if(c<a&&c<b&&c<d){
return 3;
}
if(d<b&&d<c&&d<a){
return 4;
}
}
这样碰撞问题基本解决了
更改角度
开篇还提到要按挡板的接球位置来更改反弹的角度。其实这个想想就简单,就按接触挡板时的距离对角度做百分比就行了与挡板接触处代码改为如下
if(qy>=580){
if(qx<bangleft||qx>bangleft+150){//判断是否接住
clearTimeout(rp);
}else{
zy=-1;
if((qx-bangleft)>(75)){
jiao = 90-(qx-bangleft+10-75)/75*90;
zx = 1;
}else{
jiao = 90 - (75-(qx-bangleft+10))/75*90;
zx=-1;
}
rp = setTimeout("go()",1);
}
基本这个游戏就完成了,感觉还是设计的挺烂的,每次移动都耗那么多计算,其实在挡板与最下层砖块间的空白可以省去不用计算,因为这一空间根本没砖块,所有在计算for循环前加上
else{if(qy<=480)
for(var i=0;i<zdivs.length;i++){
还有一点也可以优化下,就是砖块都是一行一行排列的。所有可以对砖块进行按行分组。当飞球飞到此行的高度时只对比此行的砖块,还有积分模块也不是很难,这里就不再写了,太长了。源代码见上文,算是抛砖引玉。
Js版游戏打砖块开发过程详细的更多相关文章
- 原生js写的贪吃蛇网页版游戏特效
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- js版九宫格拼图与启发式搜索(A*算法)
九宫格拼图游戏大家都很熟悉,这里给大家如介绍何应用状态空间搜索的方式求解拼图的最佳路径和一个游戏dome及自动求解方法: 本文分web版游戏的实现和启发式搜索算法两部分: 先看dome,直接鼠标点击要 ...
- PureMVC(JS版)源码解析:总结
PureMVC源码中设计到的11个类已经全部解析完了,回首想想,花了一周的时间做的这点事情还是挺值得的,自己的文字组织表达能力和对pureMVC的理解也在写博客的过程中得到了些提升.我也是第一次写系列 ...
- PureMVC(JS版)源码解析
PureMVC(JS版)源码解析:总结 PureMVC源码中设计到的11个类已经全部解析完了,回首想想,花了一周的时间做的这点事情还是挺值得的,自己的文字组织表达能力和对pureMVC的理解也在写 ...
- Javascript版-显示相应图片的详细信息
Hi All, 分享一个通过JS来显示相应图片的详细信息. 需求:进入页面时,动态加载图片信息:当鼠标移动到某一图片上时,则显示该图片的大图片并显示相应说明信息:当鼠标移开图片时,清除新创建的元素. ...
- js版贪吃蛇
之前没有写博客的习惯,这是我的第一个博客,有些的不好的地方,希望大家多多提意见 js版的贪吃蛇相对比较简单,废话不多说直接上代码,有需要注意的地方我会标红,github源码地址https://gith ...
- Twitter面试题蓄水池蓄水量算法(原创 JS版,以后可能会补上C#的)
之前在群里有人讨论Twitter的面试题,蓄水池蓄水量计算,于是自己写了个JS版的(PS:主要后台代码还要编译,想想还是JS快,于是就使用了JS了.不过算法主要还是思路嘛,而且JS应该都没问题吧^_^ ...
- 【干货】JS版汉字与拼音互转终极方案,附简单的JS拼音输入法
前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...
随机推荐
- 我的Python成长之路---GitHub使用克隆GitHub(SSH key配置)
六.克隆GitHub仓库 1.创建仓库目录,目录位置没有要求,比如D:\learngit. 2.配置ssh(如果不配置会每次都输入用户名和密码) 使用TortoiseGit生成ssh-key:开始菜单 ...
- HDU SPFA算法 Invitation Cards
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1535 分析: 题意:求1点到其它点的最短距离之和+其它点到1点的最短距离之和 前面一部分直接用SPFA ...
- 作业还是作孽?——Leo鉴书79
中国孩子,尤其是城市孩子课业过重是个不争的事实.儿子上幼儿园的作业已经能做到8点多了,上小学之后不知道是不是会整得更晚.于是入手这本<家庭作业的迷思>,认真读读.请特别注意,不要买书叫&q ...
- 通过sharedpreference两个程序共享数据
一.整体工程图 二.SharePreferenceWriteActivity.java package org.ourunix.android.sharepreferencewrite; i ...
- Winform TabControl控件使用
运行效果: 代码: /// <summary> /// 添加选项卡 /// </summary> /// <param name="sender"&g ...
- c++ 重载,覆盖,重定义
写的不是很明白,后来又重新整理过了,在: http://www.cnblogs.com/iois/p/4986790.html 函数重载(Function Overloading) C++允许同一范围 ...
- C语言,链表反转
倒序思路:依次把后面的节点移往头部. struct Node{ struct Node* next; int data; }; typedef struct Node NODE; NODE* inve ...
- AES加密时抛出java.security.InvalidKeyException: Illegal key size or def
原文:AES加密时抛出java.security.InvalidKeyException: Illegal key size or def 使用AES加密时,当密钥大于128时,代码会抛出 java. ...
- Spring Thread Pool 线程池的应用
Spring and Java Thread example 扫扫关注"茶爸爸"微信公众号 坚持最初的执着,从不曾有半点懈怠,为优秀而努力,为证明自己而活. Download it ...
- Cocos2d-X游戏开发之Windows7+VS2010环境搭建(亲测)
Cocos2d—X游戏引擎,提供Mac系统下的Xcode开发和Windows系统的VS开发,应该是比较常用的2种. 使用Mac以后,就会发现使用Xcode开发实在是福分啊.VS开发步骤繁琐,调试效率低 ...