Cocos2d-x 3.2 大富翁游戏项目开发-第二十五部分 大富翁股市

当角色走到股市图标时,进入股市界面。每走完一个回合,增加一条股票数据,

股市界面上半部分显示股票信息,包括代码,名称,当前价格,买入价格,涨跌百分比,角色持有的股票数量

下半部分显示股票价格走势,当点击一个股票时,显示相关股票的价格走势,共显示最新14条的价格走势。

每次点击购买,买入100股 。点击卖出,则卖出所持有的该股的所有股票。成交价格 等信息动态更新

点击返回,返回到游戏主界面,并更新角色资金值

1、首先添加股票类

包括代码,名称,买入价格,涨跌百分比,持仓数量等定义以及相关的get 、set方法

class Stock : public Sprite
{
................
private:
<span style="white-space:pre">	</span>int stockCode; //股票代码
	String* stockName;//股票名称
        int nowPrice;//当前价格
        int makedealprice;//成交价格
	float percent;//涨跌百分比
	int storeNumber;//持仓数量
};

2、VisibleRect类,主要是为了方便的获取屏幕的尺寸等信息

class VisibleRect
{
public:
    static cocos2d::Rect getVisibleRect();
...................
private:
    static void lazyInit();
    static cocos2d::Rect s_visibleRect;
};

3、股票记录中的单元格类StockCellCard,包括单元格背景和显示文字的label。同彩票类card大体相同,不再解释了

4、在RicherPlayer的init方法中,给角色创建股票持有信息,主要是股票代码和持仓数量和买入价格。其他信息无关紧要

bool RicherPlayer::init(char* name, int tag,bool enemy,int money,int strength)
{
...........
	stockMap.insert(0,Stock::create(800100,LanguageString::getInstance()->getLanguageString(RICH_TECHNOLOGY),0,10,0,100));
	stockMap.insert(1,Stock::create(800200,LanguageString::getInstance()->getLanguageString(RICH_TECHNOLOGY),0,20,0,200));
	stockMap.insert(2,Stock::create(800300,LanguageString::getInstance()->getLanguageString(RICH_TECHNOLOGY),0,70,0,800));
	stockMap.insert(3,Stock::create(800400,LanguageString::getInstance()->getLanguageString(RICH_TECHNOLOGY),0,10,0,400));
	stockMap.insert(4,Stock::create(800500,LanguageString::getInstance()->getLanguageString(RICH_TECHNOLOGY),0,0,0,0));
	..........
}

5、当角色走到股票图标时RicherGameController 控制器,发送进入股市的消息

	 if(passId == GameBaseScene::stock_tiledID)
	 {
		 String * str = String::createWithFormat("%d-%f-%f-%d-%d",MSG_STOCK_TAG,1.0f,1.0f,_richerPlayer->getTag(),MOVEPASS);
		 NotificationCenter::getInstance()->postNotification(MSG_STOCK,str);
		 return;
	 }

6、GameBaseScene类定义了股票容器类,存放所以股票相关信息

vector<float> GameBaseScene::stock_pointvec1;

vector<float> GameBaseScene::stock_pointvec2;

vector<float> GameBaseScene::stock_pointvec3;

vector<float> GameBaseScene::stock_pointvec4;

vector<float> GameBaseScene::stock_pointvec5;

在更新回合计数时,调用updateStockVec()方法,添加股票一条新纪录

void GameBaseScene::refreshRoundDisplay()

{

..........

updateStockVec()

.......

}

