Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

#1 2019-12-12 08:17:23

obscuredesign79
Member
Registered: 2019-11-02
Posts: 11

joypad not pressed

hello gbdev. another newbie question here. the jump button is J_A. i want to set it up in gbdk so when i hold the J_A button, the jump method excutes only once. not unless i let go of the J_A button and press it again would the jump method executes. what is the best way to approach this?

here is my current code

Code:

while(1)
    {
        if((joypad() & J_A) || jumping == 1)
        {
            jump();    
            gameBallStaticStretched();
            if(jumping == 0)
            {
                gameBallAnimSquashed(500);
                wait_vbl_done();
            }
        }
        if(joypad() & J_LEFT)
        {
            ballSprite01.x -= 3;
            moveGameCharacter(&ballSprite01, ballSprite01.x, ballSprite01.y);
            gameBallAnimRollLoop();
            if(joypad() & J_A)
            {
                gameBallStaticStretched();
                if(jumping == 0)
                {
                    gameBallAnimSquashed(500);
                }
            }
        }
        if(joypad() & J_RIGHT)
        {
            ballSprite01.x += 3;
            moveGameCharacter(&ballSprite01, ballSprite01.x, ballSprite01.y);
            gameBallAnimRollLoop();
            if(joypad() & J_A)
            {
                gameBallStaticStretched();
                if(jumping == 0)
                {
                    gameBallAnimSquashed(500);
                }
            }
        }

        performantDelay(2);
    }

}

Offline

 

#2 2019-12-12 18:18:49

Ardis
Member
From: USA
Registered: 2019-06-06
Posts: 58
Website

Re: joypad not pressed

The only way I know to detect a button being released would end up pausing your game until all buttons were released, but I do have a simple trick of making a Boolean tracker of if you can jump. Something of a "canJump" that gets set to FALSE when you initiate a jump and set it to be TRUE again when your character completes their jump. And make it so when you press J_A, check if canJump is TRUE or FALSE.

My solution is so primitive that this post was made on a stone tablet.


Also known as Arvex in other places.

Interceptor (Demo)
https://arvex.itch.io/interceptor

Offline

 

#3 2019-12-12 18:31:48

gbjosh
Member
From: KY
Registered: 2016-06-15
Posts: 51

Re: joypad not pressed

To piggy back off of Ardis's comment you can add in joypad() != J_A to see if A is not pressed so it could look like:

Code:

int canJump = 1;

if(joypad() == J_A && canJump == 1) {
  canJump = 0;
 }

if(joypad() != J_A){
  canJump = 1;
}

Offline

 

#4 2019-12-15 09:54:44

obscuredesign79
Member
Registered: 2019-11-02
Posts: 11

Re: joypad not pressed

thanks ardis and gbjosh! it works now! now im having trouble controlling it with the directional button. when i press the right button and then the jump button(A) it works properly. the only problem now is when i hold the A button and press on the right button. the ball jumps and moves to the right. what i would like to do is when i hold the A button and then press right, the ball just slides. Ive been trying to figure out how to do this. im still learning programming so i dont have have any tricks up my sleeve to do this. Any tips in programming would be nice.

another question about compiling. im using debian linux and compiling using gbdk-n and gbdk2.6 using virtualbox and windows xp works fine when compiling my c code. i recently installed gbdk2.6 for linux and it compiles without errors. its just that when i try to make the ball jump, it doesnt jump. it jitters and i have to press it a couple of times to make it jump. is this a compiler bug?

Code:

#include <stdio.h>
#include <gb/gb.h>
#include "ballSprite.c"//16x16 sprite with animation

//global variables
BYTE keyPressed_A;
BYTE keyPressed_RIGHT;
BYTE jumping;
INT8 gravity = -2;
UINT8 currentSpeedY;
UINT8 floorYPosition = 136;
UINT8 possibleYSurface;
UINT8 timer = 0;


//performance delay to free up CPU
void performantDelay(UINT8 numloops)
{
    UINT8 i;
    for(i=0;i < numloops;i++)
    {
        wait_vbl_done();
    }
}

//gameCharacter struct
struct gameCharacter
{
    UBYTE spriteId[4];//change this according to sprite size (16x16, 24x24..)
    UINT8 x;
    UINT8 y;
    UINT8 width;
    UINT8 height;
};

//inializes gameCharacter to ballSprite01
struct gameCharacter ballSprite01;

//cycle through tiles for animation
void gameBallAnimRollLoop()//looping ball moving animation.(highlight jitters)
{
    set_sprite_tile(1, 5);
    set_sprite_tile(2, 6);
    set_sprite_tile(3, 7);
    set_sprite_tile(4, 8);
}

void gameBallStaticStretched()//static ball stretch
{
    set_sprite_tile(1, 9);
    set_sprite_tile(2, 10);
    set_sprite_tile(3, 11);
    set_sprite_tile(4, 12);
}

void gameBallStaticRest()//static ball rest
{
    set_sprite_tile(1, 1);
    set_sprite_tile(2, 2);
    set_sprite_tile(3, 3);
    set_sprite_tile(4, 4);
}
void gameBallAnimSquashed(UINT8 numloops)//static ball squashed
{
    UINT8 i;
    for(i=0;i < numloops;i++)
    {
        set_sprite_tile(1, 0);
        set_sprite_tile(2, 0);
        set_sprite_tile(3, 13);
        set_sprite_tile(4, 14);
    }

    gameBallStaticRest();
}

//moving a 16x16 metaSprite in unison
void moveGameCharacter(struct gameCharacter *character, UINT8 x, UINT8 y)
{
    move_sprite(character->spriteId[0],x, y);
    move_sprite(character->spriteId[1],x + 8, y);
    move_sprite(character->spriteId[2],x, y + 8);
    move_sprite(character->spriteId[3],x + 8, y + 8);
}

