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.
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
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
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.
Offline
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:
int canJump = 1; if(joypad() == J_A && canJump == 1) { canJump = 0; } if(joypad() != J_A){ canJump = 1; }
Offline
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?
#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
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
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
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.
#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
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