move project to this repo
This commit is contained in:
+238
@@ -0,0 +1,238 @@
|
||||
#include <gb/gb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <gb/metasprites.h>
|
||||
#include "collision.h"
|
||||
#include "actor.h"
|
||||
|
||||
//! Hierher gehören noch weiter Attribute. is_moving, direction, hitpoints, etc.
|
||||
//! Oder besser: den Actor struct kann ich als Basis nehmen und evtl. extenden für verschiedene types (Player, Enemy, Pickup etc.)
|
||||
|
||||
// A structure of the actor
|
||||
/* typedef struct Actor
|
||||
{
|
||||
uint8_t sprite_id; // The starting ID of the sprite for this actor. Remaining sprites should follow in sequency
|
||||
uint8_t sprite_tile_width; // The number of tiles wide this sprite is
|
||||
uint8_t sprite_tile_height; // The number tiles high this sprite is
|
||||
uint8_t sprite_frame; // The total number of animated sprites
|
||||
uint8_t sprite_current_frame; // The current frame the sprite is on
|
||||
uint8_t tilemap_start; // The start index where the tiles start for this sprite
|
||||
uint8_t x; // The sprite x position (top left)
|
||||
uint8_t y; // The sprite y position (top left)
|
||||
uint8_t next_x; // The future sprite x position (top left)
|
||||
uint8_t next_y; // The future sprite y position (top left)
|
||||
int8_t dx; // The sprite x moving direction
|
||||
int8_t dy; // The sprite y moving direction
|
||||
uint8_t velocity_x; // The current speed of travel in the X direction
|
||||
uint8_t velocity_y; // The current speed of travel in the y direction
|
||||
bool is_facing_right; // The direction the player sprite is facing
|
||||
bool is_moving; // Is the actor moving or not
|
||||
const unsigned char *tilemap; // A pointer to the tilemap (may be obsolete with metasprite)
|
||||
const metasprite_t *metasprite; // A pointer to the metasprite
|
||||
} Actor; */
|
||||
|
||||
//! die load_sprite_frame wird mit dem move_metasprite_ex gar nicht mehr benutzt!
|
||||
/* void load_sprite_frame(Actor *actor, uint8_t frame)
|
||||
{
|
||||
// Set current frame
|
||||
actor->sprite_current_frame = frame;
|
||||
|
||||
// Get total sprites
|
||||
uint8_t spriteCount = actor->sprite_tile_width * actor->sprite_tile_height;
|
||||
|
||||
for (uint8_t i = 0; i != spriteCount; i++)
|
||||
{
|
||||
set_sprite_tile(actor->sprite_id + i, actor->tilemap[actor->tilemap_start + i + (frame * spriteCount)]);
|
||||
}
|
||||
} */
|
||||
|
||||
void move_actor(Actor *actor, uint8_t x, uint8_t y) // Evtl. sollte is_moving hier mit übergeben werden
|
||||
{
|
||||
|
||||
// Set actors new position
|
||||
// actor->x = x;
|
||||
// actor->y = y;
|
||||
|
||||
// actor->x = actor->next_x;
|
||||
// actor->y = actor->next_y;
|
||||
|
||||
// Move the metasprite
|
||||
if (actor->is_facing_right)
|
||||
{
|
||||
move_metasprite_ex(actor->metasprite, 0, 0, 0, x + 8, y + 16);
|
||||
}
|
||||
if (!actor->is_facing_right)
|
||||
{
|
||||
// flip the metasprite horizontally when is_facing_right is TRUE
|
||||
move_metasprite_flipx(actor->metasprite, 0, 0, 0, x + 8, y + 16);
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_actor(Actor *actor)
|
||||
{
|
||||
|
||||
uint8_t playerIsMoving = actor->dx != 0 || actor->dy != 0;
|
||||
|
||||
// If the player is moving at all
|
||||
// We'll handle horizontall and vertical movement separately
|
||||
// Handling them separately enables a sliding motion against walls
|
||||
if (playerIsMoving)
|
||||
{
|
||||
|
||||
// If we are moving horizontally
|
||||
if (actor->dx != 0)
|
||||
{
|
||||
|
||||
// Check the tiles on our side
|
||||
uint8_t solid =
|
||||
world_position_is_solid(actor->next_x + actor->dx * PLAYER_HALF_WIDTH, actor->y - PLAYER_HALF_HEIGHT) ||
|
||||
world_position_is_solid(actor->next_x + actor->dx * PLAYER_HALF_WIDTH, actor->y) ||
|
||||
world_position_is_solid(actor->next_x + actor->dx * PLAYER_HALF_WIDTH, actor->y + PLAYER_HALF_HEIGHT);
|
||||
|
||||
// printf("%u\n", world_position_is_solid(actor->x + actor->dx * PLAYER_HALF_WIDTH, actor->y - PLAYER_HALF_HEIGHT));
|
||||
|
||||
// If none are solid
|
||||
if (!solid)
|
||||
// if (solid != 0)
|
||||
{
|
||||
|
||||
// Update the player's x position
|
||||
// actor->x += x;
|
||||
actor->x = actor->next_x;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are moving vertically
|
||||
if (actor->dy != 0)
|
||||
{
|
||||
|
||||
// Check the tiles above or below us
|
||||
uint8_t solid =
|
||||
world_position_is_solid(actor->x + PLAYER_HALF_WIDTH, actor->next_y + actor->dy * PLAYER_HALF_HEIGHT) ||
|
||||
world_position_is_solid(actor->x, actor->next_y + actor->dy * PLAYER_HALF_HEIGHT) ||
|
||||
world_position_is_solid(actor->x - PLAYER_HALF_WIDTH, actor->next_y + actor->dy * PLAYER_HALF_HEIGHT);
|
||||
|
||||
// If none are solid
|
||||
if (!solid)
|
||||
// if (solid != 0)
|
||||
{
|
||||
|
||||
// Update the player's y position
|
||||
// actor->y += y;
|
||||
actor->y = actor->next_y;
|
||||
}
|
||||
}
|
||||
|
||||
// actor->x += x;
|
||||
// actor->y += y;
|
||||
|
||||
move_actor(actor, actor->x, actor->y);
|
||||
}
|
||||
}
|
||||
|
||||
void move_actor_with_joypad(Actor *actor)
|
||||
{
|
||||
// Read buttons
|
||||
uint8_t buttons = joypad();
|
||||
|
||||
bool is_moving_x = FALSE;
|
||||
bool is_moving_y = FALSE;
|
||||
|
||||
actor->dx = 0;
|
||||
actor->dy = 0;
|
||||
|
||||
if (buttons & J_LEFT)
|
||||
{
|
||||
actor->is_facing_right = FALSE;
|
||||
is_moving_x = TRUE;
|
||||
actor->next_x -= 1;
|
||||
actor->dx = -1;
|
||||
}
|
||||
else if (buttons & J_RIGHT)
|
||||
{
|
||||
actor->is_facing_right = TRUE;
|
||||
is_moving_x = TRUE;
|
||||
actor->next_x += 1;
|
||||
actor->dx = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_moving_x = FALSE;
|
||||
}
|
||||
|
||||
if (buttons & J_UP)
|
||||
{
|
||||
is_moving_y = TRUE;
|
||||
actor->next_y -= 1;
|
||||
actor->dy = -1;
|
||||
}
|
||||
else if (buttons & J_DOWN)
|
||||
{
|
||||
is_moving_y = TRUE;
|
||||
actor->next_y += 1;
|
||||
actor->dy = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_moving_y = FALSE;
|
||||
}
|
||||
|
||||
if (is_moving_x || is_moving_y)
|
||||
{
|
||||
actor->is_moving = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->is_moving = FALSE;
|
||||
}
|
||||
|
||||
scroll_actor(actor);
|
||||
}
|
||||
|
||||
void setup_actor(Actor *actor, uint8_t sprite_id, uint8_t tile_width, uint8_t tile_height, uint8_t tilemap_start, uint8_t total_frames, bool is_facing_right, const unsigned char *tilemap, const metasprite_t *metasprite)
|
||||
{
|
||||
|
||||
// Set initial X
|
||||
actor->x = 80;
|
||||
|
||||
// Set initial Y
|
||||
actor->y = 90;
|
||||
|
||||
// Set initial next X
|
||||
actor->next_x = 80;
|
||||
// Set initial next Y
|
||||
actor->next_y = 90;
|
||||
|
||||
// Set horizontal direction of
|
||||
actor->is_facing_right = is_facing_right;
|
||||
|
||||
// Set if the actor is moving
|
||||
actor->is_moving = FALSE;
|
||||
|
||||
// Store pointer to tilemap
|
||||
actor->tilemap = tilemap;
|
||||
|
||||
// Set tile start position (in tileset)
|
||||
actor->tilemap_start = tilemap_start;
|
||||
|
||||
// Set player sprite ID
|
||||
actor->sprite_id = sprite_id;
|
||||
|
||||
// Set size
|
||||
actor->sprite_tile_width = tile_width;
|
||||
actor->sprite_tile_height = tile_height;
|
||||
|
||||
// Set number of frames
|
||||
actor->sprite_frame = total_frames;
|
||||
|
||||
// Make sure to start at frame 1
|
||||
actor->sprite_current_frame = 0;
|
||||
|
||||
// Move to built in metasprite methods
|
||||
// load_sprite_frame(actor, 0);
|
||||
|
||||
// Store pointer to metasprite
|
||||
actor->metasprite = metasprite;
|
||||
|
||||
move_actor(actor, actor->x, actor->y);
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#include <gb/gb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <gb/metasprites.h>
|
||||
#include "collision.h"
|
||||
|
||||
//! Hierher gehören noch weiter Attribute. is_moving, direction, hitpoints, etc.
|
||||
//! Oder besser: den Actor struct kann ich als Basis nehmen und evtl. extenden für verschiedene types (Player, Enemy, Pickup etc.)
|
||||
|
||||
// A structure of the actor
|
||||
typedef struct Actor
|
||||
{
|
||||
uint8_t sprite_id; // The starting ID of the sprite for this actor. Remaining sprites should follow in sequency
|
||||
uint8_t sprite_tile_width; // The number of tiles wide this sprite is
|
||||
uint8_t sprite_tile_height; // The number tiles high this sprite is
|
||||
uint8_t sprite_frame; // The total number of animated sprites
|
||||
uint8_t sprite_current_frame; // The current frame the sprite is on
|
||||
uint8_t tilemap_start; // The start index where the tiles start for this sprite
|
||||
uint8_t x; // The sprite x position (top left)
|
||||
uint8_t y; // The sprite y position (top left)
|
||||
uint8_t next_x; // The future sprite x position (top left)
|
||||
uint8_t next_y; // The future sprite y position (top left)
|
||||
int8_t dx; // The sprite x moving direction
|
||||
int8_t dy; // The sprite y moving direction
|
||||
uint8_t velocity_x; // The current speed of travel in the X direction
|
||||
uint8_t velocity_y; // The current speed of travel in the y direction
|
||||
bool is_facing_right; // The direction the player sprite is facing
|
||||
bool is_moving; // Is the actor moving or not
|
||||
const unsigned char *tilemap; // A pointer to the tilemap (may be obsolete with metasprite)
|
||||
const metasprite_t *metasprite; // A pointer to the metasprite
|
||||
} Actor;
|
||||
|
||||
void move_actor(Actor *actor, uint8_t x, uint8_t y);
|
||||
|
||||
void scroll_actor(Actor *actor);
|
||||
|
||||
void move_actor_with_joypad(Actor *actor);
|
||||
|
||||
void setup_actor(Actor *actor, uint8_t sprite_id, uint8_t tile_width, uint8_t tile_height, uint8_t tilemap_start, uint8_t total_frames, bool is_facing_right, const unsigned char *tilemap, const metasprite_t *metasprite);
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <gb/gb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../res/underwater_tiles.h"
|
||||
#include "../res/underwater_map.h"
|
||||
#include "../res/collision-test/tileset.h"
|
||||
#include "../res/collision-test/tilemap.h"
|
||||
|
||||
#define SOLID 1
|
||||
#define PLAYER_HALF_WIDTH 8
|
||||
#define PLAYER_HALF_HEIGHT 8
|
||||
#define GRID_NODE_SIZE 8
|
||||
#define NUMBER_OF_SOLID_TILES 9
|
||||
|
||||
#define TILEMAP_WIDTH_IN_TILES (tilemap_WIDTH >> 3)
|
||||
#define TILEMAP_HEIGHT_IN_TILES (tilemap_HEIGHT >> 3)
|
||||
|
||||
// uint16_t playerX, playerY;
|
||||
|
||||
uint8_t world_position_is_solid(uint16_t x, uint16_t y)
|
||||
{
|
||||
|
||||
// Bit-shifting would be faster here
|
||||
uint16_t column = x / GRID_NODE_SIZE;
|
||||
|
||||
// Make sure the tile is in proper bounds
|
||||
if (column >= TILEMAP_WIDTH_IN_TILES)
|
||||
return TRUE;
|
||||
|
||||
uint16_t row = y / GRID_NODE_SIZE;
|
||||
|
||||
// Make sure the tile is in proper bounds
|
||||
if (row >= TILEMAP_HEIGHT_IN_TILES)
|
||||
return TRUE;
|
||||
|
||||
uint16_t tilemapIndex = column + row * TILEMAP_WIDTH_IN_TILES;
|
||||
|
||||
uint8_t tileIsSolid = FALSE;
|
||||
|
||||
// Get the tilset tile in our tilemap
|
||||
uint8_t tilesetTile = tilemap_map[tilemapIndex];
|
||||
|
||||
// In our tileset, the solid tiles always come first.
|
||||
// There are 10 tiles. The first 9 are solid
|
||||
// this makes it fast & easy to determine if a tile is solid or not
|
||||
tileIsSolid = tilesetTile < NUMBER_OF_SOLID_TILES;
|
||||
|
||||
return tileIsSolid;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <gb/gb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define SOLID 1
|
||||
#define PLAYER_MOVE_SPEED 10
|
||||
#define PLAYER_HALF_WIDTH 8
|
||||
#define PLAYER_HALF_HEIGHT 8
|
||||
#define GRID_NODE_SIZE 8
|
||||
#define NUMBER_OF_SOLID_TILES 9
|
||||
|
||||
// extern uint16_t playerX, playerY;
|
||||
|
||||
uint8_t world_position_is_solid(uint16_t x, uint16_t y);
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
#include <gb/gb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../res/alphabet.h"
|
||||
#include "../res/blankScreen.h"
|
||||
#include "../res/hud.h"
|
||||
#include "../res/underwater_tiles.h"
|
||||
#include "../res/underwater_map.h"
|
||||
#include "../res/submarine_sprites.h"
|
||||
#include "../res/collision-test/tileset.h"
|
||||
#include "../res/collision-test/tilemap.h"
|
||||
|
||||
#include "actor.h"
|
||||
// #include "input.h"
|
||||
#include "collision.h"
|
||||
|
||||
Actor submarine;
|
||||
|
||||
uint8_t two_frame_counter = 0;
|
||||
uint8_t two_frame_real_value = 0;
|
||||
|
||||
#define TILEMAP_WIDTH_IN_TILES (tilemap_WIDTH >> 3)
|
||||
#define TILEMAP_HEIGHT_IN_TILES (tilemap_HEIGHT >> 3)
|
||||
|
||||
// generic frame counter function
|
||||
// from https://laroldsjubilantjunkyard.com/tutorial/rpg-style-movement-in-gbdk/
|
||||
void update_two_frame_counter(void)
|
||||
{
|
||||
two_frame_counter += 1;
|
||||
two_frame_real_value = two_frame_counter >> 3;
|
||||
|
||||
// printf("%d\n", two_frame_counter);
|
||||
// Stop & reset if the value is over 2
|
||||
if (two_frame_real_value >= 2)
|
||||
{
|
||||
two_frame_real_value = 0;
|
||||
two_frame_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//! Switch metasprite on certain frames. Could be heavily improved to take props for actor->spriteFrames and more
|
||||
//! Should be called in some UpdateActor(&actor) Function
|
||||
void animate_actor(Actor *actor, int8_t two_frame_counter)
|
||||
{
|
||||
if (actor->is_moving)
|
||||
{
|
||||
if (two_frame_counter == 3)
|
||||
{
|
||||
actor->metasprite = submarine_metasprite;
|
||||
}
|
||||
|
||||
if (two_frame_counter == 9)
|
||||
{
|
||||
actor->metasprite = submarine_metasprite2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->metasprite = submarine_metasprite;
|
||||
move_actor(actor, actor->x, actor->y); // Necessary to trigger the metasprite change
|
||||
}
|
||||
}
|
||||
|
||||
//! Die HUD Funktion muss ich reparieren, damit die immer in der Lage ist, die richtigen Tiles anzuzeigen
|
||||
void show_hud(void)
|
||||
{
|
||||
// Load tiles to the window layer
|
||||
set_win_tiles(0, 0, 20, 1, hud);
|
||||
|
||||
// Move the window layer down to the last tile row.
|
||||
move_win(7, 136);
|
||||
SHOW_WIN;
|
||||
}
|
||||
|
||||
//! This has to be refactored! A function with fixed values makes little sense.
|
||||
void shiftBGTiles(void)
|
||||
{
|
||||
#define VRAM_OFFSET 48 // Change this to your desired offset
|
||||
|
||||
int map_size = 20 * 18; // Get the size of the map array
|
||||
|
||||
for (int i = 0; i < map_size; i++)
|
||||
{
|
||||
underwater_map[i] += VRAM_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
void init(void)
|
||||
{
|
||||
|
||||
// shiftBGTiles();
|
||||
|
||||
// Load HUD tiles
|
||||
// set_bkg_data(0, 48, alphabet);
|
||||
// Load background tiles after HUD tiles
|
||||
// set_bkg_data(48, 40, underwater_tiles);
|
||||
|
||||
// Use the 'blankScreen' array to write background tiles starting at 0,0 (tile positions)
|
||||
// and for 20 tiles in width and 18 tiles in height
|
||||
// set_bkg_tiles(0, 0, 20, 18, blankScreen); // Setting the first tile of alphabet to blank would be more efficient.
|
||||
|
||||
// set_bkg_tiles(0, 0, 20, 18, underwater_map);
|
||||
|
||||
set_bkg_data(0, tileset_TILE_COUNT, tileset_tiles);
|
||||
|
||||
set_bkg_tiles(0, 0, TILEMAP_WIDTH_IN_TILES, TILEMAP_HEIGHT_IN_TILES, tilemap_map);
|
||||
|
||||
// Fill tileset bank 0 with 4 actor tiles
|
||||
set_sprite_data(0, 8, submarine_tileset);
|
||||
|
||||
//! Prüfen, welche variables für das metasprite überhaupt noch benötigt werden
|
||||
// Setup player actor
|
||||
setup_actor(
|
||||
// player
|
||||
&submarine,
|
||||
// Sprite ID: 0
|
||||
0,
|
||||
// 2x2 meta-sprite
|
||||
2, 2,
|
||||
// Tiles start at 0
|
||||
0,
|
||||
// Total animated frames
|
||||
4,
|
||||
// Set is_facing_right bool
|
||||
TRUE,
|
||||
// pointer to the tilemap
|
||||
submarine_tilemap,
|
||||
// pointer to the metasprite
|
||||
submarine_metasprite);
|
||||
|
||||
// MoveCharacter(&submarine, 80, 90);
|
||||
|
||||
// Show the HUD
|
||||
// show_hud();
|
||||
|
||||
SHOW_BKG;
|
||||
SHOW_SPRITES;
|
||||
// SPRITES_8x16;
|
||||
DISPLAY_ON;
|
||||
|
||||
// move_metasprite_ex(submarine_metasprite, 0, 0, 0, 80, 80);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
// Main loop
|
||||
while (1)
|
||||
{
|
||||
|
||||
update_two_frame_counter();
|
||||
animate_actor(&submarine, two_frame_counter);
|
||||
|
||||
// Move the actor with the joypad
|
||||
move_actor_with_joypad(&submarine);
|
||||
// joypad_input(&submarine);
|
||||
|
||||
// Wait for next frame
|
||||
wait_vbl_done();
|
||||
|
||||
// Done processing, yield CPU and wait for start of next frame
|
||||
vsync();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user