mirror of https://git.sr.ht/~kikoodx/momento
water
This commit is contained in:
parent
2f6c647f12
commit
64a702ec52
|
@ -18,10 +18,12 @@ set(SOURCES
|
|||
src/level/load.c
|
||||
src/level/draw.c
|
||||
src/level/get_tile.c
|
||||
src/level/is_water.c
|
||||
src/player/init.c
|
||||
src/player/draw.c
|
||||
src/player/update.c
|
||||
src/player/collide.c
|
||||
src/player/collide_water.c
|
||||
src/trail/init.c
|
||||
src/trail/update.c
|
||||
src/trail/draw.c
|
||||
|
@ -83,6 +85,7 @@ add_custom_command(
|
|||
|
||||
set(ASSETS
|
||||
assets/graphics/tileset.png
|
||||
assets/graphics/water.png
|
||||
assets/graphics/trail.png
|
||||
assets/graphics/coin-particle.png
|
||||
assets/graphics/switch-particle.png
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
tileset.png:
|
||||
type: bopti-image
|
||||
name: bimg_tileset
|
||||
water.png:
|
||||
type: bopti-image
|
||||
name: bimg_water
|
||||
|
||||
# libimg img_t
|
||||
trail.png:
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 762 B |
Binary file not shown.
After Width: | Height: | Size: 103 B |
|
@ -18,6 +18,7 @@
|
|||
#define GRAVITY 0.2
|
||||
#define JUMP_SPD -4.0
|
||||
#define AIR_JMP_SPD -3.0
|
||||
#define SWIM_SPD -1.0
|
||||
#define BOUNCE_SPD -5.0
|
||||
#define JUMP_BUFFER 10
|
||||
#define JUMP_GRACE 6
|
||||
|
|
|
@ -21,6 +21,7 @@ struct VisualTile {
|
|||
struct Level {
|
||||
Tile data[LEVEL_WIDTH * LEVEL_HEIGHT];
|
||||
struct VisualTile visual_data[LEVEL_WIDTH * LEVEL_HEIGHT];
|
||||
int water_level;
|
||||
int width;
|
||||
int height;
|
||||
int gold;
|
||||
|
@ -28,8 +29,11 @@ struct Level {
|
|||
int id;
|
||||
};
|
||||
|
||||
extern struct Level level;
|
||||
|
||||
/* need to set global before call: level_id */
|
||||
void level_load_bfile(void);
|
||||
void level_load_binary(void);
|
||||
void level_draw(void);
|
||||
Tile level_get_tile(int x, int y);
|
||||
int level_is_water(int x, int y);
|
||||
|
|
|
@ -51,3 +51,4 @@ int player_collide_tile(Tile collisions[COLLIDE_POINTS], int x, int y,
|
|||
Tile tile, int margin, int update);
|
||||
int player_collide_solid(int x, int y);
|
||||
int player_collide_sub(int x, int y, Tile sub, Tile rep, int margin);
|
||||
int player_collide_water(struct Player player);
|
||||
|
|
|
@ -12,6 +12,7 @@ enum {
|
|||
TILE_GOLD,
|
||||
TILE_LETAL,
|
||||
TILE_BOUNCE,
|
||||
TILE_WATER,
|
||||
};
|
||||
|
||||
#define MARGIN_GOLD 4
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#define ZX_RED C_RGB(31, 6, 4)
|
||||
#define ZX_DARK_PURPLE C_RGB(26, 6, 25)
|
||||
#define ZX_PURPLE C_RGB(31, 8, 31)
|
||||
#define ZX_DARK_CYAN C_RGB(0, 25, 25)
|
||||
#define ZX_CYAN C_RGB(0, 31, 31)
|
||||
#define ZX_GRAY C_RGB(25, 25, 25)
|
||||
#define ZX_WHITE C_RGB(31, 31, 31)
|
||||
/* missing: green, blue, yellow */
|
||||
|
|
|
@ -6,14 +6,19 @@
|
|||
#include "tiles.h"
|
||||
#include <gint/display.h>
|
||||
|
||||
extern struct Level level;
|
||||
extern const bopti_image_t bimg_tileset;
|
||||
extern const bopti_image_t bimg_water;
|
||||
|
||||
static void water_draw(void);
|
||||
|
||||
void
|
||||
level_draw(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (level.water_level >= 0)
|
||||
water_draw();
|
||||
|
||||
i = level.height * level.width;
|
||||
while (i-- > 0) {
|
||||
const struct VisualTile *visual_tile = &level.visual_data[i];
|
||||
|
@ -25,3 +30,17 @@ level_draw(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
water_draw(void)
|
||||
{
|
||||
int x;
|
||||
const int y = level.water_level;
|
||||
|
||||
x = level.width;
|
||||
while (x-- > 0) {
|
||||
const Tile tile = level_get_tile(x, y);
|
||||
if (tile != TILE_SOLID)
|
||||
dimage(x * TILE_WIDTH, y * TILE_HEIGHT, &bimg_water);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include "level.h"
|
||||
#include "tiles.h"
|
||||
|
||||
extern struct Level level;
|
||||
|
||||
Tile
|
||||
level_get_tile(int x, int y)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
/* Copyright (C) 2021 KikooDX */
|
||||
|
||||
#include "level.h"
|
||||
#include "tiles.h"
|
||||
|
||||
int
|
||||
level_is_water(int __attribute__((__unused__)) x, int y)
|
||||
{
|
||||
return (level.water_level >= 0 && y >= level.water_level);
|
||||
}
|
|
@ -116,19 +116,31 @@ level_load_post(void)
|
|||
/* set level id for display */
|
||||
level.id = level_id;
|
||||
|
||||
/* disable water by default */
|
||||
level.water_level = -1;
|
||||
|
||||
y = level.height;
|
||||
while (y-- > 0) {
|
||||
x = level.width;
|
||||
while (x-- > 0) {
|
||||
int visible = 1;
|
||||
|
||||
tile = level.data[x + y * level.width];
|
||||
/* special tiles */
|
||||
switch (tile) {
|
||||
case TILE_START:
|
||||
visible = 0;
|
||||
break;
|
||||
case TILE_GOLD:
|
||||
level.gold += 1;
|
||||
break;
|
||||
case TILE_SWITCH:
|
||||
level.exit_locked = 1;
|
||||
break;
|
||||
case TILE_WATER:
|
||||
level.water_level = y;
|
||||
visible = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -136,7 +148,7 @@ level_load_post(void)
|
|||
struct VisualTile visual_data;
|
||||
visual_data.x = x * TILE_WIDTH;
|
||||
visual_data.y = y * TILE_HEIGHT;
|
||||
visual_data.visible = tile != TILE_START;
|
||||
visual_data.visible = visible;
|
||||
if (tile == TILE_SOLID) {
|
||||
const int autotile = autotile_value(x, y);
|
||||
visual_data.texture_x = autotile * TILE_WIDTH;
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
player = player_init(); \
|
||||
} while (0);
|
||||
|
||||
extern struct Level level;
|
||||
extern int level_id;
|
||||
extern int fatal_error;
|
||||
extern char *fatal_error_msg;
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#include "tiles.h"
|
||||
#include <gint/display.h>
|
||||
|
||||
extern struct Level level;
|
||||
|
||||
extern img_t img_coin_particle;
|
||||
extern img_t img_switch_particle;
|
||||
extern img_t img_switch_activated_particle;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
/* Copyright (C) 2021 KikooDX */
|
||||
|
||||
#include "conf.h"
|
||||
#include "player.h"
|
||||
|
||||
static int collide_water(int x, int y);
|
||||
|
||||
int
|
||||
player_collide_water(struct Player player)
|
||||
{
|
||||
const int lx = player.x;
|
||||
const int rx = player.x + PLAYER_WIDTH - 1;
|
||||
const int ty = player.y;
|
||||
const int dy = player.y + PLAYER_HEIGHT - 1;
|
||||
|
||||
return collide_water(lx, ty) || collide_water(lx, dy) ||
|
||||
collide_water(rx, ty) || collide_water(rx, dy);
|
||||
}
|
||||
|
||||
static int
|
||||
collide_water(int x, int y)
|
||||
{
|
||||
return level_is_water((int)(x / TILE_WIDTH), (int)(y / TILE_WIDTH));
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
#include "zxcolors.h"
|
||||
#include <gint/display.h>
|
||||
|
||||
extern struct Level level;
|
||||
extern char *const level_names[];
|
||||
|
||||
void
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#include "tiles.h"
|
||||
#include <libimg.h>
|
||||
|
||||
extern struct Level level;
|
||||
|
||||
extern img_t img_player_blink;
|
||||
extern img_t img_player_idle;
|
||||
extern img_t img_player_jump;
|
||||
|
|
|
@ -13,8 +13,6 @@ static void player_move(struct Player *restrict player, int x, int y);
|
|||
static void player_set_anim(struct Player *restrict player,
|
||||
enum AnimState new_anim);
|
||||
|
||||
extern struct Level level;
|
||||
|
||||
/* return -1 on pause, return 1 if exit reached, 2 on death/reset and 0
|
||||
* otherwise */
|
||||
int
|
||||
|
@ -22,6 +20,7 @@ player_update(struct Player *restrict player, struct Input input)
|
|||
{
|
||||
Tile collisions[COLLIDE_POINTS];
|
||||
const int on_ground = player_collide_solid(player->x, player->y + 1);
|
||||
const int in_water = player_collide_water(*player);
|
||||
|
||||
int jumped = 0;
|
||||
const int previous_flip_h = player->anim.flip_h;
|
||||
|
@ -60,7 +59,7 @@ player_update(struct Player *restrict player, struct Input input)
|
|||
}
|
||||
|
||||
/* vertical air resistance and gravity */
|
||||
player->spd_y *= 1 - AIR_RES;
|
||||
player->spd_y *= (in_water ? 0.85 : 1.0) * (1 - AIR_RES);
|
||||
if (!on_ground) {
|
||||
/* smooth jump apex */
|
||||
const float abs_spd_y =
|
||||
|
@ -79,7 +78,7 @@ player_update(struct Player *restrict player, struct Input input)
|
|||
else if (player->jump_buffer)
|
||||
player->jump_buffer -= 1;
|
||||
/* grace frames and jumps refill */
|
||||
if (on_ground) {
|
||||
if (on_ground || in_water) {
|
||||
player->jump_grace = JUMP_GRACE;
|
||||
player->jumps_left = AIR_JUMPS;
|
||||
} else if (player->jump_grace)
|
||||
|
@ -106,6 +105,13 @@ player_update(struct Player *restrict player, struct Input input)
|
|||
player->jump_buffer = 0;
|
||||
}
|
||||
|
||||
/* swim */
|
||||
if (k_jump && in_water) {
|
||||
jumped = 1;
|
||||
player->spd_y = SWIM_SPD;
|
||||
player->air_state = AirRising;
|
||||
}
|
||||
|
||||
/* speed reminder */
|
||||
const float spd_n_rem_x = player->spd_x + player->rem_x;
|
||||
const int spd_x = (int)spd_n_rem_x;
|
||||
|
|
|
@ -16,6 +16,10 @@ trail_update(struct Player player)
|
|||
{
|
||||
int i = TRAIL_LIFE;
|
||||
color_t color = player.trail_state ? ZX_WHITE : ZX_GRAY;
|
||||
|
||||
if (player_collide_water(player))
|
||||
color = ZX_CYAN;
|
||||
|
||||
/* update trail */
|
||||
while (i-- > 1) {
|
||||
trail[i] = trail[i - 1];
|
||||
|
|
Loading…
Reference in New Issue