//最多纪录14条纪录,超过的会被覆盖掉
void GameBaseScene::updateStockVec()
{
	float valule1 = rand()%800+10;
	float valule2 = rand()%800+10;
	float valule3 = rand()%800+10;
	float valule4 = rand()%800+10;
	float valule5 = rand()%800+10;

	if(stock_pointvec1.size()>13)
	{
		for(int i=0;i<13;i++)
		{
			stock_pointvec1.at(i)=stock_pointvec1.at(i+1);
			stock_pointvec2.at(i)=stock_pointvec2.at(i+1);
			stock_pointvec3.at(i)=stock_pointvec3.at(i+1);
			stock_pointvec4.at(i)=stock_pointvec4.at(i+1);
			stock_pointvec5.at(i)=stock_pointvec5.at(i+1);

		}
		stock_pointvec1.at(13) =valule1;
		stock_pointvec2.at(13) =valule2;
		stock_pointvec3.at(13) =valule3;
		stock_pointvec4.at(13) =valule4;
		stock_pointvec5.at(13) =valule5;
	}else
	{
		stock_pointvec1.push_back(valule1);
		stock_pointvec2.push_back(valule2);
		stock_pointvec3.push_back(valule3);
		stock_pointvec4.push_back(valule4);
		stock_pointvec5.push_back(valule5);
	}
}	 

7、当GameBaseScene收到进入股市界面的消息时,添加股市layer,显示股市

	case MSG_STOCK_TAG:
		{
				auto lineView = LineChart::createChart(player1);
				lineView->setPosition(Point(0, 0));
				moveTag = messageVector.at(4)->intValue();
				lineView->moveTag = moveTag;
				addChild(lineView);
				..............
			break;
		}	

8、LineChart类是股票界面类

(1)initChart方法

bool LineChart::initChart(RicherPlayer* player)
{
    if ( !LayerColor::initWithColor(Color4B(0,0,0,255))) //黑色背景
	{
		 return false;
	}
	richerPlayer = player; //角色
	playerStockMap = player->stockMap;//角色持有的股票容器
	initStockVector(playerStockMap);
	drawNode = DrawNode::create();//创建DrawNode ,准备画图
	this->addChild(drawNode);
	tv = TableView::create(this, Size(650, 160));//创建TableView对象
        tv->setAnchorPoint(Point(0, 0));
        tv->setPosition(10, VisibleRect::getVisibleRect().size.height * 1 /2);
        tv->setDelegate(this);
        addChild(tv);
	initMenu();//创建菜单,包括买入,卖出,返回Menu
	selectedTag =0;
	float tableY =  VisibleRect::getVisibleRect().size.height * 1/2;
	//选择股票时,箭头移动到相关股票
	arrowSprite_left->setPosition(600+arrowSprite_left->getContentSize().width,tableY +selectedTag*32);
	arrowSprite_right->setPosition(10,tableY + selectedTag*32);
	setData(getsock_pointVec(selectedTag));//设置股票数据
	drawpic();//画走势图
    return true;
}

(2)initMenu方法创建菜单,包括买入,卖出,返回Menu,以及箭头提示

void LineChart::initMenu()
{
	Menu* menu = Menu::create();
	menu->setPosition(CCPointZero);
    setMenu(menu);
    MenuItemImage* buyMenuItemButton = MenuItemImage::create("images/buy_normal.png", "images/buy_pressed.png", this, menu_selector(LineChart::buttonCallback));

    buyMenuItemButton->setPosition(ccp(700,VisibleRect::getVisibleRect().size.height-110));
	buyMenuItemButton->setAnchorPoint(ccp(0,0));
	buyMenuItemButton->setTag(buy_button);
	menu->addChild(buyMenuItemButton);
	............
	arrowSprite_left = Sprite::create("images/arrow_left.png");
	arrowSprite_left->setPosition(ccp(-500,-500));
	arrowSprite_left->setAnchorPoint(ccp(0,0));
	addChild(arrowSprite_left);

	arrowSprite_right = Sprite::create("images/arrow_right.png");
	arrowSprite_right->setPosition(ccp(-500,-500));
	arrowSprite_right->setAnchorPoint(ccp(0,0));
	addChild(arrowSprite_right);
}

(3)initStockVector()添加股票上半部分表格的标题,以及给股票容器添加各个股票信息

