Homebrew Sprite GFX issue with NightFox Lib

infamousjcv

Active Member
OP
Newcomer
Joined
Nov 12, 2020
Messages
31
Trophies
0
Age
22
XP
211
Country
United States
I am having trouble getting two sprites to show on screen. My goal is to attempt to get two square sprites to appear on screen.

Here is the error image:
desmume-screenshot-0.png


Now, I have tried constantly to fix this, but to no avail. As far as I know, it should be working as I've assigned different Ram and VRAM GFXs, and different Ram and VRAM Pal IDs for each sprite.

I've made C++ classes for both objects. The code is shown here:

Player.h

C++:
#ifndef PLAYER_H
#define PLAYER_H
#include <nds.h>
#include <nf_lib.h>

class Player {
    
    public:
        Player() {

        }

        Player(s16 x_pos, s16 y_pos, s16 width, s16 height, const char* name, u8 screen, u16 palid, u16 gfxid, u16 vram, u16 vramPALSLOT, u16 sprID)
        {
            x = x_pos;
            y = y_pos;
            w = width;
            h = height;
            sprite_name = name;
            player_screen = screen;
            gfxid = gfxid;
            palid = palid;
            vramGFX = vram;
            vrampalSLOT = vramPALSLOT;
            spriteID = sprID;

        }

        void createSprite()
        {
            NF_LoadSpriteGfx(sprite_name,gfxid,w,h);
            NF_LoadSpritePal(sprite_name,palid);
            NF_VramSpriteGfx(player_screen,gfxid,vramGFX,TRUE);
            NF_VramSpritePal(player_screen,palid,vrampalSLOT);
        }

        void moveX(s16 moveAmount) {
            x+=moveAmount;
        }
    
        void moveY(s16 moveAmount) {
            y+=moveAmount;
        }

        void moveSprite() {
            NF_CreateSprite(player_screen,spriteID,vramGFX,vrampalSLOT,x,y);
        }


    protected:
        s16 x;
        s16 y;
        s16 w;
        s16 h;
        const char* sprite_name;
        u8 player_screen;
        u16 gfxid;
        u16 palid;
        u16 vramGFX;
        u16 vrampalSLOT;
        u16 spriteID;
};

#endif //PLAYER_H

FoodObject.h

C++:
#ifndef FOODOBJECT_H
#define FOODOBJECT_H

#include <nds.h>
#include <nf_lib.h>
#include "Player.h"


class FoodObject : public Player {

    public:
        FoodObject(s16 x_pos, s16 y_pos, s16 width, s16 height, const char* name, u8 screen, u16 gfxID, u16 palID, u16 vram, u16 vramPALSLOT, u16 sprID)
        {
            x = x_pos;
            y = y_pos;
            w = width;
            h = height;
            enemy_name = name;
            enemy_screen = screen;
            gfxid = gfxid;
            palid = palid;
            vramGFX = vram;
            vrampalSLOT = vramPALSLOT;
            spriteID = sprID;
        }

        // void createSprite()
        // {
        //     NF_LoadSpriteGfx(sprite_name,gfxid,w,h);
        //     NF_LoadSpritePal(sprite_name,palid);
        //     NF_VramSpriteGfx(player_screen,ram,vram,false);
        //     NF_VramSpritePal(player_screen,vrampalID,vrampalSLOT);
        // }

        // void moveX(s16 moveAmount) {
        //     x+=moveAmount;
        // }
    
        // void moveY(s16 moveAmount) {
        //     y+=moveAmount;
        // }

        void moveSprite() {
            NF_CreateSprite(player_screen,spriteID,vramGFX,vrampalSLOT,x,y);
        }

    private:
        const char* enemy_name;
        u8 enemy_screen;
        
};



#endif

main.cpp

C++:
#include <nds.h>
#include <nf_lib.h>
#include "Player.h"
#include "FoodObject.h"


void initSystem() {
    NF_Set2D(0,0);
    NF_Set2D(0,1);
    NF_InitTiledBgBuffers();
    NF_InitTiledBgSys(0);
    NF_InitSpriteBuffers();
    NF_InitSpriteSys(0);
    NF_SetRootFolder("NITROFS");

}

