map.cpp

来自「一个symbian 冒险游戏代码」· C++ 代码 · 共 1,225 行 · 第 1/3 页

CPP
1,225
字号
	for ( int blocky = starty; blocky < endy; blocky++ )
	{
		if ( blocky >= 0 && blocky < m_props.mapHeight )
		{
			int mappos = mappos0;
			int bx = bx0;
			int by = by0;
			if ( blocky & 1 ) bx += m_props.blockStaggerX;

			// collect triggers on this block row
			int spritetriggers = 0;
			for ( int i = 0 ; i < m_spriteTriggers.size() ; ++i )
			{
				SpriteTrigger* trigger = &m_spriteTriggers[i];
				int triggerblockx = trigger->block.x.toInt();
				if ( trigger->enabled() && triggerblockx >= startx && 
					triggerblockx <= endx && blocky == trigger->block.y.toInt() )
				{
					assert( spritetriggers < int(sizeof(spritetriggerbuffer)/sizeof(spritetriggerbuffer[0])) );
					spritetriggerbuffer[spritetriggers++] = trigger;
				}
			}

			for ( int blockx = startx ; blockx < endx ; ++blockx )
			{
				if ( blockx >= 0 && blockx < m_props.mapWidth )
				{
					int block = m_map[ mappos ];
					const BlockInfo& blockinfo = m_blocks[block];
					for ( int layer = 0; layer < 4; ++layer )
					{
						int blockgfx = blockinfo.bg[ layer ];
						if ( blockgfx != 0 )
						{
							int yoffset = 0;
							if ( layer >= 2 )
							{
								yoffset = (layer - 1) * m_props.blockHeight;
							}
							drawBlock( dst, bx - x0, by - y0 - yoffset, blockgfx-1 );
						}

						if ( 0 == layer )
						{
							// draw sprites
							for ( int i = 0 ; i < spritetriggers ; ++i )
							{
								SpriteTrigger& trigger = * spritetriggerbuffer[i];
								if ( blockx == trigger.block.x.toInt() )
								{
									dstx = trigger.position[0];
									dsty = trigger.position[1];
									dstx -= app->spriteRefPoints[i][0];
									dsty -= app->spriteRefPoints[i][1];
									if ( halfRes )
									{
										dstx >>= 1;
										dsty >>= 1;
									}
									dst.blt( dstx, dsty, sprites[trigger.spriteIndex], Surface::BLEND_ALPHA1B );
								}
							}

							// draw objects
							for ( int i = 0 ; i < m_objs ; ++i )
							{
								MapObject* obj = m_objlist[i];

								// Map object drawing (player, enemies) in correct order
								if ( ( blockinfo.bg[1] != 0 && blockx == m_objBlockPosX0[i] && blocky == m_objBlockPosY0[i] ) ||  // Object in the rendering base block that has more than 1 layer
									( blockx == m_objBlockPosX1[i] && blocky == m_objBlockPosY1[i] ) )	   	            		  // Object in latter rendering block
								{
									if ( !obj->isDrawn() )
										obj->draw( dst );
								}
							}
						}
					}
				}

				++mappos;
				bx += m_props.blockWidth;
			}
		}

		mappos0 += m_props.mapWidth;
		by0 += m_props.blockStaggerY;
	}
}

void Map::drawBlock( Surface& dst, int dstx, int dsty, int blockgfx )
{
	GameApp* app = GameApp::get();
	MapBlockSet& blockset = app->blockSet();

	int blockwidth = m_props.blockWidth;
	int blockheight = m_props.blockHeight;
	if ( app->isHalfResolution() )
	{
		dstx >>= 1;
		dsty >>= 1;
		blockwidth >>= 1;
		blockheight >>= 1;
	}

	// clip
	int dstx0 = dstx;
	int dsty0 = dsty;
	int dstw = dst.width();
	int dsth = dst.height();
	int dstx1 = dstx0 + blockwidth;
	int dsty1 = dsty0 + blockheight;

	if ( dstx1 > dstw )
		dstx1 = dstw;
	if ( dsty1 > dsth )
		dsty1 = dsth;
	if ( dstx1 < 0 )
		dstx1 = 0;
	if ( dsty1 < 0 )
		dsty1 = 0;
	if ( dstx0 > dstw )
		dstx0 = dstw;
	if ( dsty0 > dsth )
		dsty0 = dsth;
	if ( dstx0 < 0 )
		dstx0 = 0;
	if ( dsty0 < 0 )
		dsty0 = 0;
	if ( dstx0 >= dstx1 || dsty0 >= dsty1 )
		return;

	assert( blockset.format.bitsPerPixel() == 8 );
	const int dstpixelsize = 2;
	const int dstpitch = dst.pitch();
	const int srcpitch = blockset.pitch;
	uint8_t* dstdata = dst.data() + dsty0*dstpitch + dstx0*dstpixelsize;
	register const int w = dstx1 - dstx0;
	assert( (blockgfx % blockset.blockbits.size()) == blockgfx );
	const uint8_t* srcdata = blockset.blockbits[ blockgfx ];
	srcdata += dstx0-dstx + (dsty0-dsty)*srcpitch;
	const uint16_t* const pal = blockset.palette;

	for ( register int y = dsty0 ; y < dsty1 ; ++y )
	{
		register uint16_t* d = (uint16_t*)dstdata;
		for ( register int i = 0 ; i < w ; ++i )
		{
			assert( dst.isValid(d+i) );

			register uint16_t pix = pal[ srcdata[i] ];
			if ( pix & 0xF000 )
			{
				d[i] = pix;
			}
		}
		dstdata += dstpitch;
		srcdata += srcpitch;
	}
}

void Map::drawBlockBound( Surface& dst, const FixVec2& block )
{
	int blockx = block.x.toInt();
	int blocky = block.y.toInt();

	if ( blockx-m_boundX0 >= 0 && blockx-m_boundX1 < 0 &&
		blocky-m_boundY0 >= 0 && blocky-m_boundY1 < 0 )
	{
		int bx = blockx * m_props.blockWidth;
		int by = blocky * m_props.blockStaggerY;
		if ( blocky & 1 )
			bx += m_props.blockStaggerX;
		
		int c[4] = {0xF0,0xF0,0xF0,0xF0};
		if ( isMapBlock(blockx,blocky) )
		{
			const BlockInfo& bi = getBlockInfo( getMapBlock(blockx,blocky) );
			int cc = 0xF00;
			if ( bi.coll & BlockInfo::COLL_TOPLEFT )
				c[0] = cc;
			if ( bi.coll & BlockInfo::COLL_TOPRIGHT )
				c[1] = cc;
			if ( bi.coll & BlockInfo::COLL_BOTTOMRIGHT )
				c[2] = cc;
			if ( bi.coll & BlockInfo::COLL_BOTTOMLEFT )
				c[3] = cc;
		}

		int bw = m_props.blockWidth;
		int bh = m_props.blockHeight;
		int sx = m_props.blockStaggerX;
		int sy = m_props.blockStaggerY;
		int marginx = blockWidth();
		int marginy = blockHeight();
		int x[4] = { bx+marginx, bx+sx, bx+bw-marginx, bx+sx };
		int y[4] = { by+sy, by+marginy, by+sy, by+bh-marginy };
		if ( GameApp::get()->isHalfResolution() )
		{
			for ( int i = 0; i < 4; i++ )
			{
				x[i] >>= 1;
				y[i] >>= 1;
			}
		}

		for ( int i = 0, k = 4-1 ; i < 4 ; k = i++ )
		{
			Fix x0 = Fix::fromInt( x[k] );
			Fix y0 = Fix::fromInt( y[k] );
			Fix x1 = Fix::fromInt( x[i] );
			Fix y1 = Fix::fromInt( y[i] );
			Line line( FixVec2(x0,y0), FixVec2(x1,y1), c[k] );
			line.drawViewport( dst );
		}
	}
}

void Map::resetTriggers()
{
	for ( int i = 0; i < m_screenTriggers.size(); i++ )
	{
		m_screenTriggers[i].active = true;
	}
	for ( int i = 0; i < m_specialTriggers.size(); i++ )
	{
		m_specialTriggers[i].active = true;
	}
}

#ifdef WIN32_CONVERT
//Conversion functions
//-------

void Map::setStartBlock( float x, float y )
{
	startBlock[0] = Fix::fromInt( (int)x );
	startBlock[1] = Fix::fromInt( (int)y );
}

void Map::setAmbientSound( String basename )
{
	String::cpy( m_ambientSound, sizeof(m_ambientSound), basename );
}

void Map::addLevelTrigger( String name, float x, float y, String filename, float x1, float y1 )
{
	LevelTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(x);
	o.block[1] = Fixf(y);
	o.targetblock[0] = Fixf(x1);
	o.targetblock[1] = Fixf(y1);
	String::cpy( o.filename, sizeof(o.filename), filename );
	m_levelTriggers.add( o );
}

void Map::addCharStateTrigger( String name, float x, float y, String statename )
{
	CharStateTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(x);
	o.block[1] = Fixf(y);
	String::cpy( o.statename, sizeof(o.statename), statename );
	m_charStateTriggers.add( o );
}