void LineChart::initStockVector(Map<int,Stock*> stockMap)
{
	float percent = 0;
	if(GameBaseScene::stock_pointvec1.size()>1)
	{
		percent = (GameBaseScene::stock_pointvec1.at(GameBaseScene::stock_pointvec1.size()-1) - GameBaseScene::stock_pointvec1.at(GameBaseScene::stock_pointvec1.size()-2))/GameBaseScene::stock_pointvec1.at(GameBaseScene::stock_pointvec1.size()-2)*100;
	}

	stockVector.pushBack(Stock::create(800100,LanguageString::getInstance()->getLanguageString(RICH_TECHNOLOGY),GameBaseScene::stock_pointvec1.at(GameBaseScene::stock_pointvec1.size()-1),stockMap.at(0)->getMakedealprice(),percent,stockMap.at(0)->getStoreNumber()));

	..................

	Label* code = Label::createWithSystemFont(LanguageString::getInstance()->getLanguageString(STOCK_CODE)->getCString(),"", 20);
	code->setPosition(Point(20, 410 ));
	code->setAnchorPoint(ccp(0,0));
	addChild(code);

	Label* name = Label::createWithSystemFont(LanguageString::getInstance()->getLanguageString(STOCK_NAME)->getCString(),"", 20);
	name->setPosition(Point(stockCellWidth+20, 410 ));
	name->setAnchorPoint(ccp(0,0));
	addChild(name);

	Label* nowprice = Label::createWithSystemFont(LanguageString::getInstance()->getLanguageString(STOCK_NOWPRICE)->getCString(),"", 20);
	nowprice->setPosition(Point(stockCellWidth*2+20, 410 ));
	nowprice->setAnchorPoint(ccp(0,0));
	addChild(nowprice);

	Label* dealprice = Label::createWithSystemFont(LanguageString::getInstance()->getLanguageString(STOCK_DEALPRICE)->getCString(),"", 20);
	dealprice->setPosition(Point(stockCellWidth*3+20, 410 ));
	dealprice->setAnchorPoint(ccp(0,0));
	addChild(dealprice);

	Label* percentLabel = Label::createWithSystemFont(LanguageString::getInstance()->getLanguageString(STOCK_PERCENT)->getCString(),"", 20);
	percentLabel->setPosition(Point(stockCellWidth*4+20, 410 ));
	percentLabel->setAnchorPoint(ccp(0,0));
	addChild(percentLabel);

	Label* store = Label::createWithSystemFont(LanguageString::getInstance()->getLanguageString(STOCK_STORE)->getCString(),"", 20);
	store->setPosition(Point(540, 410 ));
	store->setAnchorPoint(ccp(0,0));
	addChild(store);

	playerMoneyLabel = Label::createWithSystemFont(
		String::createWithFormat("%s %d",LanguageString::getInstance()->getLanguageString(PLAYER_MONEY)->getCString(),richerPlayer->getMoney())->getCString(),
		"", 20);
	playerMoneyLabel->setPosition(Point(20, 450 ));
	playerMoneyLabel->setAnchorPoint(ccp(0,0));
	addChild(playerMoneyLabel);

}

(4)buttonCallback(),点击买入 ,卖出,返回的回调方法

void LineChart::buttonCallback(CCObject* pSender)

{

.............

}

(5)TableView 相关实现方法

