Graphics update

* Remade tileset
* Implement autotiling
* Implement animations and particle engine
* Create gold pickup animation
This commit is contained in:
KikooDX 2021-04-08 18:04:24 +02:00
parent d27c73cf38
commit 7326e28e6b
15 changed files with 169 additions and 6 deletions

View File

@ -28,16 +28,22 @@ set(SOURCES
src/main.c
src/level/load.c
src/level/draw.c
src/level/get_tile.c
src/player/init.c
src/player/draw.c
src/player/update.c
src/player/collide.c
src/particles/init.c
src/particles/update.c
src/particles/draw.c
src/particles/create.c
)
set(ASSETS
assets/graphics/tileset.png
assets/graphics/player.png
assets/graphics/burst.png
assets/graphics/coin-particle.png
)
set(FLAGS

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

View File

@ -7,3 +7,6 @@ player.png:
burst.png:
type: bopti-image
name: bimg_burst
coin-particle.png:
type: libimg-image
name: img_coin_particle

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -20,3 +20,4 @@ struct Level {
/* need to set global before call: level_id */
void level_load(void);
void level_draw(void);
Tile level_get_tile(int x, int y);

23
include/particles.h Normal file
View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#pragma once
#include <libimg.h>
#define MAX_PARTICLES 64
struct Particle {
img_t *texture;
int x;
int y;
int frame_width;
int frame_height;
int frame_duration;
int frame;
int life;
};
void particles_init(void);
void particles_update(void);
void particles_draw(void);
void particle_create(img_t *texture, int x, int y, int frame_width, int frame_duration);

View File

@ -2,8 +2,8 @@
/* Copyright (C) 2021 KikooDX */
#pragma once
#define TILE_OOB TILE_SOLID
enum {
TILE_OOB = -1,
TILE_VOID,
TILE_SOLID,
TILE_START,

View File

@ -3,11 +3,14 @@
#include "conf.h"
#include "level.h"
#include "tiles.h"
#include <libimg.h>
extern struct Level level;
extern img_t const img_tileset;
static int autotile_value(int x, int y);
void level_draw(void)
{
int x;
@ -22,7 +25,14 @@ void level_draw(void)
const int draw_x = x * TILE_WIDTH;
const Tile tile =
level.data[x + y * level.width];
img_render_vram(
switch (tile) {
case TILE_VOID: break;
case TILE_SOLID: {
const int autotile = autotile_value(x, y) * TILE_WIDTH;
img_render_vram(img_sub(img_tileset, autotile, TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT), draw_x, draw_y);
}
break;
default: img_render_vram(
img_sub(img_tileset,
(int)(tile % tileset_width) *
TILE_WIDTH,
@ -30,6 +40,15 @@ void level_draw(void)
TILE_HEIGHT,
TILE_WIDTH, TILE_HEIGHT),
draw_x, draw_y);
break;
}
}
}
}
static int autotile_value(int x, int y) {
return ((level_get_tile(x - 1, y) == TILE_SOLID) |
((level_get_tile(x + 1, y) == TILE_SOLID) << 1) |
((level_get_tile(x, y - 1) == TILE_SOLID) << 2) |
((level_get_tile(x, y + 1) == TILE_SOLID) << 3));
}

13
src/level/get_tile.c Normal file
View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "level.h"
#include "tiles.h"
extern struct Level level;
Tile level_get_tile(int x, int y) {
if (x < 0 || y < 0 || x >= level.width || y >= level.height)
return TILE_OOB;
return level.data[x + y * level.width];
}

View File

@ -4,6 +4,7 @@
#include "conf.h"
#include "level.h"
#include "player.h"
#include "particles.h"
#include <gint/clock.h>
#include <gint/display.h>
#include <gint/gint.h>
@ -42,6 +43,8 @@ int main(void)
PANIC(fatal_error_msg);
/* create player */
struct Player player = player_init();
/* initialize particle engine */
particles_init();
/* timer setup */
timer = timer_setup(TIMER_ANY, 1000000 / TARGET_UPS, callback,
&has_ticked);
@ -60,6 +63,7 @@ int main(void)
has_ticked = 0;
/* update */
clearevents();
particles_update();
player_return_code = player_update(&player);
switch (player_return_code) {
case 1:
@ -67,12 +71,14 @@ int main(void)
gint_switch(level_load);
if (fatal_error == -1)
PANIC(fatal_error_msg);
particles_init();
player = player_init();
break;
case -1:
gint_switch(level_load);
if (fatal_error == -1)
PANIC(fatal_error_msg);
particles_init();
player = player_init();
break;
default:
@ -83,6 +89,7 @@ int main(void)
dclear(C_BLACK);
level_draw();
player_draw(player);
particles_draw();
dupdate();
}

25
src/particles/create.c Normal file
View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "particles.h"
#include <libimg.h>
extern struct Particle particles[MAX_PARTICLES];
void particle_create(img_t *texture, int x, int y, int frame_width, int frame_duration) {
/* find unused slot */
int i = MAX_PARTICLES;
while (i --> 0)
if (!particles[i].life)
break;
struct Particle *particle = &particles[i];
particle->texture = texture;
particle->x = x;
particle->y = y;
particle->frame_width = frame_width;
particle->frame_height = texture->height;
particle->frame_duration = frame_duration;
particle->frame = 0;
particle->life = frame_duration * texture->width / frame_width;
}

21
src/particles/draw.c Normal file
View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "particles.h"
#include <libimg.h>
extern struct Particle particles[MAX_PARTICLES];
static void particle_draw(struct Particle particle);
void particles_draw(void) {
int i = MAX_PARTICLES;
while (i --> 0)
particle_draw(particles[i]);
}
static void particle_draw(struct Particle particle) {
if (!particle.life) return;
img_render_vram(img_sub(*particle.texture, particle.frame * particle.frame_width, 0, particle.frame_width, particle.frame_height), particle.x, particle.y);
}

20
src/particles/init.c Normal file
View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "particles.h"
struct Particle particles[MAX_PARTICLES];
void particles_init(void) {
int i = MAX_PARTICLES;
while (i --> 0) {
particles[i] = (struct Particle){
.x = 0,
.y = 0,
.texture = NULL,
.frame_width = 0,
.frame = 0,
.life = 0,
};
}
}

22
src/particles/update.c Normal file
View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "particles.h"
extern struct Particle particles[MAX_PARTICLES];
static void particle_update(struct Particle *particle);
void particles_update(void) {
int i = MAX_PARTICLES;
while (i --> 0)
particle_update(&particles[i]);
}
static void particle_update(struct Particle *particle) {
if (!particle->life) return;
particle->life -= 1;
if (!(particle->life % particle->frame_duration))
particle->frame += 1;
}

View File

@ -5,9 +5,13 @@
#include "level.h"
#include "player.h"
#include "tiles.h"
#include "particles.h"
#include <libimg.h>
extern struct Level level;
extern img_t img_coin_particle;
static Tile collide_single(int x, int y);
static int collide_sub_single(int x, int y, Tile sub, Tile rep);
@ -60,10 +64,7 @@ static Tile collide_single(int x, int y)
{
const int tx = x / TILE_WIDTH;
const int ty = y / TILE_WIDTH;
/* out of bounds handling */
if (x < 0 || y < 0 || tx >= level.width || ty >= level.height)
return TILE_OOB;
return level.data[tx + ty * level.width];
return level_get_tile(tx, ty);
}
/* try collide and replace tile at pixel position, return 1 if tile
@ -75,6 +76,8 @@ static int collide_sub_single(int x, int y, Tile sub, Tile rep)
(int)(x / TILE_WIDTH) +
(int)(y / TILE_WIDTH) * level.width;
level.data[tile_index] = rep;
if (sub == TILE_GOLD)
particle_create(&img_coin_particle, (int)(x / TILE_WIDTH) * TILE_WIDTH, (int)(y / TILE_HEIGHT) * TILE_HEIGHT, TILE_WIDTH, 2);
return 1;
}
return 0;