metasprites.c (4600B)
1#include <stdint.h> 2 3#include <gbdk/platform.h> 4#include <gbdk/metasprites.h> 5 6#include "sprite.h" 7 8const unsigned char pattern[] = {0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01}; 9 10joypads_t joypads; 11 12#define ACC_X 1 13#define ACC_Y 2 14 15// The metasprite will be built starting with hardware sprite zero (the first) 16#define SPR_NUM_START 0 17 18// Metasprite tiles are loaded into VRAM starting at tile number 0 19#define TILE_NUM_START 0 20 21// sprite coords 22uint16_t PosX, PosY; 23int16_t SpdX, SpdY; 24uint8_t PosF; 25uint8_t hide, jitter; 26uint8_t idx, rot; 27 28// main funxction 29void main(void) { 30 // init palettes 31 BGP_REG = OBP0_REG = 0xE4; 32 OBP1_REG = 0xE0; 33 34 // Fill the screen background with a single tile pattern 35 fill_bkg_rect(0, 0, 20, 18, 0); 36 set_bkg_data(0, 1, pattern); 37 38 // Load metasprite tile data into VRAM 39 set_sprite_data(TILE_NUM_START, sizeof(sprite_tiles) >> 4, sprite_tiles); 40 41 // show bkg and sprites 42 SHOW_BKG; SHOW_SPRITES; 43 44 // Check what size hardware sprite the metasprite is using (from sprite.h) 45 #if sprite_TILE_H == 16 46 SPRITES_8x16; 47 #else 48 SPRITES_8x8; 49 #endif 50 51 // init 1 joypad 52 joypad_init(1, &joypads); 53 54 // Set initial position, zero out speed 55 PosX = PosY = 64 << 4; 56 SpdX = SpdY = 0; 57 58 hide = 0; jitter = 0; idx = 0; rot = 0; 59 60 while(1) { 61 // poll joypads 62 joypad_ex(&joypads); 63 64 PosF = 0; 65 // game object 66 if (joypads.joy0 & J_UP) { 67 SpdY -= 2; 68 if (SpdY < -32) SpdY = -32; 69 PosF |= ACC_Y; 70 } else if (joypads.joy0 & J_DOWN) { 71 SpdY += 2; 72 if (SpdY > 32) SpdY = 32; 73 PosF |= ACC_Y; 74 } 75 76 if (joypads.joy0 & J_LEFT) { 77 SpdX -= 2; 78 if (SpdX < -32) SpdX = -32; 79 PosF |= ACC_X; 80 } else if (joypads.joy0 & J_RIGHT) { 81 SpdX += 2; 82 if (SpdX > 32) SpdX = 32; 83 PosF |= ACC_X; 84 } 85 86 87 // Press A button to show/hide metasprite 88 if ((joypads.joy0 & J_A) && (!jitter)) { 89 hide = (!hide); 90 jitter = 20; 91 } 92 93 // Press B button to cycle through metasprite animations 94 if ((joypads.joy0 & J_B) && (!jitter) && (!hide)) { 95 idx++; if (idx >= (sizeof(sprite_metasprites) >> 1)) idx = 0; 96 jitter = 10; 97 } 98 99 // Press SELECT button to cycle metasprite through Normal/Flip-Y/Flip-XY/Flip-X 100 if ((joypads.joy0 & J_SELECT) && (!jitter) && (!hide)) { 101 rot++; rot &= 3; 102 jitter = 20; 103 } 104 105 // Hide/Animate/Flip input throttling 106 if (jitter) jitter--; 107 108 PosX += SpdX, PosY += SpdY; 109 110 uint8_t hiwater = 0; 111 112 // NOTE: In a real game it would be better to only call the move_metasprite..() 113 // functions if something changed (such as movement or rotation). That 114 // reduces CPU usage on frames that don't need updates. 115 // 116 // In this example they are called every frame to simplify the example code 117 118 // Hide the metasprite or move it & apply any rotation settings 119 if (hide) 120 hide_metasprite(sprite_metasprites[idx], SPR_NUM_START); 121 else 122 switch (rot) { 123 case 0: hiwater = move_metasprite (sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break; 124 case 1: hiwater = move_metasprite_hflip (sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break; 125 case 2: hiwater = move_metasprite_hvflip(sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break; 126 case 3: hiwater = move_metasprite_vflip (sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break; 127 }; 128 129 // Hide rest of the hardware sprites, because amount of sprites differ between animation frames. 130 hide_sprites_range(hiwater, 40); 131 132 // Y Axis: update velocity (reduce speed) if no U/D button pressed 133 if (!(PosF & ACC_Y)) { 134 if (SpdY != 0) { 135 if (SpdY > 0) SpdY--; 136 else SpdY ++; 137 } 138 } 139 140 // X Axis: update velocity (reduce speed) if no L/R button pressed 141 if (!(PosF & ACC_X)) { 142 if (SpdX != 0) { 143 if (SpdX > 0) SpdX--; 144 else SpdX ++; 145 } 146 } 147 148 149 // wait for VBlank to slow down everything and reduce cpu use when idle 150 wait_vbl_done(); 151 } 152} 153