//setup the ballSprite01 sprite struct
void setupBallSprite01()
{
    set_sprite_data(0, 15, ballSprite);
    
    ballSprite01.x=16;
    ballSprite01.y = floorYPosition;
    ballSprite01.width=16;
    ballSprite01.height=16;

    set_sprite_tile(1,1);
    ballSprite01.spriteId[0]=1;
    set_sprite_tile(2,2);
    ballSprite01.spriteId[1]=2;
    set_sprite_tile(3,3);
    ballSprite01.spriteId[2]=3;
    set_sprite_tile(4,4);
    ballSprite01.spriteId[3]=4;

    moveGameCharacter(&ballSprite01,ballSprite01.x,ballSprite01.y);
}

INT8 wouldHitSurf(UINT8 projectedYPosition)
{
    if(projectedYPosition >= floorYPosition){
        return floorYPosition;
    }
    return -1;
}

//jump algorithm
void jump()
{
    if(jumping == 0)
    {
        jumping = 1;
        currentSpeedY = 10;
    }
    currentSpeedY = currentSpeedY + gravity;

    ballSprite01.y -= currentSpeedY;

    possibleYSurface = wouldHitSurf(ballSprite01.y);


    if(possibleYSurface == floorYPosition)
    {
        jumping = 0;
        moveGameCharacter(&ballSprite01,ballSprite01.x, possibleYSurface);

    }
    else
    {
        moveGameCharacter(&ballSprite01,ballSprite01.x,ballSprite01.y);
    }
}
void main()
{
    //loads ballSprite
    setupBallSprite01();

    //initialize jumping variable
    jumping = 0;

    keyPressed_A = 1;


    DISPLAY_ON;
    SHOW_SPRITES;

    while(1)
    {
//        printf("%d", joypad());

        if((joypad() & J_A || jumping == 1) && keyPressed_A == 1)
        {
            jump();    
            gameBallStaticStretched();
            if(jumping == 0)
            {
                gameBallAnimSquashed(500);
                keyPressed_A = 0;
            }
        }

        else if(joypad() != J_A)
        {
            keyPressed_A = 1;
        }



        if((joypad() & J_RIGHT) && keyPressed_RIGHT == 1)
        {

            ballSprite01.x += 3;
            moveGameCharacter(&ballSprite01, ballSprite01.x, ballSprite01.y);
            gameBallAnimRollLoop();
            if(jumping == 0)
            {
                keyPressed_A = 1;
            }


        }
        else if(joypad() != J_RIGHT)
        {
            keyPressed_RIGHT = 1;
        }

        performantDelay(2);
    }

}

Offline

 

#5 2019-12-20 02:07:46

obscuredesign79
Member
Registered: 2019-11-02
Posts: 11

Re: joypad not pressed

so i checked out the the source for the game Pluto's Corner so i can learn how the controls were set but i couldn't find the "Keys.h" for the code. Theres this function i think called KEY_TICKED and i wanted to learn how it was done. Does anybody know? im just trying to learn. thanks

Offline

 

#6 2019-12-20 02:38:58

Zalo
Member
From: Spain
Registered: 2016-07-26
Posts: 103
Website

Re: joypad not pressed

I can answer that
instead of just having the current state of the keys (obtained from the function joypad()) I also keep a copy of the previous state
So checking if a key has been ticked is just checking if it is currently pressed but it wasn't on the previous state

You can see how all this work here https://github.com/Zal0/ZGB/blob/master … ude/Keys.h

I call UPDATE_KEYS on every frame https://github.com/Zal0/ZGB/blob/2b6302 … ain.c#L120

Hope it helps

Offline

 

#7 2020-01-09 02:28:07

obscuredesign79
Member
Registered: 2019-11-02
Posts: 11

Re: joypad not pressed

Yes!!! Thank you so much Zalo. Im just learning to make games with gameboy using GBDK-n. Its a small game or demo/test so I just incorporate the function in the main.c file.

Code:

#include <gb/gb.h>

//performance delay to free up CPU
void performantDelay(UINT8 numloops)
{
    UINT8 i;
    for(i=0;i < numloops;i++)
    {   
        wait_vbl_done();
    }   
}

//joypad functions
void updateKeys()
{
    previousKeys = keys;
    keys = joypad();
}

INT8 keyPressed(INT8 K)
{
    return keys & (K);
}

INT8 keyTicked(INT8 K)
{
    return (keys & (K) && !(previousKeys & (K)));
}

INT8 keyReleased(INT8 K)
{
    return previousKeys & (K) && !(keys & (K));
}

void anyKey()
{
    keys;
}

void main()
{
    while(1)
    {
        updateKeys();

        if(keyPressed(J_RIGHT))
        {
            player.x += 1;
            movePlayerR(&player, player.x, player.y);
        }

    }
}

when i use keyTicked, it works now! Being new to c programming, im still having trouble wraping my head around how this works. Can anyone care to help me explain? Also, what if i wanted to use a double tick on a button? Say, when i press and hold right the character walks but when i ticked the right button and press it again, the character runs. basically a double click and hold the button. How would i go about doing that? is it a timer thing?

Offline

 

#8 2020-01-17 14:55:24

bbbbbr
Member
Registered: 2019-03-04
Posts: 124

Re: joypad not pressed

Most likely you'll want a limit on the amount of time between button presses for the double tap. There are probably a couple ways do to it, so here is one simplified example.

* A variable to track the state of whether the first tap occurred (this might be shared with general character moving state).
* Another variable to track how long (perhaps in frames) since the first button tap was released.

So then, when a subsequent tap occurs you can test whether the previous state is a matching one to start the double tap sequence, and whether it is within the required amount of time.

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson