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 + -
显示快捷键?