int main() {
    initSystem();
    NF_LoadTiledBg("clearbackground","Background",256,256);
    NF_CreateTiledBg(0,3,"Background");

    Player player1(256/2 - 16/2,192 - 35,16,16,"box",0,0,0,0,0,0);
    FoodObject foodObj(256/2 - 16/2,0,16,16,"spr",0,64,1,10,3,21);
    player1.createSprite();
    foodObj.createSprite();
    // player1.moveSprite();
    // foodObj.moveSprite();
    
    consoleDemoInit();

    while (1)
    {
        scanKeys();
        NF_SpriteOamSet(0);
        swiWaitForVBlank();
        oamUpdate(&oamMain);

        // foodObj.moveY(3);
        // foodObj.moveSprite();

        // if (KEY_LEFT & keysHeld())
        // {
        //     player1.moveX(-5);
        //     player1.moveSprite();
        // }
        // else if (KEY_RIGHT & keysHeld())
        // {
        //     player1.moveX(5);
        //     player1.moveSprite();
        // }
    }
    return 0;
}

Any idea as to what could be causing this issue?
 

plasturion

temporary hermit
Member
Joined
Aug 17, 2012
Messages
825
Trophies
1
Location
Tree
XP
2,483
Country
Poland
hard to say but it seems FoodObject should have better definition.. My doubts are when you try to set up some private vars inside a class so...
gfxid = gfxid;
palid = palid;
seems valid, so it doesn't show up any error but it doesnt changes anything either because it indicates the same var, so maybe it should be changed to:
this->gfxid = gfxid;
this->palid = palid;
or change it's name slightly like you did for other vars (in example "gfxID"). But maybe I'm wrong.
 
Last edited by plasturion,

infamousjcv

Active Member
OP
Newcomer
Joined
Nov 12, 2020
Messages
31
Trophies
0
Age
22
XP
211
Country
United States
hard to say but it seems FoodObject should have better definition.. My doubts are when you try to set up some private vars inside a class so...
gfxid = gfxid;
palid = palid;
seems valid, so it doesn't show up any error but it doesnt changes anything either because it indicates the same var, so maybe it should be changed to:
this->gfxid = gfxid;
this->palid = palid;
or change it's name slightly like you did for other vars (in example "gfxID"). But maybe I'm wrong.

I have solved the issue. I had initially assumed that the RAM and VRAM GFX, and PAL were different for each instance of the sprite made. It turns out that for something like this, you really only need two ids for the RAM and VRAM GFX and PAL.

My problem now is deleting an instance of the sprite. When I do this, it gives the error :

desmume-screenshot-0.png


This is what the code looks like as of now:

main.cpp
C++:
#include <nds.h>
#include <nf_lib.h>
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <ctime>
#include <iostream>

using namespace std;

struct PlayerObject {
    s16 x;
    s16 y;
    u16 sprID;
};

struct FallObject {
    s16 x;
    s16 y;
    bool falling;
    u16 sprID;
};


void initSystem() {
    NF_Set2D(0,0);
    NF_Set2D(0,1);
    NF_InitTiledBgBuffers();
    NF_InitTiledBgSys(0);
    NF_InitSpriteBuffers();
    NF_InitSpriteSys(0);
    NF_SetRootFolder("NITROFS");

}

void loadSprite(u8 screen, const char* sprite_name, u16 gfxRAM, u16 w, u16 h, u16 palRAM, u16 gfxVRAM, bool keep, u16 palVRAM)
{
    NF_LoadSpriteGfx(sprite_name,gfxRAM,w,h);
    NF_LoadSpritePal(sprite_name,palRAM);
    NF_VramSpriteGfx(screen,gfxRAM,gfxVRAM,keep);
    NF_VramSpritePal(screen,palRAM,palVRAM);
}

void loadResources()
{
    loadSprite(0,"box",0,16,16,0,0,true,0);
    loadSprite(0,"food",1,16,16,1,1,true,1);
}

void updateSprite(u8 screen, u16 spriteID, u16 gfxVRAM, u16 palVRAM, s16 x, s16 y)
{
    NF_CreateSprite(screen,spriteID,gfxVRAM,palVRAM,x,y);
}

FallObject createFallObject(s16 x, s16 y, u16 sprID)
{
    FallObject fallObj;
    fallObj.x = x;
    fallObj.y = y;
    fallObj.falling = TRUE;
    fallObj.sprID = sprID;

    return fallObj;
}

