我目前正在学习 C,以便使用 GBDK 库和 C 编译器对原始 Game Boy 进行编程。无论出于何种原因,每当我尝试在主函数的某些部分中声明变量以及尝试在其他函数中声明变量时,C 编译器都会继续遇到解析器错误。这可能是一个问题,因为没有足够的内存空间来存储这些变量,所以解析器创建了最大数量的变量..?我不知道。
我试图在错误日志指示的行中使用不同的数据类型来解决问题(见下文)。我也试图移动声明这些变量的位置,但无济于事。 编辑:更具体地说,我改变了一些变量的声明顺序,但它只交换了解析错误所说的有问题的标记。这个问题肯定与声明的顺序有关,但只是在声明了一定数量的变量之后才发生。
这是我的源代码:
'''
#include <gb/gb.h>
#include <stdio.h>
#include "playerSprites.c"
#include "levelTileset.c"
#include "levelOne.c"
#define TRUE 1
#define FALSE 0
//Entity = x, y, sprID, direction, timer, frame, *sprites, state, type, speed, lspr, cspr, & damage.
typedef struct Entity {
UBYTE x;
UBYTE y;
UBYTE sprID; //Sprite ID
BYTE direction;
UWORD timer;
UBYTE frame;
UBYTE state; //0x80, 0x40, & 0x20 = HP/Pickup ID; 0x10, 0x08, 0x04, 0x02 = Score; 0x01 = State. --> For Non-Player Entities
//0x80, 0x40, 0x20, & 0x10 = HP; 0x08, 0x04, 0x02, & 0x01 = AP. --> For Player
UBYTE type; //0 = Player; 1 = Pushblock; 2 = Chasing Enemy; 3 = Turret Enemy; 4 = Fleeing Enemy; 5 = Pickup; 6 = Projectile; 7 = Explosive.
UWORD speed;
UBYTE lspr; //Last Sprite Index
UBYTE cspr; //Current Sprite Index
UBYTE damage;
} Entity;
//PlayerData = level, score, deaths, kills, secretsFound, overallTime[2], max_HP_AP, weapons, multipliers, cooldown, activeWeapon, powerupTimer, & currentPowerup.
typedef struct SaveData {
UBYTE level; //Current level.
UWORD score; //Total score of player.
UWORD deaths; //Number of times player has died.
UWORD kills; //Number of enemies killed.
UBYTE secretsFound;
UWORD overallTimeH; //Overall time spent playing for this save file. (HIGH)
UWORD overallTimeL; //Overall time spent playing for this save file. (LOW)
UBYTE max_HP_AP; //0x80, 0x40, 0x20, & 0x10 = Max HP; 0x08, 0x04, 0x02, & 0x01 = Max AP.
UBYTE weapons; //0x80 & 0x40 = Quake; 0x20 & 0x10 = Beam; 0x08 & 0x04 = Spreadshot; 0x02 & 0x01 = Boomer.
UBYTE multipliers; //0x80 & 0x40 = Damage Multiplier; 0x20 & 0x10 = Speed Multiplier; 0x08 & 0x04 = Point Collection Multiplier; 0x02 & 0x01 = Weapon Cooldown Multiplier.
UBYTE cooldown; //Used during combat to determine whether or not the player is able to use the currently selected weapon. Each weapon has a different cooldown rate. This value gets reset to 0 every time the player switches to a different weapon and when the game is saved at the end of each level.
UBYTE activeWeapon;
UBYTE powerupTimer;
UBYTE currentPowerup; //0 = None, 1 = Double Damage, 2 = Half Cooldown Time, 3 = Invincibility, 4 = Double Points, 5 = Double Speed.
} SaveData;
void apply_input(Entity *player);
void updatePlayerAnimation(Entity *player);
void main()
{
static Entity player;
player.x = 8U;
player.y = 16U;
player.sprID = 0U;
player.direction = 2;
player.timer = 0U;
player.frame = 0U;
player.lspr = 0U;
player.cspr = 0U;
player.state = 0x33U;
player.type = 0U;
player.speed = 4U;
player.lspr = 0U;
player.cspr = 0U;
player.damage = 1U;
SaveData player_data;
player_data.level = 0U;
player_data.score = 0U;
player_data.deaths = 0U;
player_data.kills = 0U;
player_data.secretsFound = 0U;
player_data.overallTimeH = 0U;
player_data.overallTimeL = 0U;
player_data.max_HP_AP = 0x33U;
player_data.weapons = 0x00U;
player_data.multipliers = 0x55U;
player_data.cooldown = 0U;
player_data.activeWeapon = 0U;
player_data.powerupTimer = 0U;
player_data.currentPowerup = 0U;
set_sprite_data(player.sprID, 8, PlayerSprites);
set_sprite_tile(player.sprID, player.cspr);
move_sprite(player.sprID, player.x, player.y);
set_bkg_data(0, 79, LevelTileset);
set_bkg_tiles(0, 0, 30, 43, LevelOne);
SHOW_SPRITES;
SHOW_BKG;
DISPLAY_ON;
while (TRUE)
{
apply_input(&player);
updatePlayerAnimation(&player);
}
}
void apply_input(Entity *player) {
UBYTE joypad_status = joypad();
if (joypad_status && (player->timer == 325U || player->timer == 750U))
{
UWORD speed = player->speed;
UBYTE direction = player->direction;
UBYTE sprID = player->sprID;
switch (joypad_status)
{
case J_LEFT:
if (direction == -1)
scroll_sprite(sprID, -speed, 0);
else
direction = -1;
break;
case J_RIGHT:
if (direction == 1)
scroll_sprite(sprID, speed, 0);
else
direction = 1;
break;
case J_UP:
if (direction == -2)
scroll_sprite(sprID, 0, -speed);
else
direction = -2;
break;
case J_DOWN:
if (direction == 2)
scroll_sprite(sprID, 0, speed);
else
direction = 2;
break;
case J_LEFT | J_UP:
if (direction == -2)
scroll_sprite(sprID, -speed, -speed);
else
direction = -2;
break;
case J_LEFT | J_DOWN:
if (direction == 2)
scroll_sprite(sprID, -speed, speed);
else
direction = 2;
break;
case J_RIGHT | J_UP:
if (direction == -2)
scroll_sprite(sprID, speed, -speed);
else
direction = -2;
break;
case J_RIGHT | J_DOWN:
if (direction == 2)
scroll_sprite(sprID, speed, speed);
else
direction = 2;
break;
default:
break;
}
}
}
void updatePlayerAnimation(Entity *player) {
UWORD timer = player->timer;
if (timer == 625U)
player->frame = player->frame ? 0U : 1U;
if (timer == 750U)
player->timer = 0U;
else
player->timer++;
UBYTE frame = player->frame;
switch (player->direction)
{
case -2: //UP
player->cspr = frame + 2U;
break;
case -1: //LEFT
player->cspr = frame + 6U;
break;
case 1: //RIGHT
player->cspr = frame + 4U;
break;
case 2: //DOWN
player->cspr = frame;
break;
default:
break;
}
UBYTE cspr = player->cspr;
if (player->lspr != cspr)
{
set_sprite_tile(player->sprID, cspr);
player->lspr = cspr;
}
}
'''
这是我在尝试编译时不断进入 Windows 命令控制台的错误日志:
'''
c:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o main.o main.c
main.c(67) parse error: token -> 'SaveData' ; column 16
main.c(69):error *** Undefined identifier 'player_data'
main.c(69):error *** Structure/Union expected left of '.->'
main.c(70):error *** Undefined identifier 'player_data'
main.c(70):error *** Structure/Union expected left of '.->'
main.c(71):error *** Undefined identifier 'player_data'
main.c(71):error *** Structure/Union expected left of '.->'
main.c(72):error *** Undefined identifier 'player_data'
main.c(72):error *** Structure/Union expected left of '.->'
main.c(73):error *** Undefined identifier 'player_data'
main.c(73):error *** Structure/Union expected left of '.->'
main.c(74):error *** Undefined identifier 'player_data'
main.c(74):error *** Structure/Union expected left of '.->'
main.c(75):error *** Undefined identifier 'player_data'
main.c(75):error *** Structure/Union expected left of '.->'
main.c(76):error *** Undefined identifier 'player_data'
main.c(76):error *** Structure/Union expected left of '.->'
main.c(77):error *** Undefined identifier 'player_data'
main.c(77):error *** Structure/Union expected left of '.->'
main.c(78):error *** Undefined identifier 'player_data'
main.c(78):error *** Structure/Union expected left of '.->'
main.c(79):error *** Undefined identifier 'player_data'
main.c(79):error *** Structure/Union expected left of '.->'
main.c(80):error *** Undefined identifier 'player_data'
main.c(80):error *** Structure/Union expected left of '.->'
main.c(81):error *** Undefined identifier 'player_data'
main.c(81):error *** Structure/Union expected left of '.->'
main.c(82):error *** Undefined identifier 'player_data'
main.c(82):error *** Structure/Union expected left of '.->'
error *** code not generated for 'main' due to previous errors
error *** code not generated for 'apply_input' due to previous errors
main.c(176) parse error: token -> 'UBYTE' ; column 21
main.c(196) parse error: token -> 'UBYTE' ; column 21
main.c(181):error *** Undefined identifier 'frame'
main.c(184):error *** Undefined identifier 'frame'
main.c(187):error *** Undefined identifier 'frame'
main.c(190):error *** Undefined identifier 'frame'
main.c(198):error *** Undefined identifier 'cspr'
main.c(200):error *** Undefined identifier 'cspr'
main.c(201):error *** Undefined identifier 'cspr'
error *** code not generated for 'updatePlayerAnimation' due to previous errors
c:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -o main.gb main.o
'''
当前对该代码的期望只是将动画精灵放在屏幕上,该精灵由运行游戏的任何模拟器分配给 Game Boy D-Pad 的任何键移动。但是,我什至无法判断它是否会有正确的输出,因为它甚至无法正确解析。任何帮助,将不胜感激。