move project to this repo

This commit is contained in:
Norman Bos
2024-04-08 23:56:20 +02:00
parent 662a1edce4
commit aa42870720
35 changed files with 1858 additions and 3 deletions
+238
View File
@@ -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
View File
@@ -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);
+49
View File
@@ -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;
}
+13
View File
@@ -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
View File
@@ -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();
}
}