void startGame()
{
    initSystem();
    loadResources();
    srand(time(NULL));
    NF_LoadTiledBg("clearbackground","Background",256,256);
    NF_CreateTiledBg(0,1,"Background");
    u16 spriteID = 1;
    s16 x_positions[3] = {0 + 50, 256/2 - 16/2, 256 - 50};
    std::vector<FallObject> objects;
    std::vector<FallObject> deletedObjects;

    float spawnDelay = 10.00;
    float dt = 0.20;
    float spawnTimer = 0;
    s16 spriteID_MAX = 127;
    PlayerObject p1;
    p1.x = 256/2 - 16/2;
    p1.y = 192 - 35;
    p1.sprID = 0;
    updateSprite(0,p1.sprID,0,0,p1.x,p1.y);

    consoleDemoInit();

    while (1)
    {
        spawnTimer += dt;
        cout << spriteID << endl;
        if (spawnTimer > spawnDelay)
        {
            if (spriteID >= spriteID_MAX)
            {
                spriteID = 1;
            }

            s16 randomNum = rand() % 3 + 0;
            objects.push_back(createFallObject(x_positions[randomNum],-16,spriteID));
            spawnTimer = 0;
            spriteID++;

        }

        scanKeys();
        NF_SpriteOamSet(0);
        swiWaitForVBlank();
        oamUpdate(&oamMain);

        for (size_t i = 0; i < objects.size(); i++)
        {
            objects[i].y += 4;

            if ((p1.x < objects[i].x + 16) && (p1.x + 16 > objects[i].x))
            {
                if ((p1.y < objects[i].y + 16) && (p1.y + 16 > objects[i].y))
                {
                    objects[i].falling = FALSE;
                }
            }

            if (objects[i].falling == TRUE)
                updateSprite(0,objects[i].sprID,0,0,objects[i].x,objects[i].y);
            else
                NF_DeleteSprite(0,objects[i].sprID);

            if (objects[i].y >= 192)
            {
                objects[i].falling = FALSE;
            }
            

        }

        if (keysHeld() & KEY_LEFT) {

            if (p1.x <= 0)
            {
                p1.x-=0;
            }
            else
            {
                p1.x-=4;
            }
            updateSprite(0,0,0,0,p1.x,p1.y);
        }
        else if (keysHeld() & KEY_RIGHT) {

            if (p1.x + 16 >= 256)
            {
                p1.x+=0;
            }
            else
            {
                p1.x+=4;
            }
            updateSprite(0,0,0,0,p1.x,p1.y);
        }

    }
}

int main() {
    startGame();
    return 0;
}
 

aerglass

Well-Known Member
Newcomer
Joined
Apr 10, 2022
Messages
89
Trophies
0
Age
42
Location
earth
XP
205
Country
United States
I have solved the issue. I had initially assumed that the RAM and VRAM GFX, and PAL were different for each instance of the sprite made. It turns out that for something like this, you really only need two ids for the RAM and VRAM GFX and PAL.

My problem now is deleting an instance of the sprite. When I do this, it gives the error :

View attachment 316491

This is what the code looks like as of now:

main.cpp
C++:
#include <nds.h>
#include <nf_lib.h>
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <ctime>
#include <iostream>

using namespace std;

struct PlayerObject {
    s16 x;
    s16 y;
    u16 sprID;
};

struct FallObject {
    s16 x;
    s16 y;
    bool falling;
    u16 sprID;
};


void initSystem() {
    NF_Set2D(0,0);
    NF_Set2D(0,1);
    NF_InitTiledBgBuffers();
    NF_InitTiledBgSys(0);
    NF_InitSpriteBuffers();
    NF_InitSpriteSys(0);
    NF_SetRootFolder("NITROFS");

}

void loadSprite(u8 screen, const char* sprite_name, u16 gfxRAM, u16 w, u16 h, u16 palRAM, u16 gfxVRAM, bool keep, u16 palVRAM)
{
    NF_LoadSpriteGfx(sprite_name,gfxRAM,w,h);
    NF_LoadSpritePal(sprite_name,palRAM);
    NF_VramSpriteGfx(screen,gfxRAM,gfxVRAM,keep);
    NF_VramSpritePal(screen,palRAM,palVRAM);
}