void Map::addSpecialTrigger( lang::String name, lang::String type, float x, float y, lang::String parameterString, float parameterValue )
{
	SpecialTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(x);
	o.block[1] = Fixf(y);
	o.active = true;
	o.parameterValue = int(parameterValue);
	String::cpy( o.parameterString, sizeof(o.parameterString), parameterString );
	if ( type.compareTo( "AddHealth" ) == 0 )
	{
		o.type = SpecialTrigger::AddHealth;
	}
	else if ( type.compareTo( "SetHealth" ) == 0 )
	{
		o.type = SpecialTrigger::SetHealth;
	}
	else if ( type.compareTo( "MaximizeHealth" ) == 0 )
	{
		o.type = SpecialTrigger::MaximizeHealth;
	}
	else if ( type.compareTo( "Sound" ) == 0 )
	{
		o.type = SpecialTrigger::Sound;
	}
	else if ( type.compareTo( "SignalGameFinish" ) == 0 )
	{
		o.type = SpecialTrigger::SignalGameFinish;
	}
	else
	{
		o.type = SpecialTrigger::None;
	}
	m_specialTriggers.add( o );
}

void Map::addTextTrigger( String name, float x, float y, String text, float time )
{
	TextTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(x);
	o.block[1] = Fixf(y);
	String::cpy( o.text, sizeof(o.text), text );
	o.time = Fixf(time);
	m_textTriggers.add( o );
}

void Map::addEnableTrigger( String name, float x, float y, String targetname, float enabled )
{
	EnableTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(x);
	o.block[1] = Fixf(y);
	o.enabletype = EnableTrigger::EnableType::PositionBased;
	String::cpy( o.targetname, sizeof(o.targetname), targetname );
	o.targetflags = (enabled != 0.f ? Trigger::FLAG_ENABLED : 0);
	m_enableTriggers.add( o );
}

void Map::setTriggerByItem( lang::String name, lang::String targetname )
{
	EnableTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(-1);
	o.block[1] = Fixf(-1);
	o.enabletype = EnableTrigger::EnableType::ItemBased;
	o.flags |= Trigger::FLAG_ENABLED;
	String::cpy( o.targetname, sizeof(o.targetname), targetname );
	o.targetflags = Trigger::FLAG_ENABLED; //Enable if item found
	m_enableTriggers.add( o );
}

void Map::setTriggerByItems( lang::String name, lang::String otherItem, lang::String targetname )
{
	EnableTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(-1);
	o.block[1] = Fixf(-1);
	o.enabletype = EnableTrigger::EnableType::TwoItemAndBased;
	o.flags |= Trigger::FLAG_ENABLED;
	String::cpy( o.parameterString, sizeof(o.parameterString), otherItem );
	String::cpy( o.targetname, sizeof(o.targetname), targetname );
	o.targetflags = Trigger::FLAG_ENABLED; //Enable if item found
	m_enableTriggers.add( o );
}

void Map::setTriggerReverseByItem( lang::String name, lang::String targetname )
{
	EnableTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(-1);
	o.block[1] = Fixf(-1);
	o.enabletype = EnableTrigger::EnableType::ItemBased;
	o.flags |= Trigger::FLAG_ENABLED;
	String::cpy( o.targetname, sizeof(o.targetname), targetname );
	o.targetflags = 0; //Disable if item found (reverse)
	m_enableTriggers.add( o );
}

void Map::setTriggerByObjectState( lang::String name, lang::String statename, lang::String targetname )
{
	EnableTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(-1);
	o.block[1] = Fixf(-1);
	o.enabletype = EnableTrigger::EnableType::EnemyBased;
	o.flags |= Trigger::FLAG_ENABLED;
	String::cpy( o.parameterString, sizeof(o.parameterString), statename );
	String::cpy( o.targetname, sizeof(o.targetname), targetname );
	o.targetflags = Trigger::FLAG_ENABLED; //Enable if enemy state matches
	m_enableTriggers.add( o );
}

void Map::setTriggerReverseByObjectState( lang::String name, lang::String statename, lang::String targetname )
{
	EnableTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(-1);
	o.block[1] = Fixf(-1);
	o.enabletype = EnableTrigger::EnableType::EnemyBased;
	o.flags |= Trigger::FLAG_ENABLED;
	String::cpy( o.parameterString, sizeof(o.parameterString), statename );
	String::cpy( o.targetname, sizeof(o.targetname), targetname );
	o.targetflags = 0; // Disable if enemy state matches (reverse)
	m_enableTriggers.add( o );
}

void Map::addSpriteTrigger( String name, float x, float y, String sprite )
{
	SpriteTrigger o;
	String::cpy( o.name, sizeof(o.name), name );
	o.block[0] = Fixf(x);
	o.block[1] = Fixf(y);

	FixVec2 pos = blockToPixel( FixVec2(o.block[0],o.block[1]) );
	o.position[0] = pos.x.toInt();
	o.position[1] = pos.y.toInt();

	GameApp* app = GameApp::get();
	o.spriteIndex = app->findItem( app->spriteNames, app->spriteCount, sprite.c_str() );
	if ( -1 == o.spriteIndex )
		throwError( Exception(Format("sprite {0} not found from list", sprite )) );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?