//当点击股票时,移动箭头,更新数据,重画走势图
void LineChart::tableCellTouched(cocos2d::extension::TableView *table, cocos2d::extension::TableViewCell *cell)
{

	for(int i=0;i<30;i++)
	{
		this->removeChildByTag(100+i);
	}

	int tag = cell->getTag();
	selectedTag =tag;
    log("******click id = %d",tag);
	float height = VisibleRect::getVisibleRect().size.height;
	float tableY =  VisibleRect::getVisibleRect().size.height * 1/2;
	arrowSprite_left->setPosition(600+arrowSprite_left->getContentSize().width,tableY +tag*32);
	arrowSprite_right->setPosition(10,tableY + tag*32);
	log("all height is %f",height);
	log("all cellY is %f",tableY);
	setData(getsock_pointVec(tag));
	drawpic();

}
//创建tableview相关单元格,当股市上涨时,背景色为红色,下跌时为绿色
TableViewCell* LineChart::tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx)
{
    TableViewCell *cell = table->dequeueCell();
    LabelTTF *label;

    int colorTag = 0;
	if(stockVector.at(idx)->getPercent()>0)
	{
		colorTag = 1;
	}else
	{
		colorTag = -1;
	}

    if (cell==NULL)
	{
        cell = TableViewCell::create();
		cell->setTag(idx);
		for(int i=0; i<6; i++)
		{
			switch(i)
			{
			case 0:
				{
					StockCellCard* card = StockCellCard::createCardSprite(String::createWithFormat("%d",stockVector.at(idx)->getCode()), stockCellWidth, stockCellHeight, stockCellWidth*i+10, 0,colorTag);
					cell->addChild(card);
					break;
				}
			case 1:
				{
					StockCellCard* card = StockCellCard::createCardSprite(stockVector.at(idx)->getStockName(), stockCellWidth, stockCellHeight, stockCellWidth*i+10, 0,colorTag);
					cell->addChild(card);
					break;
				}
....................................
			}

		} 

    }

    return cell;
}

//共5支股票

ssize_t LineChart::numberOfCellsInTableView(cocos2d::extension::TableView *table){

return 5;

}

(6)画走势图

void LineChart::drawpic()
{
	drawNode->clear();
	int maxValue = getMaxValue(pointvec);
	int maxValue2 = int((maxValue+100) / 100)* 100 ;
     maxValue1 = maxValue2  / 10;

     spaceRatio = 0.08f;  //y轴间距系数
     leftRatioX = 0.1f;   //x轴左侧间距系数

    int fontSize = 20;
    string fontName = StringUtils::format("Thonburi");

    Size layerSize = Size(VisibleRect::getVisibleRect().size.width, VisibleRect::getVisibleRect().size.height * 1 /2);

      layerHeight1 = 30;
    float layerHeight = layerHeight1;
    float layerWidth = layerSize.width;
    int count = layerSize.width /50;
    /***********************画xy轴标签*************************************/

    for (int i = 0; i < 11; i++) {
        Point bPoint = Point(layerWidth* leftRatioX, layerHeight );
        Point ePoint = Point(layerWidth* leftRatioX+(count-2) * 50, layerHeight );
        Label* label = Label::createWithSystemFont(StringUtils::format("%d",maxValue1* i).c_str(), fontName.c_str(), fontSize);
        label->setPosition(Point(layerWidth* 0.05f, layerHeight ));
	label->setTag(100+i);
        addChild(label);
	drawNode->drawSegment(bPoint, ePoint, 0.5,Color4F(100, 100, 200, 200));
        layerHeight += layerSize.height * spaceRatio;
    }

	float layer_wd = layerSize.width * leftRatioX;
        for (int i = 0; i < count; i++) {

		Point bPoint  = Point(layer_wd, layerHeight1);
		Point ePoint  = Point(layer_wd, layerSize.height * spaceRatio*10+layerHeight1);
		if(i%2 == 0)
		{
			drawNode->drawSegment(bPoint,ePoint,0.5,Color4F(100, 100, 200, 200));
		}

		auto labelX = Label::createWithSystemFont(StringUtils::format("%d",i).c_str(), "Thonburi", 20);
                labelX->setPosition(Point(ePoint.x, 0));
		labelX->setAnchorPoint(ccp(0,0));
		labelX->setTag(100+11+i);
                this->addChild(labelX);
                layer_wd += 50;

    }

	drawLine(pointvec, Color4B(0, 255, 255, 255),Color4B(255, 0, 255, 255));
}

//画走势线条

void LineChart::drawLine(vector<Point> vec,Color4B lineColor,Color4B dotColor)
{

    Size layerSize = Size(VisibleRect::getVisibleRect().size.width, VisibleRect::getVisibleRect().size.height * 1 /2);

    float layerWidth = layerSize.width;

    float tempWidth = layerSize.height * spaceRatio;
    float tempWidth2 = 0;

    float tempHeight1 = maxValue1  ;   

    double  ratio = tempWidth/tempHeight1;

    /**********************开始画线**********************/
    std::vector<Point>::iterator beforePoint;
    std::vector<Point>::iterator currentPoint;

    beforePoint = vec.begin();

    for (currentPoint = vec.begin() + 1;currentPoint != vec.end() ; currentPoint++) {
        Point bPoint  = *beforePoint;
        bPoint = Point(bPoint.x + layerWidth* leftRatioX, bPoint.y * ratio + layerHeight1 +tempWidth2);

        Point ePoint  = *currentPoint;
        ePoint = Point(ePoint.x + layerWidth* leftRatioX, ePoint.y * ratio + layerHeight1 +tempWidth2);

		drawNode->drawSegment(bPoint, ePoint, 0.8,Color4F::RED);
        beforePoint = currentPoint;

    }

     /**********************结束画线**********************/   

    /********************开始画点**********************************************/
    beforePoint = vec.begin();
    DrawPrimitives::setDrawColor4B(dotColor.r, dotColor.g, dotColor.b, dotColor.a);
    Point bPoint  = *beforePoint;
    bPoint = Point(bPoint.x +layerWidth* leftRatioX, bPoint.y * ratio + layerHeight1 +tempWidth2);

	drawNode->drawDot(bPoint, 5, Color4F::YELLOW); 

    int i = 2;
    for (currentPoint = vec.begin() + 1;currentPoint != vec.end() ; currentPoint++) {
        Point ePoint  = *currentPoint;
        ePoint = Point(ePoint.x + layerWidth* leftRatioX, ePoint.y * ratio + layerHeight1 + tempWidth2);
        drawNode->drawDot(ePoint, 5, Color4F::YELLOW);
        i++;
    }
     /********************结束画点*********************************************END**/

}

//设置股票数据

void LineChart::setData(vector<float> data)
{
	pointvec.clear();
    vector<float>::iterator it;
    int i = 0;

    for (it = data.begin();it != data.end();it++) {
        float f = *it;
        pointvec.push_back(Point(50 * (i+1), f));
        i++;

    }

}
//获取最大值
double LineChart::getMaxValue(std::vector<Point> vec)
{

    double maxY =1;

    for (int i = 0; i < vec.size(); i++)
	{
        float num = vec.at(i).y;
        if (maxY < abs(num))
		{
            maxY = abs(num);
        }
    }
    return maxY;
}

这就是大体代码,详细内容,请参考代码,如下效果图

点击下载代码

未完待续...................

时间: 2024-10-25 10:26:19

Cocos2d-x 3.2 大富翁游戏项目开发-第二十五部分 大富翁股市的相关文章

Cocos2d-x 3.2 大富翁游戏项目开发-第二十九部分 游戏配音

我从大富翁里提取出来里面的wav音效文件,放到我们的游戏中以增加趣味性,仅供学习研究之用 1.修改AppDelegate.cpp文件 // This function will be called when the app is inactive. When comes a phone call,it's be invoked too void AppDelegate::applicationDidEnterBackground() { Director::getInstance()->stop

Cocos2d-x 3.2 大富翁游戏项目开发-第二十六部分 人物技能

本节主要是添加人物技能,技能包括 暴风骤雨:此技能可以把地块变成空白地块, 随心步:  选择想走的步数,想走几步走几步 巧取豪夺:把对手的土地变成自己的 技能包含的信息:等级 和 耗费体力 等级共5级,每提高一个等级,需要耗费的体力值减10 暴风骤雨:初始耗费体力值70 随心步:  初始耗费体力值50 巧取豪夺:初始耗费体力值100 1.添加技能SkillCard 类,包含了技能基本信息以及如何显示技能 其实现和前面讲解的股票 彩票 card类相似,不再累述 2.修改RicherPlayer类,

Cocos2d-x 3.2 大富翁游戏项目开发-第二十部分 螃蟹挡路

