📄 map.cpp
字号:
/* cache 为四倍主画面尺寸,初始状态下,主画面占据6,7,10,11四块
cache 的刷新过程分为若干子步骤,最多8步,
cache分为16小块,大小不等:顶行和末行高度为WIN_HEIGHT/2-TILE_HEIGHT/2
中间两行的高度为WIN_HEIGHT/2
WIN_HEIGHT = 11 * TILE_HEIGHT
WIN_WIDTH = 10 * TILE_WIDTH
+----+----+----+----+
| 1 | 2 | 3 | 4 |
+----+----+----+----+
| 5 | 6 | 7 | 8 |
+----+----+----+----+ 大小不等 !!
| 9 | 10 | 11 | 12 |
+----+----+----+----+
| 13 | 14 | 15 | 16 |
+----+----+----+----+
*/
#include "..\common.h"
#include "gengine.h"
#define DEBUG
Maze maze[MAZE_SIZE][MAZE_SIZE];
// cache负责画出地面,必要时带有明暗效果
Cache cache;
// scene负责墙壁及精灵的显示
Scene scene;
// 生成随机地图
void MapGenerate( void )
{// for test !
FILE *fp;
int i, j;
char temp[128];
ZeroMemory( maze, sizeof(maze));
fp = fopen( "level00.txt", "rb" );
if( fp == NULL )
return;
for( i=0; i<MAZE_SIZE; i++ ){
fgets( temp, 128, fp );
for( j=0; j<MAZE_SIZE; j++ )
if( temp[j] >= 'a' ){ // ground
maze[i][j].isWall = 0;
maze[i][j].plot = temp[j] - 'a' + 1;
}
else if( temp[j] >= 'A' ){ // wall
maze[i][j].isWall = 1;
maze[i][j].occupied = 1;
maze[i][j].plot = temp[j] - 'A';
}
}
fclose( fp );
return;
}
void Cache::Redraw( int x, int y, int r, int t, int w, int h )
{//假设:maze的低7位表示地面,
int i, j, k, l, gx;
int c = MAX( w, (h+1)/2 );
SpriteSetDrawMode( Bitmap::BetaMode, 256 );
OutDebugInt( "r", r );
OutDebugInt( "t", t );
OutDebugInt( "w", w );
OutDebugInt( "h", h );
if( r > c && r < MAZE_SIZE - c
&& t >= 0 && t < MAZE_SIZE - c*2 ){
// no clip
for( i=0; i<h; i++ ){
l = r + (i+1)/2;
k = t + i/2;
gx = (i%2) ? x : x - 32;
for( j=0; j<w+i%2; j++ ){
if( maze[k][l].isWall ) // wallbase
wallBase.Draw( ground, gx, y, maze[k][l].plot );
else
floor.Draw( ground, gx, y, maze[k][l].plot );
k ++;
l --;
gx -= 64;
}
y += 16;
}
OutDebugString( "cache.redraw no clip" );
}
else{ // clip
for( i=0; i<h; i++ ){
l = r + (i+1)/2;
k = t + i/2;
gx = (i%2) ? x : x - 32;
for( j=0; j<w+i%2; j++ ){
if( k >= 0 && l >= 0 && k < MAZE_SIZE && l < MAZE_SIZE )
if( maze[k][l].isWall ) // wallbase
wallBase.Draw( ground, gx, y, maze[k][l].plot );
else
floor.Draw( ground, gx, y, maze[k][l].plot );
else
floor.Draw( ground, gx, y, 0 );
k ++;
l --;
gx -= 64;
}
y += 16;
}
}
}
void Cache::RefreshTop( void )
{// 重画块1,2,3,4
#ifdef DEBUG
OutDebugString( "refreshTop" );
#endif
switch( refreshStep ){
case 0: // 移动块9,10
ground->Blit( ground, 0, WIN_HEIGHT*3/2 - TILE_HEIGHT,
0, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 );
break;
case 1: // 移动块11,12
ground->Blit( ground, WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT,
WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 );
break;
case 2:
if( sceneX < WIN_WIDTH/2 ) // 移动块4,8
ground->Blit( ground, WIN_WIDTH*3/2, WIN_HEIGHT/2 - TILE_HEIGHT/2,
WIN_WIDTH*3/2, 0, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
else // 移动块1,5
ground->Blit( ground, 0, WIN_HEIGHT/2 - TILE_HEIGHT/2,
0, 0, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 3:
// have a rest
break;
case 4:
if( sceneX < WIN_WIDTH/2 ) // 移动块1,2,3,5,6,7
ground->Blit( ground, 0, WIN_HEIGHT/2 - TILE_HEIGHT/2, 0, 0, WIN_WIDTH*3/2, WIN_HEIGHT - TILE_HEIGHT/2 );
else // 移动块10,11,12,14,15,16
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2 - TILE_HEIGHT/2,
WIN_WIDTH/2, 0, WIN_WIDTH*3/2, WIN_HEIGHT - TILE_HEIGHT/2 );
sceneY += WIN_HEIGHT/2 - TILE_HEIGHT/2;
mapX -= WIN_WIDTH/TILE_WIDTH/2;
mapY -= WIN_WIDTH/TILE_WIDTH/2;
break;
case 5:
// have a rest
break;
case 6: // 1,2
Redraw( WIN_WIDTH, 0, mapX-11, mapY-10, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
break;
case 7: // 3,4
Redraw( WIN_WIDTH*2, 0, mapX-1, mapY-20, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
status = NoRefresh;
break;
}
refreshStep ++;
}
void Cache::RefreshTopLeft( void )
{// 重画块1,2,3,4,5,9,13
#ifdef DEBUG
OutDebugString( "RefreshTopLeft" );
#endif
switch( refreshStep ){
case 0: // 移动块9,10,11
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT*3/2 - TILE_HEIGHT, 0, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH*3/2, WIN_HEIGHT/2 );
break;
case 1: // 移动块3,7
ground->Blit( ground, WIN_WIDTH*3/2, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH, 0, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 2: // 移动块1,2,5,6
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2 - TILE_HEIGHT/2, 0, 0, WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2 );
sceneX += WIN_WIDTH/2;
sceneY += WIN_HEIGHT/2 - TILE_HEIGHT/2;
mapX -= WIN_WIDTH/TILE_WIDTH;
break;
case 3:
break;
case 4: //1,2
Redraw( WIN_WIDTH, 0, mapX-11, mapY-10, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
break;
case 5: // 3,4
Redraw( WIN_WIDTH*2, 0, mapX-1, mapY-20, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
break;
case 6: // 5,9
Redraw( WIN_WIDTH/2, WIN_HEIGHT/2 - TILE_HEIGHT/2, mapX-11, mapY, WIN_WIDTH/2/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT*2 );
break;
case 7: // 13
Redraw( WIN_WIDTH/2, WIN_HEIGHT*3/2- TILE_HEIGHT/2, mapX, mapY+11, WIN_WIDTH/2/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
status = NoRefresh;
break;
}
refreshStep ++;
}
void Cache::RefreshLeft( void )
{
#ifdef DEBUG
OutDebugString( "RefreshLeft" );
#endif
switch( refreshStep ){
case 0: // 移动块3,7
ground->Blit( ground, WIN_WIDTH*3/2, 0, WIN_WIDTH, 0, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 1: // 移动块11,15
ground->Blit( ground, WIN_WIDTH*3/2, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 2:
if( sceneY < WIN_HEIGHT/2 ) // 移动块13,14
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, 0, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 - TILE_HEIGHT/2 );
else // 移动块1,2
ground->Blit( ground, WIN_WIDTH/2, 0, 0, 0, WIN_WIDTH, WIN_HEIGHT/2 - TILE_HEIGHT/2 );
break;
case 3:
if( sceneY < WIN_HEIGHT/2 ) // 移动块1,2,5,6,9,10
ground->Blit( ground, WIN_WIDTH/2, 0, 0, 0, WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2 );
else // 移动块5,6,9,10,13,14
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2 - TILE_HEIGHT/2, 0, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2 );
sceneX += WIN_WIDTH/2;
mapX -= WIN_WIDTH/TILE_WIDTH/2;
mapY += WIN_WIDTH/TILE_WIDTH/2;
break;
case 4:
break;
case 5:
break;
case 6: //1,5
Redraw( WIN_WIDTH/2, 0, mapX-16, mapY-5, WIN_WIDTH/TILE_WIDTH/2, WIN_HEIGHT/TILE_HEIGHT*2-1 );
break;
case 7: //9,13
Redraw( WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT, mapX-6, mapY+5, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT*2+1);
status = NoRefresh;
break;
}
refreshStep ++;
}
void Cache::RefreshBottomLeft( void )
{
#ifdef DEBUG
OutDebugString( "RefreshBottomLeft" );
#endif
switch( refreshStep ){
case 0: // 移动块5,6,7到2,3,4
ground->Blit( ground, WIN_WIDTH/2, 0, 0, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH*3/2, WIN_HEIGHT/2 );
break;
case 1: // 移动块11,15到8,12
ground->Blit( ground, WIN_WIDTH*3/2, WIN_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 2: // 移动块9,10,13,14到6,7,10,11
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2, 0, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2 );
sceneX += WIN_WIDTH/2;
sceneY -= WIN_HEIGHT/2 - TILE_HEIGHT/2;
mapY += WIN_WIDTH/TILE_WIDTH;
break;
case 3:
break;
case 4: //9
Redraw( WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT, mapX-6, mapY+5, WIN_WIDTH/TILE_WIDTH/2, WIN_HEIGHT/TILE_HEIGHT+2 );
break;
case 5: //1,5
Redraw( WIN_WIDTH/2, 0, mapX-16, mapY-5, WIN_WIDTH/TILE_WIDTH/2, WIN_HEIGHT/TILE_HEIGHT*2-1 );
break;
case 6: //13,14
Redraw( WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, mapX+5, mapY+6, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
break;
case 7: //15,16
Redraw( WIN_WIDTH*2, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, mapX+15, mapY-4, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
status = NoRefresh;
break;
}
refreshStep ++;
}
void Cache::RefreshBottom( void )
{
#ifdef DEBUG
OutDebugString( "RefreshBottom" );
#endif
switch( refreshStep ){
case 0: // 移动块5,6到1,2
ground->Blit( ground, 0, 0, 0, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 );
break;
case 1: // 移动块7,8到3,4
ground->Blit( ground, WIN_WIDTH, 0, WIN_WIDTH, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 );
break;
case 2:
if( sceneX < WIN_WIDTH/2 ) // 移动块12,16到8,12
ground->Blit( ground, WIN_WIDTH*3/2, WIN_HEIGHT/2, WIN_WIDTH*3/2, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
else // 移动块9,13到5,9
ground->Blit( ground, 0, WIN_HEIGHT/2, 0, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 3:
if( sceneX < WIN_WIDTH/2 ) // 移动块9,10,11,13,14,15到5,6,7,9,10,11
ground->Blit( ground, 0, WIN_HEIGHT/2, 0, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH*3/2, WIN_HEIGHT - TILE_HEIGHT/2 );
else // 移动块10,11,12,14,15,16到6,7,8,10,11,12
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH*3/2, WIN_HEIGHT - TILE_HEIGHT/2 );
sceneY -= WIN_HEIGHT/2 - TILE_HEIGHT/2;
mapX += WIN_WIDTH/TILE_WIDTH/2;
mapY += WIN_WIDTH/TILE_WIDTH/2;
break;
case 4:
break;
case 5:
break;
case 6: //13,14
Redraw( WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, mapX+5, mapY+6, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
break;
case 7: //15,16
Redraw( WIN_WIDTH*2, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, mapX+15, mapY-4, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
status = NoRefresh;
break;
}
refreshStep ++;
}
void Cache::RefreshBottomRight( void )
{
#ifdef DEBUG
OutDebugString( "RefreshBottomRight" );
#endif
switch( refreshStep ){
case 0: // 移动块6,7,8到1,2,3
ground->Blit( ground, 0, 0, WIN_WIDTH/2, WIN_HEIGHT/2-TILE_HEIGHT/2, WIN_WIDTH*3/2, WIN_HEIGHT/2 );
break;
case 1: // 移动块10,14到5,9
ground->Blit( ground, 0, WIN_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT-TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT-TILE_HEIGHT/2 );
break;
case 2: // 移动块11,12,15,16到6,7,10,11
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT - TILE_HEIGHT/2 );
sceneX -= WIN_WIDTH/2;
sceneY -= WIN_HEIGHT/2 - TILE_HEIGHT/2;
mapX += WIN_WIDTH/TILE_WIDTH;
break;
case 3:
break;
case 4: //12
Redraw( WIN_WIDTH*2, WIN_HEIGHT-TILE_HEIGHT, mapX+9, mapY-10, WIN_WIDTH/TILE_WIDTH/2, WIN_HEIGHT/TILE_HEIGHT+2 );
break;
case 5: //4,8
Redraw( WIN_WIDTH*2, 0, mapX-1, mapY-20, WIN_WIDTH/TILE_WIDTH/2, WIN_HEIGHT/TILE_HEIGHT*2 );
break;
case 6: //13,14
Redraw( WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, mapX+5, mapY+6, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
break;
case 7: //15,16
Redraw( WIN_WIDTH*2, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, mapX+15, mapY-4, WIN_WIDTH/TILE_WIDTH, WIN_HEIGHT/TILE_HEIGHT );
status = NoRefresh;
break;
}
refreshStep ++;
}
void Cache::RefreshRight( void )
{
#ifdef DEBUG
OutDebugString( "RefreshRight" );
#endif
switch( refreshStep ){
case 0: // 移动块2,6到1,5
ground->Blit( ground, 0, 0, WIN_WIDTH/2, 0, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 1: // 移动块10,14到9,13
ground->Blit( ground, 0, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2, WIN_WIDTH/2, WIN_HEIGHT - TILE_HEIGHT/2 );
break;
case 2:
if( sceneY < WIN_HEIGHT/2 - TILE_HEIGHT/2 ) // 移动块15,16到14,15
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT*3/2 - TILE_HEIGHT/2,
WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 - TILE_HEIGHT/2 );
else // 移动块3,4到2,3
ground->Blit( ground, WIN_WIDTH/2, 0,
WIN_WIDTH, 0, WIN_WIDTH, WIN_HEIGHT/2 - TILE_HEIGHT/2 );
break;
case 3:
if( sceneY < WIN_HEIGHT/2 - TILE_HEIGHT/2 ) // 移动块3,4,7,8,11,12到2,3,6,7,10,11
ground->Blit( ground, WIN_WIDTH/2, 0, WIN_WIDTH, 0, WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2 );
else // 移动块7,8,11,12,15,16到6,7,10,11,14,15
ground->Blit( ground, WIN_WIDTH/2, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT/2 - TILE_HEIGHT/2, WIN_WIDTH, WIN_HEIGHT*3/2 - TILE_HEIGHT/2 );
sceneX -= WIN_WIDTH/2;
mapX += WIN_WIDTH/TILE_WIDTH/2;
mapY -= WIN_WIDTH/TILE_WIDTH/2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -