到了第11天我将说明怎么旋转背景。 HAM 做这个很简单,只要用 RotBgEx() 函数。这个函数十分强大,它不仅能旋转背景还能放大缩小还有卷动背景。注意: 还有一个叫做 RotBg() 的函数, 但是我更喜欢 RotBgEx() 因为你除了旋转还可以控制更多。
噢,不要忘了。你只能在模式1和模式2中旋转。 在模式1中,背景2可以旋转/缩放。在模式2中,背景2和背景3可以旋转/缩放。如果你忘了请再看一下 Day 1 。
用下面这句转换图片:gfx2gba -fsrc -m -protate.pal -rs -t8 rotate.bmp
你的 gfx 文件夹下会有下面这些文件:rotate.map.crotate.pal.c
rotate.raw.c
下面看代码:
// 主要 HAM 库#include "mygba.h"
// 包含图形头文件// gfx2gba -fsrc -m -protate.pal -rs -t8 rotate.bmp#include "gfx/rotate.map.c"
#include "gfx/rotate.pal.c"
#include "gfx/rotate.raw.c"
// 全局变量u32 frames = 0;
u32 zoomx = 256; // X co-ordinate of zoom centeru32 zoomy = 256; // Y co-ordinate of zoom centeru32 scrollx = 64; // X co-ordinate of scrolling centeru32 scrolly = 64; // Y co-ordinate of scrolling centerbool zoomin = 1;
// 函数声明void vblFunc(); // 中断函数VBLvoid query_keys(); // 检查按键状态void redraw(); // 重画屏幕
// Main主函数int main()
{
// 初始化
HAMlib ham_Init();
// 设定背景模式为Mode1
ham_SetBgMode(1);
// 初始化调色板
ham_LoadBGPal(&rotate_Palette,256);
// 背景调色板
// 初始化转动的背景
ham_bg[2].ti = ham_InitTileSet(&rotate_Tiles,SIZEOF_16BIT(rotate_Tiles),1,1);
ham_bg[2].mi = ham_InitMapSet(&rotate_Map,256,0,1);
// 显示背景
ham_InitBg(2,1,1,0);
//移动背景到屏幕中央
ham_RotBgEx(2,0,120,80,scrollx,scrolly,zoomx,zoomy);
// 打开 VBL 中断函数
ham_StartIntHandler(INT_TYPE_VBL,&vblFunc);
while(1)
{
// 死循环
}
return EXIT_SUCCESS;
} // 主程序尾
// 中断函数VBL
void vblFunc()
{
ham_CopyObjToOAM();
// 把 精灵 拷贝到内存的OAM中
query_keys();
// 检查按键
redraw();
// 重画飞机
// 旋转背景
ham_RotBgEx(2,frames%360,120,80,scrollx,scrolly,zoomx,zoomy);
// 帧自增1
++frames;
return;
} // End of vblFunc()
// 检查按键
void query_keys()
{
// 只按RIGHT键 if (F_CTRLINPUT_RIGHT_PRESSED)
{
if (scrollx
}
// 只按LEFT键 if (F_CTRLINPUT_LEFT_PRESSED)
{
if (scrollx 0) --scrollx;
}
// 只按START键
if (F_CTRLINPUT_START_PRESSED) {
scrollx = 64;
scrolly = 64;
}
return;
} // End of query_keys()
// 重画屏幕
void redraw()
{
if (zoomin) { // 放大
if (zoomx != 396) {
zoomx+=2;
zoomy+=2;
} else {
zoomin = FALSE;
}
} else { // 缩小
if (zoomx != 116) {
zoomx-=2;
zoomy-=2;
} else {
zoomin = TRUE;
}
}
return;
} // End of redraw()
代码解释
// 全局变量
u32 zoomx=256;u32 zoomy=256;这两个分别表示在X方向和Y方向的缩放量。在HAM文档中,你可以看到作者用0x100(=256)表示没有缩放。 数字增加放大,反之减小。
u32 scrollx=64;u32 scrolly=64;这两个变量对应图像的旋转轴的X和Y坐标。这次我全设置成64代表旋转轴在图像中心(原始图像大小为128x128象素)。当心,不要尝试把坐标定在图像的边界外。我们待会再详细说明。
// Main()
你将会注意到这次我加载背景的方法跟前几天不同。这次的方法更短,尽管两种方法都可以。// 初始化旋转背景ham_bg[2].ti = ham_InitTileSet(&rotate_Tiles,SIZEOF_16BIT(rotate_Tiles),1,1);这个调用刚好一样,下面的部分就不同了。ham_bg[2].mi = ham_InitMapSet(&rotate_Map,256,0,1);第一个参数就是背景map数组。接下来就是“将要拷贝到BG显存中的Tile大小,是个16位数字。”下一个数字是建立在最后一个参数 (是否为可旋转)的基础上的。所以128x128大小的图像做旋转背景对应的数字是0。最后的的参数是1,因为是旋转背景。
注意: 你可以用下面的代码完成同样的事:
// 变量
map_fragment_info_ptr bg_rotate; // 背景指针
// 为图像安装tile
ham_bg[2].ti = ham_InitTileSet(&rotate_Tiles,SIZEOF_16BIT(rotate_Tiles),1,1);
// 安装map
ham_bg[2].mi = ham_InitMapEmptySet(0,1);
bg_rotate = ham_InitMapFragment(&rotate_Map,16,16,0,0,16,16,1);
ham_InsertMapFragment(bg_rotate,2,0,0);
// 显示背景
ham_InitBg(2,1,0,0);
// 移动背景到中央
ham_RotBgEx(2,0,120,80,scrollx,scrolly,zoomx,zoomy);
这是RotBgEx() 函数的隐含工作。就像我说的,这是个功能很强的函数。我现在只用它把背景移到中央,而没有旋转。我待会会在VBL中断函数中旋转并且解释参数。
// VBL function
// 旋转背景
ham_RotBgEx(2,frames%360,120,80,scrollx,scrolly,zoomx,zoomy);
Okay, 现在的这个才是真正的旋转(和缩放)。 第一个参数代表背景号。(它只能是2或3,因为背景0和1不能旋转) 。接下来的是旋转的角度。frames%360 的值会在 0 ? 359间。 再接下来的是旋转中心的X和Y坐标。我使它位于120,80几乎是屏幕的中心。在这里停一下以确定你真的明白了。这就是图像将要绕着转的点。然后你传递的X和Y坐标是卷轴的偏移量。这就是旋转中心点在图像上位置。我选择了64,64 (又几乎是图像的中心)。多花了一些时间得到一个合适的图片。图片的中心将会跟着屏幕的中心转。最后你传入X方向上的缩放和Y方向上的缩放。它从256开始算起(或者是十六进制的 0x100),意思是没有缩放。如果你看了重画函数,你将会看到怎么修正zoomx 和 zoomy 。
// query_keys()
if (scrollx 0) --scrollx;当演示程序运行时,使用者可以按 左 或 右 来移动图像的旋转中心点。比方说,如果你一直按 左,图像将会围绕中间左侧旋转。注意字母'R'接近中心。如果你按 右 键,图像将会绕左侧旋转,接近中心的是字母'e'。 噢,如果你按了 Start 键将会回到中心。
// redraw()
这里的这段代码不难。我设置了最大的缩放在116和396之间。当到达了界限时,我把放大改成缩小,或把缩小改成放大。
啊,今天就到这里吧。下一天,下一节精彩的课将关于用HAM编GBA程序的精美艺术。 你毫无疑问应该在学习第十二课以前,尽你所能修改今天的代码,看看RotBgEx() 函数的所有功能。
HAM教程第十二天翻译本
我想是时候学一种简单且依然很酷的特效――马赛克。今天我们做马赛克用在sprite上,明天我们再把它同背景核对。今天的大部分代码将会跟第八天和第十天相似。
注意: 我的图片是从这里免费得到的。
控制:Up ? 马赛克纵向增大Down ? 马赛克纵向减小Left ? 马赛克横向减小Right ? 马赛克横向增大Start ? 复位到没有马赛克
// The Main HAM Library
#include "mygba.h"
// Graphics Includes
#include "gfx/background.pal.c" // Created from water.bmp
#include "gfx/object.pal.c" // Created from ship.bmp
#include "gfx/ship.raw.c" // gfx2gba -D -fsrc -pobject.pal -t8 ship.bmp
#include "gfx/water.map.c" // gfx2gba -fsrc -m -pbackground.pal -t8 water.bmp
#include "gfx/water.raw.c"
// Global Variables
u8 ship[1]; // Sprite index for the ship
u8 new_frame = 0; // 0 = true, 1 = false
u16 curr_frame = 1; // Current frame
u8 mosaic_h = 0; // Mosaic horizontal amount
u8 mosaic_v = 0; // Mosaic vertical amount
// Function Prototypes
void vblFunc(); // VBL function
void query_keys(); // Query for input
void redraw(); // Redraw sprites
// Main function
int main()
{
// Variables
map_fragment_info_ptr bg_water; // Pointer to our background
// Initialize HAMlib
ham_Init();
// Setup the background mode
ham_SetBgMode(1);
// Initialize the palettes
ham_LoadBGPal(&background_Palette,256); // Background palette
ham_LoadObjPal(&object_Palette, 256); // Sprite palette