void loadResources()
{
    loadSprite(0,"box",0,16,16,0,0,true,0);
    loadSprite(0,"food",1,16,16,1,1,true,1);
}

void updateSprite(u8 screen, u16 spriteID, u16 gfxVRAM, u16 palVRAM, s16 x, s16 y)
{
    NF_CreateSprite(screen,spriteID,gfxVRAM,palVRAM,x,y);
}

FallObject createFallObject(s16 x, s16 y, u16 sprID)
{
    FallObject fallObj;
    fallObj.x = x;
    fallObj.y = y;
    fallObj.falling = TRUE;
    fallObj.sprID = sprID;

    return fallObj;
}

void startGame()
{
    initSystem();
    loadResources();
    srand(time(NULL));
    NF_LoadTiledBg("clearbackground","Background",256,256);
    NF_CreateTiledBg(0,1,"Background");
    u16 spriteID = 1;
    s16 x_positions[3] = {0 + 50, 256/2 - 16/2, 256 - 50};
    std::vector<FallObject> objects;
    std::vector<FallObject> deletedObjects;

    float spawnDelay = 10.00;
    float dt = 0.20;
    float spawnTimer = 0;
    s16 spriteID_MAX = 127;
    PlayerObject p1;
    p1.x = 256/2 - 16/2;
    p1.y = 192 - 35;
    p1.sprID = 0;
    updateSprite(0,p1.sprID,0,0,p1.x,p1.y);

    consoleDemoInit();

    while (1)
    {
        spawnTimer += dt;
        cout << spriteID << endl;
        if (spawnTimer > spawnDelay)
        {
            if (spriteID >= spriteID_MAX)
            {
                spriteID = 1;
            }

            s16 randomNum = rand() % 3 + 0;
            objects.push_back(createFallObject(x_positions[randomNum],-16,spriteID));
            spawnTimer = 0;
            spriteID++;

        }

        scanKeys();
        NF_SpriteOamSet(0);
        swiWaitForVBlank();
        oamUpdate(&oamMain);

        for (size_t i = 0; i < objects.size(); i++)
        {
            objects[i].y += 4;

            if ((p1.x < objects[i].x + 16) && (p1.x + 16 > objects[i].x))
            {
                if ((p1.y < objects[i].y + 16) && (p1.y + 16 > objects[i].y))
                {
                    objects[i].falling = FALSE;
                }
            }

            if (objects[i].falling == TRUE)
                updateSprite(0,objects[i].sprID,0,0,objects[i].x,objects[i].y);
            else
                NF_DeleteSprite(0,objects[i].sprID);

            if (objects[i].y >= 192)
            {
                objects[i].falling = FALSE;
            }
           

        }

        if (keysHeld() & KEY_LEFT) {

            if (p1.x <= 0)
            {
                p1.x-=0;
            }
            else
            {
                p1.x-=4;
            }
            updateSprite(0,0,0,0,p1.x,p1.y);
        }
        else if (keysHeld() & KEY_RIGHT) {

            if (p1.x + 16 >= 256)
            {
                p1.x+=0;
            }
            else
            {
                p1.x+=4;
            }
            updateSprite(0,0,0,0,p1.x,p1.y);
        }

    }
}

int main() {
    startGame();
    return 0;
}

your code is somewhat ineficient but whatever, the error says it all, sprite 1 on the top screen is not created, you may have created the object with another id, but because of your code, if you delete a sprite, it will regenerate it self, i would recomend set the obj position using NF_MoveSprite

sorry if this was too complicated but i am not the best at explaining things
 
  • Like
Reactions: infamousjcv

infamousjcv

Active Member
OP
Newcomer
Joined
Nov 12, 2020
Messages
31
Trophies
0
Age
22
XP
211
Country
United States
your code is somewhat ineficient but whatever, the error says it all, sprite 1 on the top screen is not created, you may have created the object with another id, but because of your code, if you delete a sprite, it will regenerate it self, i would recomend set the obj position using NF_MoveSprite

sorry if this was too complicated but i am not the best at explaining things

You're right about MoveSprite. I guess what happened was that there were some things that didn't appear in the documentation that I wasn't aware of.

