📄 sprite.c
字号:
#include <GsGBA.h>
#include "data.h"
#include "sprite.h"
#include "bomb.h"
GsSPRITE blut,player,bomb; //标准的子弹和一个主角飞机
SOBJ sprite_list[61]; //精灵列表 一共61个角色
void LoadGfx() //度入所有图象数据
{
//打开所有中断
GsOpenIRQ();
//设置BG模式为0
GsSetMode( MODE_0 | DISP_OBJ_CHAR_2D_MAP);
//初始化BG
GsInitBG();
//设置BG寄存器
GsSetBg(0 , Gs_BG_TEXT_SIZE_256x256 , Gs_BG_COLOR16, 0 ,28 , 0);
//设置优先级
GsBgPriority(0,1);
//设置BG开关
GsSetBgState(0,ON);
GsSetBgState(1,OFF);
GsSetBgState(2,OFF);
GsSetBgState(3,OFF);
//将背景图片载入VRAM
GsRGXLoad(bin_map,0,28,0);
//将所有角色图像资料送入VRAM
GsLoadObjPal16(GsRGXGetPal(bin_obj) , OPAL_OBJ);
GtLoadObjChar2D(GsRGXGetTile(bin_obj) ,16,32, CNO_OBJ); //16 X 32
GsLoadObjPal16(GsRGXGetPal(bin_blut) , OPAL_BLUT);
GtLoadObjChar2D(GsRGXGetTile(bin_blut) ,8,8, CNO_BLUT); //8 X 8
GsLoadObjPal16(GsRGXGetPal(bin_bomb) , OPAL_BOMB);
GtLoadObjChar2D(GsRGXGetTile(bin_bomb) ,160,32,CNO_BOMB); //160 X 32
}
void SOBJ_RESET() //所有OBJ复位
{
int i;
player.obj.HPos=240;
player.obj.VPos=160;
player.obj.Shape=Gs_OAM_VRECT; //子弹是16x8 大小的
player.obj.Size=Gs_OAM_BIG;
player.obj.Priority=1; //设置有先级为1
player.obj.Pltt=OPAL_OBJ; //设置调色盘
player.obj.CharNo=CNO_OBJ; //设置子弹在VRAM中的贴图
blut.obj.HPos=240;
blut.obj.VPos=160;
blut.obj.Shape=Gs_OAM_SQUARE; //子弹是8x8 大小的
blut.obj.Size=Gs_OAM_SMALL;
blut.obj.Priority=0; //设置有先级为0
blut.obj.Pltt=OPAL_BLUT; //设置调色盘
blut.obj.CharNo=CNO_BLUT; //设置子弹在VRAM中的贴图
bomb.obj.HPos=240;
bomb.obj.VPos=160;
bomb.obj.Shape=Gs_OAM_SQUARE; //爆炸是32x32 大小的
bomb.obj.Size=Gs_OAM_BIG;
bomb.obj.Priority=0; //设置有先级为0
bomb.obj.Pltt=OPAL_BOMB; //设置调色盘
bomb.obj.CharNo=CNO_BOMB; //设置子弹在VRAM中的贴图
//设置主角的开始位置
sprite_list[0].flag=SPR_NULL;
sprite_list[0].obj=&player;
sprite_list[0].flag=SPR_ALIVE;
player.obj.HPos=sprite_list[0].mb.ln_x=100;
player.obj.VPos=sprite_list[0].mb.ln_y=70;
//设置精灵列表的开始位置和动画参数
for(i=1;i<60;i++) //子弹
{
sprite_list[i].flag=SPR_NULL;
sprite_list[i].obj=&blut;
}
sprite_list[60].flag=SPR_NULL;
sprite_list[60].obj=&bomb;
bomb_flag=0;
}
void SOBJ_Process() //处理所有OBJ
{
int i=0,j=0;;
GsClearOamBufferRam(); //首先将OAM清空
for(i=0;i<61;i++)
{
switch(sprite_list[i].flag)
{
case SPR_ALIVE: //如果,角色是活的
if(i>0 && i!=60) //如果不是主角(因为主角是玩家控制的)
{ //也不是爆炸
MB_Move(&sprite_list[i].mb); //移动
SOBJ_POSION(&sprite_list[i]); //坐标更新
if(SOBJ_COLLISION(i)==1) //主角和子弹碰撞检测 [1,59]
{
if(bomb_flag!=1) //如果没有爆炸(如果爆炸的话,就不需要再次爆炸了)
BOMB_Set(); //主角爆炸!!
}
}
//将SPRITE写到OAM中去
sprite_list[i].obj->ID=j; //得到OAM编号
GsSortSPRITE(sprite_list[i].obj); //写到OAM里去
j++;
break;
case SPR_DEAD:
sprite_list[i].flag=SPR_NULL;
break;
}
}
}
void SOBJ_POSION(SOBJ *p) //坐标更新
{
p->obj->obj.HPos=p->mb.ln_x; //ln_x是当前的X
p->obj->obj.VPos=p->mb.ln_y; //ln_y是当前的Y
if(p->mb.ln_x <0 || p->mb.ln_x>240) //如果横坐标在屏幕之外,那么返回3
p->flag=SPR_DEAD;
if(p->mb.ln_y <0 || p->mb.ln_y>160)
p->flag=SPR_DEAD;
}
int SOBJ_COLLISION (int i) //碰撞检测 子弹和主角的
{
GsRect rc1,rc2;
rc1.left =player.obj.HPos;
rc1.top =player.obj.VPos;
rc1.right =player.obj.HPos+16;
rc1.bottom=player.obj.VPos+32;
rc2.left =sprite_list[i].mb.ln_x;
rc2.top =sprite_list[i].mb.ln_y;
rc2.right =sprite_list[i].mb.ln_x+4;
rc2.bottom=sprite_list[i].mb.ln_y+4;
if(rc1.top > rc2.bottom || rc1.bottom < rc2.top) //不发生碰撞
return 0;
if(rc1.left > rc2.right || rc1.right < rc2.left) //不发生碰撞
return 0;
return 1; //碰撞
}
int SOBJ_BLUT_EMIT() //子弹发射器
{ //从上到下,瞄准主角发射
int i=GTIMER%60+1;
static pos;
if(sprite_list[i].flag==SPR_NULL)
{
if(GTIMER%4==0) //顶部发子弹
{
sprite_list[i].flag=SPR_ALIVE; //使一个子弹活
MB_StartMove(
&sprite_list[i].mb,
pos,0,
player.obj.HPos+8,player.obj.VPos+16
);
pos=(pos+8)%240;
}
if(GTIMER%4==4) //底部发子弹
{
sprite_list[i].flag=SPR_ALIVE; //使一个子弹活
MB_StartMove(
&sprite_list[i].mb,
pos,159,
player.obj.HPos+8,player.obj.VPos+16
);
pos=(pos+8)%240;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -