你们在看了这篇教程后可能想知道这目的或这跟第六天有什么不同。老实说,没有太大不同,除了今天的地图大小是512×512,还有你可以看到怎么使地图移动。我们将要对今天的图形做一点点不同的事情。原因是我不想要一个优化的调色板。如果你一直很注意,你应该已经注意到gfx2gba通过去掉图像中没有用到的颜色来优化调色板。这很好。然而今天,当我用ham_SetTextCol()时我想用一种确切的颜色,
在之前的Photoshop处理中计算出颜色的索引号是更容易的。
在转换图片时,打入:
gfx2gba -fsrc -m -t8 -x simple_world.bmp
如果你看了gfx2gba readme,你会发现 ?x 参数可以防止它优化调色板。你也可以发现我略去了-p,因为当你用了?x参数 gfx2gba会忽略掉它。
现在你的gfx文件夹下有了下面这些文件:
simple_world.pal.c
simple_world.map.c
simple_world.raw.c
现在让我们来看代码:
// 主要的 HAM 库
#include
// 图像文件包含
// gfx2gba -fsrc -m -t8 -x simple_world.bmp
#include "gfx/simple_world.pal.c"
#include "gfx/simple_world.raw.c"
#include "gfx/simple_world.map.c"
// 全局变量
u8 newframe = 1; // Signifies a new frame
u16 map_x = 0; // X position of the map
u16 map_y = 0; // Y position of the map
// 函数声明
void vbl_func(); // VBL function
// 主程序: main()
int main()
{
// 变量
map_fragment_info_ptr bg_simple_world;
// 初始化 HAMlib
ham_Init();
// 初始化文本显示系统
ham_InitText(0);
// 设置背景模式
ham_SetBgMode(0);
// 初始化调色板
ham_LoadBGPal((void*)simple_world_Palette,256);
// 设定文本颜色
ham_SetTextCol(195, 40);
// 设置图块
ham_bg[1].ti = ham_InitTileSet( (void*)simple_world_Tiles, SIZEOF_16BIT(simple_world_Tiles),1,1);
// 设置地图
ham_bg[1].mi = ham_InitMapEmptySet(3,0);
bg_simple_world = ham_InitMapFragment( (void*)simple_world_Map,64,64,0,0,64,64,0);
// 拷贝整张地图到 BG0 坐标 x=0, y=0
ham_InsertMapFragment(bg_simple_world,1,0,0);
// 显示背景
ham_InitBg(1,1,2,0);
// 开始 VBL 中断处理程序
ham_StartIntHandler(INT_TYPE_VBL,(void*)&vbl_func);
while(1)
{
if(newframe)
{
// 写一些东西到屏幕上
ham_DrawText(1,1,"512x512 Map example");
ham_DrawText(1,2,"Use pad to scroll around");
ham_DrawText(1,17,"scroll-x: %5d",map_x);
ham_DrawText(1,18,"scroll-y: %5d",map_y);
// 让玩家可以移动地图
if(F_CTRLINPUT_DOWN_PRESSED)
{
if(map_y
ham_SetBgXY(1,map_x,++map_y);
}
if(F_CTRLINPUT_UP_PRESSED)
{
if(map_y 0)
ham_SetBgXY(1,map_x,--map_y);
}
if(F_CTRLINPUT_RIGHT_PRESSED)
{
if(map_x
ham_SetBgXY(1,++map_x,map_y);
}
if(F_CTRLINPUT_LEFT_PRESSED)
{
if(map_x 0)
ham_SetBgXY(1,--map_x,map_y);
}
newframe = 0; // 不再有新的帧
} // End of if(newframe)
} // 死循环 while(1)结束
return 0;
} // End of main()
//**********************
// Function: vbl_func()
// Purpose: VBL function
//**********************
void vbl_func()
{
newframe = 1; // 开始新的帧
return;
} // End of vbl_func()
代码解释
// 全局变量
newframe 在 main() 使用在整个循环中决定是否有新的帧。你可能会想,“新的帧什么时候产生?” 很好, 在每个 vertical blank (VBL)中断发生时。
对你们 map_x 和 map_y 应该非常清楚。 它们是显示在屏幕上的地图的左上角的坐标。
现在看 main() 函数
// 设置文本颜色
ham_SetTextCol(195, 40);
这应该是计算出相当简单的函数。基本上你想要前景和背景字体颜色要通过背景调色板索引值。你会问,“我怎么计算出索引值?” 很好,看一下 Graphics FAQ. 如果你看了 simple_world.bmp和其调色板, 你就会发现 195 是红色,40 是一种紫色。
//为我们的图像设置 map
ham_bg[1].mi = ham_InitMapEmptySet(3,0);
mymap = ham_InitMapFragment(&simple_world_Map,64,64,0,0,64,64,0);
希望你注意到我传递了 64,64 而不是 30,20。 为什么我这么做? 好的,我建立起一个512x512象素 而不是240x160象素的背景地图。
现在让我们来研究 while(1)
if(newframe)...
这将在每个VBL中断被设成 1, 或 true。
if(F_CTRLINPUT_DOWN_PRESSED)... if(map_y
这将允许地图往下移动如果它没有到达底部的话。
不知道为什么我们用 512 ? 160? 好的, 屏幕的高度有 160 象素。 图像的高度有 512 象素。当地图在屏幕底部时,图像的顶部将会在 512 ? 160象素。
还是不清楚? Click here.
ham_SetBgXY(...)
这个函数可以用来滚动地图。你通过BG号,新的 X 轴偏移量, 和新的 Y 轴偏移量。你将会发现我使用了 prefix incrementation/decrementation (前置增减量)在 map_x 和 map_y之前。比方说,当使用者摁下 DOWN按钮, map_y 得到一个增量。 注意: 这个函数不能用于 rotation backgrounds(可旋转背景,区别与text backgrounds)。
在这里你需要再知道一个事情 ? tiles(图块)。 你一次加载的图块数量的极限是- 651 (我相信). 因为我们的图像是 512x512 象素,我一次加载了整个图像,这个我必须考虑。 当你运行 gfx2gba 你会发现在优化前有 4096 个图块优化后只有431个。 如果我的图像再复杂一点,这将会出现一个问题,我将必须不同地加载图像。这类的屏幕滚动有两种方法,这是其中最简单地一种。
对于第九天来说已经够多了,我希望这不是太难。
HAM教程第十天翻译本
今天的教程跟第八天的很相似,除了我们要使飞机活动起来,使它的发动机看起来好像在旋转。我从第八天的图开始,在作些处理。你可以看 这里 来明白我的意思。为了节省时间,我决定飞机只可以在上、下、左、右四个方向移动,而不允许在对角线上。
这次的教程的一个目的是让你对定时器有个基本的了解。你必须确定明白帧变量和怎么用它来使发动机动起来。你会注意到这基本上跟第七天的vbl_count 一样。还要注意animcnt 是怎么被用的――这非常重要。
用下面的命令转换图片:
gfx2gba -fsrc -m -pbackground.pal -t8 water.bmp
sprite 没有转换成tile/map格式,所以再打入:
gfx2gba -D -fsrc -pobject.pal -t8 red_plane_anim.bmp
你的gfx 文件夹将会有下面这些文件:
background.pal.c
object.pal.c
red_plane_anim.raw.c
water.map.c
water.raw.c
看代码:
//主要的HAM 库
#include
// 图形文件包含
// gfx2gba -fsrc -m -pbackground.pal -t8 water.bmp
#include "gfx/background.pal.c"
#include "gfx/water.raw.c"
#include "gfx/water.map.c"
// gfx2gba -D -fsrc -pobject.pal -t8 red_plane_anim.bmp
#include "gfx/object.pal.c"
#include "gfx/red_plane_anim.raw.c"
// 定义宏
#define ANIM_UP 0
#define ANIM_RIGHT 1
#define ANIM_DOWN 2
#define ANIM_LEFT 3
// 全局变量
u32 dir_plane = ANIM_RIGHT; // 飞机方向
u8 plane; // 飞机的Sprite 索引
u32 plane_x = 110; // X 坐标
u32 plane_y = 50; // Y 坐标
u32 animcnt = 0; // 动画的当前帧
u32 frames = 0; // 全局帧计数器
u32 array_spot = 0; // Sprite的当前图像位置
// Function Prototypes
void vbl_func(); // VBL 函数
void query_buttons(); // 查询输入
void update_plane_gfx(); // 更新飞机的图像
void update_plane_pos(); // 更新飞机的位置
// 主函数:main()
int main()
{
//变量
map_fragment_info_ptr bg_water; // 背景指针
// 初始化 HAM库
ham_Init();
// 设定背景显示模式
ham_SetBgMode(1);
// 初始化调色板
ham_LoadBGPal((void*)background_Palette,256);
ham_LoadObjPal((void*)object_Palette,256);
// 为我们的图像设置图块
ham_bg[0].ti = ham_InitTileSet( (void*)water_Tiles,SIZEOF_16BIT(water_Tiles),1,1);
// 设置地图
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_water = ham_InitMapFragment( (void*)water_Map,30,20,0,0,30,20,0);
ham_InsertMapFragm