Also, could you explain more about the inefficiency? I am not a very experience programmer, and any tips are useful.

EDIT: Turns out it WAS in the API. I just didn't read it properly. My fault entirely.
 
Last edited by infamousjcv,

infamousjcv

Active Member
OP
Newcomer
Joined
Nov 12, 2020
Messages
31
Trophies
0
Age
22
XP
211
Country
United States
I have changed my code so that it uses NF_MoveSprite to move the sprites, but it still gives the same error.

Slightly edited main.cpp

C++:
#include <nds.h>
#include <nf_lib.h>
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <ctime>
#include <iostream>

using namespace std;

struct PlayerObject {
    s16 x;
    s16 y;
    u16 sprID;
};

struct FallObject {
    s16 x;
    s16 y;
    bool created = false;
    u16 sprID;
};


void initSystem() {
    NF_Set2D(0,0);
    NF_Set2D(0,1);
    NF_InitTiledBgBuffers();
    NF_InitTiledBgSys(0);
    NF_InitSpriteBuffers();
    NF_InitSpriteSys(0);
    NF_SetRootFolder("NITROFS");

}

void loadSprite(u8 screen, const char* sprite_name, u16 gfxRAM, u16 w, u16 h, u16 palRAM, u16 gfxVRAM, bool keep, u16 palVRAM)
{
    NF_LoadSpriteGfx(sprite_name,gfxRAM,w,h);
    NF_LoadSpritePal(sprite_name,palRAM);
    NF_VramSpriteGfx(screen,gfxRAM,gfxVRAM,keep);
    NF_VramSpritePal(screen,palRAM,palVRAM);
}

void loadResources()
{
    loadSprite(0,"box",0,16,16,0,0,true,0);
    loadSprite(0,"food",1,16,16,1,1,true,1);
}

FallObject createFallObject(s16 x, s16 y, u16 sprID)
{
    FallObject fallObj;
    fallObj.x = x;
    fallObj.y = y;
    fallObj.sprID = sprID;
    if (fallObj.created == false)
    {
        NF_CreateSprite(0,fallObj.sprID,0,0,0,0);
        NF_MoveSprite(0,fallObj.sprID,fallObj.x,fallObj.y);
        fallObj.created = true;
    }
    return fallObj;
}

void startGame()
{
    initSystem();
    loadResources();
    srand(time(NULL));
    NF_LoadTiledBg("clearbackground","Background",256,256);
    NF_CreateTiledBg(0,1,"Background");
    u16 spriteID = 1;
    s16 x_positions[3] = {0 + 50, 256/2 - 16/2, 256 - 50};
    std::vector<FallObject> objects;
    std::vector<FallObject> deletedObjects;

    float spawnDelay = 10.00;
    float dt = 1.00;
    float spawnTimer = 0;
    s16 spriteID_MAX = 127;
    PlayerObject p1;
    p1.x = 256/2 - 16/2;
    p1.y = 192 - 35;
    p1.sprID = 0;
    int vecIndex = 0;
    NF_CreateSprite(0,p1.sprID,0,0,p1.x,p1.y);

    consoleDemoInit();

    while (1)
    {
        spawnTimer += dt;
        cout << spriteID << " " << vecIndex << " " << objects.size() << endl;
        if (spawnTimer == spawnDelay)
        {
            if (spriteID >= spriteID_MAX)
            {
                spriteID = 1;
            }

            s16 randomNum = rand() % 3 + 0;
            objects.push_back(createFallObject(x_positions[randomNum],-16,spriteID));
            spriteID++;
            vecIndex++;
            spawnTimer = 0;

        }

        scanKeys();
        NF_SpriteOamSet(0);
        swiWaitForVBlank();
        oamUpdate(&oamMain);

        for (size_t i = 0; i < objects.size(); i++)
        {
            NF_MoveSprite(0,objects[i].sprID,objects[i].x,objects[i].y += 4);

            if (((p1.x < objects[i].x + 16) && (p1.x + 16 > objects[i].x) &&
                (p1.y < objects[i].y + 16) && (p1.y + 16 > objects[i].y)) || (objects[i].y >= 192))
            {
                    NF_DeleteSprite(0,objects[i].sprID);
            }
            
        }

        if (keysHeld() & KEY_LEFT) {

            if (p1.x <= 0)
            {
                p1.x-=0;
            }
            else
            {
                p1.x-=4;
            }
            NF_MoveSprite(0,p1.sprID,p1.x,p1.y);
        }
        else if (keysHeld() & KEY_RIGHT) {

            if (p1.x + 16 >= 256)
            {
                p1.x+=0;
            }
            else
            {
                p1.x+=4;
            }
            NF_MoveSprite(0,p1.sprID,p1.x,p1.y);
        }

    }
}

int main() {
    startGame();
    return 0;
}
 

plasturion

temporary hermit
Member
Joined
Aug 17, 2012
Messages
825
Trophies
1
Location
Tree
XP
2,483
Country
Poland
Code:
        for (size_t i = 0; i < objects.size(); i++)
        {
            NF_MoveSprite(0,objects[i].sprID,objects[i].x,objects[i].y += 4);

            if (((p1.x < objects[i].x + 16) && (p1.x + 16 > objects[i].x) &&
                (p1.y < objects[i].y + 16) && (p1.y + 16 > objects[i].y)) || (objects[i].y >= 192))
            {
                    NF_DeleteSprite(0,objects[i].sprID);
            }
           
        }
It seems you are trying to delete sprites but element of vector container is not earesed / deleted. So after deleting your program may try to move non existing sprites. Not sure what is created for, but If you like don't update list maybe you can use it in that way:
Code:
        for (size_t i = 0; i < objects.size(); i++)
        {
            if(objects[i].created)       
                    NF_MoveSprite(0,objects[i].sprID,objects[i].x,objects[i].y += 4);

            if (((p1.x < objects[i].x + 16) && (p1.x + 16 > objects[i].x) &&
                (p1.y < objects[i].y + 16) && (p1.y + 16 > objects[i].y)) || (objects[i].y >= 192))
            {
                    NF_DeleteSprite(0,objects[i].sprID);
                    objects[i].created = false;
            }
           
        }
also why not to keep objects in seperate files like you did at begining... It may really grow later.
 
Last edited by plasturion,

infamousjcv

Active Member
OP
Newcomer
Joined
Nov 12, 2020
Messages
31
Trophies
0
Age
22
XP
211
Country
United States
OK, so I actually fixed everything now. You guys were right about deleting the item from the vector. What happened was that VSCode gave me an error when attempting to use vector.erase(), that I tried to do things without removing the item, but you can't always trust a compiler.

Later on in development, I'll probably replace the vector with std::list, since using vector.erase() is expensive.
 

plasturion

temporary hermit
Member
Joined
Aug 17, 2012
Messages
825
Trophies
1
Location
Tree
XP
2,483
Country
Poland
I see, you can still swap one element of vector that you plan to be deleted with the last one and then use pop_back. It should be same fast. Another way is consider to not delete them at all but place in unvisible area of srceen and set them as unactive. In example (-64 to 0 on y axis)
 

aerglass

Well-Known Member
Newcomer
Joined
Apr 10, 2022
Messages
89
Trophies
0
Age
42
Location
earth
XP
205
Country
United States
I have changed my code so that it uses NF_MoveSprite to move the sprites, but it still gives the same error.

Slightly edited main.cpp

C++:
#include <nds.h>
#include <nf_lib.h>
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <ctime>
#include <iostream>

using namespace std;

struct PlayerObject {
    s16 x;
    s16 y;
    u16 sprID;
};

struct FallObject {
    s16 x;
    s16 y;
    bool created = false;
    u16 sprID;
};


void initSystem() {
    NF_Set2D(0,0);
    NF_Set2D(0,1);
    NF_InitTiledBgBuffers();
    NF_InitTiledBgSys(0);
    NF_InitSpriteBuffers();
    NF_InitSpriteSys(0);
    NF_SetRootFolder("NITROFS");

}

void loadSprite(u8 screen, const char* sprite_name, u16 gfxRAM, u16 w, u16 h, u16 palRAM, u16 gfxVRAM, bool keep, u16 palVRAM)
{
    NF_LoadSpriteGfx(sprite_name,gfxRAM,w,h);
    NF_LoadSpritePal(sprite_name,palRAM);
    NF_VramSpriteGfx(screen,gfxRAM,gfxVRAM,keep);
    NF_VramSpritePal(screen,palRAM,palVRAM);
}

