chapter12 实验手册.docx
- 文档编号:26682877
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:74
- 大小:107.15KB
chapter12 实验手册.docx
《chapter12 实验手册.docx》由会员分享,可在线阅读,更多相关《chapter12 实验手册.docx(74页珍藏版)》请在冰豆网上搜索。
chapter12实验手册
第12章网络游戏编程
网络坦克大战
客户端的实现
(一)准备工作:
1.新建cocos2d-x项目
2.游戏资源从光盘拷贝到Resources目录下
3.将ODSocket加入到Classes下并在VS工程中添加这些已有项,结构如图:
4.将HelloWorld场景相关的头文件和cpp文件删除,同时把对这个场景的所有引用删除
(二)编写全局常量配置文件Global.h,方便常用数值的访问
#ifndef__GLOBAL_H__
#define__GLOBAL_H__
#defineWINDOWHEIGHTDirector:
:
getInstance()->getVisibleSize().height
#defineWINDOWWIDTHDirector:
:
getInstance()->getVisibleSize().width
#endif
(三)实体类的封装
实体类的继承关系如下图:
(1)实体类基类BaseObject的封装:
#ifndef__BASE_OBJECT_H__
#define__BASE_OBJECT_H__
#include"cocos2d.h"
USING_NS_CC;
usingnamespacecocos2d;
classBaseObject:
publicSprite
{
public:
BaseObject(){};
virtual~BaseObject(){};
CREATE_FUNC(BaseObject);
virtualboolinit();
//setandget
intgetLife(){returnm_life;};
floatgetSpeed(){returnm_speed;};
intgetKind(){returnm_kind;};
intgetDirection(){returnm_direction;};
intgetLevel(){returnm_level;};
intgetID(){returnm_ID;};
intgetHindered(){returnm_hindered;};
voidsetLife(intl){m_life=l;};
voidsetSpeed(floats){m_speed=s;};
voidsetDirection(floatd){m_direction=d;};
voidsetKind(intk){m_kind=k;};
voidsetLevel(intlev){m_level=lev;};
voidsetID(intid){m_ID=id;};
voidsetHindered(inthindered){m_hindered=hindered;};
private:
intm_ID;//OBJECT的ID
floatm_speed;//OBJECT的移动速度
intm_life;//OBJECT的生命值(或有效值)
intm_direction;//OBJECT移动的方向
intm_kind;//OBJECT所属的类型,在不同的派生类中有不同的意思
intm_level;//OBJECT等级
intm_hindered;//OBJECT在四个方向上是否受到阻碍up.down.left.right
};
#endif
该类主要定义了基类的属性和方法,绝大多数方法都在头文件提供了简单的实现,实现文件只提供了init方法的实现:
#include"BaseObject.h"
boolBaseObject:
:
init()
{
if(!
Sprite:
:
init()){
returnfalse;
}
returntrue;
}
(2)坦克类Tank的封装:
#ifndef__TANK_H__
#define__TANK_H__
#include"BaseObject.h"
#include"cocos2d.h"
#include"cocostudio/CocoStudio.h"
#include"ui/CocosGUI.h"
#include"Global.h"
#include"Bullet.h"
USING_NS_CC;
usingnamespacecocos2d;
usingnamespacecocostudio;
usingnamespacecocos2d:
:
ui;
#defineTANKBASELIFE1//TANK基础生命
#defineTANKSPEED1//TANK默认速度
#defineTANKSIZE32//TANK尺寸大小
#defineTANK_UP1//TANK向上状态
#defineTANK_DOWN2//TANK向下状态
#defineTANK_LEFT3//TANK向左状态
#defineTANK_RIGHT4//TANK向右状态
#defineTANK_STAY5//TANK停止状态
classTank:
publicBaseObject
{
public:
staticTank*create(intID,floatx,floaty,intdir,intkind);
voidMoveUP();
voidMoveDown();
voidMoveLeft();
voidMoveRight();
voidFire();
voidStay(intdir);
voidBlast();//爆炸时已自动设置life为0
boolisMoving(){returnm_isMoving;};
RectgetRect(){returnm_rect;};
Vector
private:
virtualboolinit(intID,floatx,floaty,intdir,intkind);
voidDraw();
voidupdate(floatt);
voiddeleteObj(Sprite*obj);
private:
Sprite*m_sprite;//图片精灵
Texture2D*m_texture;//保存texture
Vector
boolm_moveUp;//坦克往上移动
boolm_moveDown;//坦克往下移动
boolm_moveLeft;//坦克往左移动
boolm_moveRight;//坦克往右移动
floatm_frametime;//切换图片时间步长
floatm_temptime;//每经过temptime切换图片
intm_texchange;//坦克履带纹理切换控制
Rectm_rect;//坦克包围框
boolm_isMoving;//坦克正在移动
intm_textureX;
intm_textureY;
};
#endif
Tank中主要的注意点在Tank的爆炸Blatant完成之后需要销毁自己,所以需要实现一个对应的销毁自己的方法:
deleteObj,实现文件如下:
#include"Tank.h"
Tank*Tank:
:
create(intID,floatx,floaty,intdir,intkind)
{
Tank*pRet=new(std:
:
nothrow)Tank();
if(pRet&&pRet->init(ID,x,y,dir,kind))
{
pRet->autorelease();
returnpRet;
}else
{
deletepRet;
pRet=NULL;
returnNULL;
}
}
boolTank:
:
init(intID,floatx,floaty,intdir,intkind)
{
if(!
BaseObject:
:
init())
{
returnfalse;
}
Director:
:
getInstance()->setProjection(Director:
:
Projection:
:
_2D);//改为正交投影,避免图片模糊
setLife(TANKBASELIFE);//tanklife
setSpeed(TANKSPEED);//tankspeed
setLevel
(1);//tanklevel
setHindered(TANK_STAY);//tankhindered
m_moveUp=FALSE;
m_moveDown=FALSE;
m_moveRight=FALSE;
m_moveLeft=FALSE;
m_isMoving=false;
m_frametime=2.0;
m_temptime=0;
//tankinitifo
setID(ID);
this->setPositionX(x);
this->setPositionY(y);
setDirection(dir);
setKind(kind);
//tankkind
if(kind==1)
{
m_texture=Director:
:
getInstance()->getTextureCache()->addImage("Chapter12/tank/player1.png");
}
if(kind==2)
{
m_texture=Director:
:
getInstance()->getTextureCache()->addImage("Chapter12/tank/player2.png");
}
//tankinitYstate
m_textureX=((this->getLevel()-1)*4+1)*14;
if(dir>0&&dir<6&&dir==TANK_UP)
{
m_textureY=1*14;
}
if(dir>0&&dir<6&&dir==TANK_LEFT)
{
m_textureY=7*14;
}
if(dir>0&&dir<6&&dir==TANK_RIGHT)
{
m_textureY=3*14;
}
if(dir>0&&dir<6&&dir==TANK_DOWN)
{
m_textureY=5*14;
}
//坦克初始状态
m_sprite=Sprite:
:
createWithTexture(m_texture,Rect(m_textureX-14.0,m_textureY-14.0,28,28));
m_rect=Rect(this->getPositionX()-16,this->getPositionY()-16,32,32);
m_sprite->setPosition(Vec2:
:
ZERO);
m_sprite->setScale(TANKSIZE/28);
this->addChild(m_sprite);
this->scheduleUpdate();
returntrue;
}
voidTank:
:
MoveUP()
{
m_moveUp=true;
m_moveDown=false;
m_moveLeft=false;
m_moveRight=false;
setDirection(TANK_UP);
}
voidTank:
:
MoveDown()
{
m_moveDown=true;
m_moveUp=false;
m_moveLeft=false;
m_moveRight=false;
setDirection(TANK_DOWN);
}
voidTank:
:
MoveLeft()
{
m_moveLeft=true;
m_moveDown=false;
m_moveRight=false;
m_moveUp=false;
setDirection(TANK_LEFT);
}
voidTank:
:
MoveRight()
{
m_moveRight=true;
m_moveLeft=false;
m_moveUp=false;
m_moveDown=false;
setDirection(TANK_RIGHT);
}
voidTank:
:
Fire()
{
Vec2position;
switch(this->getDirection())
{
caseTANK_UP:
position=Vec2(this->getPositionX(),this->getPositionY()+14);
break;
caseTANK_DOWN:
position=Vec2(this->getPositionX(),this->getPositionY()-14);
break;
caseTANK_LEFT:
position=Vec2(this->getPositionX()-14,this->getPositionY());
break;
caseTANK_RIGHT:
position=Vec2(this->getPositionX()+14,this->getPositionY());
break;
}
autobullet=Bullet:
:
create(position,3,this->getDirection());
m_bulletList.pushBack(bullet);//添加到子弹列表
this->getParent()->addChild(bullet,8);//添加到游戏场景
}
voidTank:
:
Draw()
{
if(this->getLife()){
m_textureX=((this->getLevel()-1)*4+1)*14;//gettanktextureX
//控制坦克履带转动
if(m_moveUp||m_moveDown||m_moveLeft||m_moveRight)
{
m_temptime+=m_frametime;
if(m_temptime>5)
{
m_temptime-=5;
m_texchange=(m_texchange+1)%2;
}
switch(m_texchange)
{
case0:
m_textureX=((this->getLevel()-1)*4+1)*14;
break;
case1:
m_textureX=((this->getLevel()-1)*4+1)*14+2*14;
break;
}
}
this->removeChild(m_sprite,true);//重要:
把前一个精灵移除,避免内存无法释放
m_sprite=Sprite:
:
createWithTexture(m_texture,Rect(m_textureX-14.0,m_textureY-14.0,28,28));
m_sprite->setScale(TANKSIZE/28);
this->addChild(m_sprite);//更新精灵图片
}
}
voidTank:
:
Blast()
{
this->setVisible(false);//坦克消失
this->setLife(0);
autoexplode=Sprite:
:
create("Chapter12/tank/explode2.png");
this->getParent()->addChild(explode);
explode->setPosition(this->getPosition());//显示爆炸
explode->runAction(Sequence:
:
create(
DelayTime:
:
create(0.3f),
FadeOut:
:
create(0.3f),//爆炸消失
CallFunc:
:
create(CC_CALLBACK_0(Tank:
:
deleteObj,this,explode)),
NULL
));
}
voidTank:
:
update(floatt)
{
m_isMoving=m_moveUp|m_moveDown|m_moveLeft|m_moveRight;//更新移动状态
m_rect=Rect(this->getPositionX()-16,this->getPositionY()-16,32,32);//更新rect
for(inti=0;i { autonowBullet=m_bulletList.at(i); if(nowBullet->getLife()<=0) { m_bulletList.eraseObject(nowBullet); } } if(this->getLife()<=0) { this->unscheduleUpdate(); } if(m_moveUp) { m_textureY=1*14; if((this->getPositionY()<=WINDOWHEIGHT-14)&&(this->getHindered()! =TANK_UP)) { setHindered(TANK_STAY); this->setPositionY(this->getPositionY()+this->getSpeed()); } Draw(); } if(m_moveDown) { m_textureY=5*14; if((this->getPositionY()>=14)&&(this->getHindered()! =TANK_DOWN)) { setHindered(TANK_STAY); this->setPositionY(this->getPositionY()-this->getSpeed()); } Draw(); } if(m_moveLeft) { m_textureY=7*14; if((this->getPositionX()>=14)&&(this->getHindered()! =TANK_LEFT)) { setHindered(TANK_STAY); this->setPositionX(this->getPositionX()-this->getSpeed()); } Draw(); } if(m_moveRight) { m_textureY=3*14; if((this->getPositionX()<=WINDOWWIDTH-14)&&(this->getHindered()! =TANK_RIGHT)) { setHindered(TANK_STAY); this->setPositionX(this->getPositionX()+this->getSpeed()); } Draw(); } } voidTank: : Stay(intdir) { switch(dir) { caseTANK_UP: m_moveUp=false; this->setPositionY(this->getPositionY()-1); break; caseTANK_DOWN: m_moveDown=false; this->setPositionY(this->getPositionY()+1); break; caseTANK_LEFT: m_moveLeft=false; this->setPositionX(this->getPositionX()+1); break; caseTANK_RIGHT: m_moveRight=false; this->setPositionX(this->getPositionX()-1); break; } } voidTank: : deleteObj(Sprite*obj) { obj->removeFromParent(); this->removeFromParent(); } (3)子弹类Bullet的封装,子弹相对简单,只涉及到方向、速度、爆炸以及自身销毁等操作,实现起来比较简单,对应的头文件和实现文件如下: #ifndef__BULLET_H__//Bullet.h #define__BULLET_H__ #include"BaseObject.h" #include"Global.h" #defineBULLET_UP1//BULLET向上状态 #defineBULLET_DOWN2//BULLET向下状态 #defineBULLET_LEFT3//BULLET向左状态 #defineBULLET_RIGHT4
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- chapter12 实验手册 实验 手册