该部分我们添加螃蟹伤人事件,道路位置随机添加螃蟹精灵,当角色行走完毕如果停留位置碰到了螃蟹,首先播放伤人动画,然后是播放救护车把角色带走动画. 如果轮流到该角色行走时,吐司提示住院还有几天,当住院天数到期,该角色才可以继续行走 新建了几个精灵类 Item_crab.cpp 螃蟹 Item_emergency.cpp 救护车 Item_fog.cpp 烟雾 Item_stretcher.cpp 担架 //该方法在场景中添加这几个精灵 void GameBaseScene::initItemSpri

Cocos2d-x 3.2 大富翁游戏项目开发-第二十二部分 拾到珍珠

该部分同前面处理逻辑基本一样,道路上随机出现闪烁的珍珠,在捡到珍珠后,toast显示捡到珍珠资金增加. 1.编写Item_ball类,该类存储了珍珠相关动画 bool Item_ball::init() { addItemSpriteFrameCache(); SpriteFrame* spf; spf = itemSpriteFrameCache->getSpriteFrameByName("ball_01.png"); Sprite::initWithSpriteFrame(

Cocos2d-x 3.2 大富翁游戏项目开发-第二十四部分 彩票开奖

每隔N个回合,彩票开奖一次,每期开奖奖金固定5万,暂不累积.摇奖效果一般,以后考虑用物理引擎实现 1.定义彩票开奖类 bool LotteryPublish::init() { addItemSpriteFrameCache(); SpriteFrame* spf; spf = itemSpriteFrameCache->getSpriteFrameByName("publish_ly01.png"); Sprite::initWithSpriteFrame(spf); setI

Cocos2d-x 3.2 大富翁游戏项目开发-第十五部分 升级地块

当路过的地块属于自己的时,如果是第一角色则弹出对话框,提示升级地块,其他角色直接升级地块. 当路过的地块不是自己的时,需要缴纳与地块等级相应的过路费. 修改RicherGameController.cpp文件的handlePropEvent()方法 针对不同的地块,发送不同的消息 void RicherGameController::handlePropEvent() { ---------- for (int i = 0; i < 4; i++) //遍历角色上下左右相邻位置的地块 { Poi

Cocos2d-x 3.2 大富翁游戏项目开发-第二部分片头动画

第二部分片头动画 首先在visula studio 下创建新工程 工具类ConstUtil.h,该文件主要定义了一些图片资源.字符串.字体等 #ifndef __CONSTUTIL_H__ #define __CONSTUTIL_H__ //定义了诚迈科技四张图片资源,由于在诚迈科技,就用公司名称做动画吧 #define CHENG_IMAGE "cheng.png" #define MAI_IMAGE "mai.png" #define KE_IMAGE &quo

Cocos2d-x 3.2 大富翁游戏项目开发-第二十三部分 购买彩票

当角色路过彩票的标志或者停留位置有彩票标志时,弹出购买彩票的对话框,提示购买彩票,已经买过的号码,不显示.当机器对手路过时则直接购买彩票. 1. 在RicherPlayer.h中增加std::vector<int> lottery_vector;用来存储购买的彩票号码 2. RicherGameController 修改endGo方法,每走完一步就会进入该方法,判断是否有彩票标示图标,有的话发送MSG_LOTTERY彩票消息,MOVEPASS标示走完一步的标志 void RicherGameC

Cocos2d-x 3.2 大富翁游戏项目开发-第二十七部分 技能提升和游戏结束判断

本节主要是增加技能提升事件 和 游戏结束判断,游戏判断简单处理了一下,只要有一个角色资金小于0 ,就认为游戏结束. 如果人物在3个以上,则需要做进一步处理,比如失败方的房屋如何处理,这些在处理到多个角色的时候再做处理. 1.添加提升技能随机事件 oid GameBaseScene::initRandomAskEvent() { ................. randomAskEventMap.insert(STORM_UP_TAG,LanguageString::getInstance()