void loadResources()
{
    loadSprite(0,"box",0,16,16,0,0,true,0);
    loadSprite(0,"food",1,16,16,1,1,true,1);
}

FallObject createFallObject(s16 x, s16 y, u16 sprID)
{
    FallObject fallObj;
    fallObj.x = x;
    fallObj.y = y;
    fallObj.sprID = sprID;
    if (fallObj.created == false)
    {
        NF_CreateSprite(0,fallObj.sprID,0,0,0,0);
        NF_MoveSprite(0,fallObj.sprID,fallObj.x,fallObj.y);
        fallObj.created = true;
    }
    return fallObj;
}

void startGame()
{
    initSystem();
    loadResources();
    srand(time(NULL));
    NF_LoadTiledBg("clearbackground","Background",256,256);
    NF_CreateTiledBg(0,1,"Background");
    u16 spriteID = 1;
    s16 x_positions[3] = {0 + 50, 256/2 - 16/2, 256 - 50};
    std::vector<FallObject> objects;
    std::vector<FallObject> deletedObjects;

    float spawnDelay = 10.00;
    float dt = 1.00;
    float spawnTimer = 0;
    s16 spriteID_MAX = 127;
    PlayerObject p1;
    p1.x = 256/2 - 16/2;
    p1.y = 192 - 35;
    p1.sprID = 0;
    int vecIndex = 0;
    NF_CreateSprite(0,p1.sprID,0,0,p1.x,p1.y);

    consoleDemoInit();

    while (1)
    {
        spawnTimer += dt;
        cout << spriteID << " " << vecIndex << " " << objects.size() << endl;
        if (spawnTimer == spawnDelay)
        {
            if (spriteID >= spriteID_MAX)
            {
                spriteID = 1;
            }

            s16 randomNum = rand() % 3 + 0;
            objects.push_back(createFallObject(x_positions[randomNum],-16,spriteID));
            spriteID++;
            vecIndex++;
            spawnTimer = 0;

        }

        scanKeys();
        NF_SpriteOamSet(0);
        swiWaitForVBlank();
        oamUpdate(&oamMain);

        for (size_t i = 0; i < objects.size(); i++)
        {
            NF_MoveSprite(0,objects[i].sprID,objects[i].x,objects[i].y += 4);

            if (((p1.x < objects[i].x + 16) && (p1.x + 16 > objects[i].x) &&
                (p1.y < objects[i].y + 16) && (p1.y + 16 > objects[i].y)) || (objects[i].y >= 192))
            {
                    NF_DeleteSprite(0,objects[i].sprID);
            }
          
        }

        if (keysHeld() & KEY_LEFT) {

            if (p1.x <= 0)
            {
                p1.x-=0;
            }
            else
            {
                p1.x-=4;
            }
            NF_MoveSprite(0,p1.sprID,p1.x,p1.y);
        }
        else if (keysHeld() & KEY_RIGHT) {

            if (p1.x + 16 >= 256)
            {
                p1.x+=0;
            }
            else
            {
                p1.x+=4;
            }
            NF_MoveSprite(0,p1.sprID,p1.x,p1.y);
        }

    }
}

int main() {
    startGame();
    return 0;
}
oh yeah i forgot you have to use nf_createsprite first or else nf_movesprite won't work. ok so if the error is the same check the following things. About code eficiency, don't worry yet, is that i am more experienced and yeah (when i was getting started i also did worse code lol) and i usually talk to experienced people.

1. Make sure that you use the correct id, mainly if you use NF_CreateSprite with the id of 0 anything sprite-related will need that id.
2.Make sure that NF_DeleteSprite has the correct id of each object.
3. Make sure that NF_DeleteSprite is caled after NF_CreateSprite.

whatever i do not like nflib (i know something), and i don't understand your code so i can't say anthing about the fix. i guess i can't help you? i mean, when i explain something to someone they end up quitting the thing that they were trying to do (exept for the spanish series on how to make games for the wii but that is offtopic.)
 
General chit-chat
Help Users
    KenniesNewName @ KenniesNewName: Man $14 for 1 ticket Fu imax