first half of smart missiles
This commit is contained in:
parent
e912ed7b9a
commit
72ad64c780
|
@ -11,6 +11,7 @@ include_directories(inc)
|
|||
|
||||
set(SOURCES
|
||||
src/main.c
|
||||
src/vec.c
|
||||
src/util.c
|
||||
src/draw.c
|
||||
src/input.c
|
||||
|
@ -19,6 +20,7 @@ set(SOURCES
|
|||
src/player.c
|
||||
src/polarity.c
|
||||
src/time.c
|
||||
src/missile.c
|
||||
)
|
||||
|
||||
set(ASSETS
|
||||
|
|
|
@ -22,3 +22,6 @@
|
|||
#define BOUNCE_SPEED -2.0f
|
||||
#define DRAW_OFF_X -2
|
||||
#define GRAVS_MARGIN 0
|
||||
#define MISSILE_MAX_SPEED 4.0f
|
||||
#define MISSILE_ACCEL 0.06f
|
||||
#define MISSILE_FRICTION (MISSILE_ACCEL / MISSILE_MAX_SPEED)
|
||||
|
|
|
@ -12,6 +12,7 @@ enum Key {
|
|||
K_EDITOR,
|
||||
K_SCROLL_UP,
|
||||
K_SCROLL_DOWN,
|
||||
K_DEBUG,
|
||||
K_COUNT
|
||||
};
|
||||
enum KeyState { KS_UP, KS_DOWN, KS_PRESS };
|
||||
|
|
|
@ -39,4 +39,5 @@ int level_get_px(int x, int y);
|
|||
void level_set(int x, int y, int v);
|
||||
void level_set_px(int x, int y, int v);
|
||||
struct Vec level_find(enum Tile);
|
||||
int level_count(enum Tile);
|
||||
struct Vec level_dim(void);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
#include "vec.h"
|
||||
|
||||
struct Missile {
|
||||
int active;
|
||||
struct VecF pos, spd;
|
||||
};
|
||||
|
||||
struct MissileManager {
|
||||
int n_missiles;
|
||||
struct Missile *missiles;
|
||||
};
|
||||
|
||||
void missile_manager_init(void);
|
||||
void missile_manager_free(void);
|
||||
void missile_manager_update(struct VecF target);
|
||||
void missile_manager_draw(void);
|
||||
struct Missile *missile_new(int x, int y);
|
|
@ -12,5 +12,7 @@ struct Player {
|
|||
|
||||
void player_spawn(struct Player *);
|
||||
void player_update(struct Player *);
|
||||
void player_draw(struct Player *);
|
||||
void player_draw(const struct Player *);
|
||||
void player_move(struct Player *, struct Vec);
|
||||
|
||||
struct Vec player_middle(const struct Player *);
|
||||
|
|
|
@ -16,6 +16,7 @@ enum Tile {
|
|||
TILE_WATER,
|
||||
TILE_BURN_RED,
|
||||
TILE_BURN_BLUE,
|
||||
TILE_MISSILE_LAUNCHER,
|
||||
TILE_COUNT,
|
||||
TILE_OOB = TILE_BURN,
|
||||
};
|
||||
|
|
|
@ -7,3 +7,8 @@ struct Vec {
|
|||
struct VecF {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
struct VecF vecf(struct Vec);
|
||||
struct Vec vec(struct VecF);
|
||||
|
||||
struct VecF normalize(struct VecF);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
static struct Input input;
|
||||
static const int default_map[K_COUNT] = {
|
||||
KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_SHIFT, KEY_ALPHA,
|
||||
KEY_EXIT, KEY_TAN, KEY_F3, KEY_F2, KEY_F1};
|
||||
KEY_EXIT, KEY_TAN, KEY_F3, KEY_F2, KEY_F1, KEY_F6};
|
||||
|
||||
void
|
||||
input_init(void)
|
||||
|
|
12
src/level.c
12
src/level.c
|
@ -1,5 +1,6 @@
|
|||
#include "level.h"
|
||||
#include "conf.h"
|
||||
#include "missile.h"
|
||||
#include "player.h"
|
||||
#include "polarity.h"
|
||||
#include "tile.h"
|
||||
|
@ -62,6 +63,7 @@ level_load(int id)
|
|||
polarity_reset();
|
||||
level_regen_visual_data(0);
|
||||
player_spawn(level.player);
|
||||
missile_manager_init();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -169,6 +171,16 @@ level_find(enum Tile t)
|
|||
return (struct Vec){i % level.width, i / level.width};
|
||||
}
|
||||
|
||||
int
|
||||
level_count(enum Tile t)
|
||||
{
|
||||
int c = 0;
|
||||
int i = level.size;
|
||||
while (i-- > 0)
|
||||
c += level.data[i] == t;
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Vec
|
||||
level_dim(void)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "editor.h"
|
||||
#include "input.h"
|
||||
#include "level.h"
|
||||
#include "missile.h"
|
||||
#include "player.h"
|
||||
#include "time.h"
|
||||
#include "util.h"
|
||||
|
@ -70,6 +71,7 @@ static void
|
|||
deinit(void)
|
||||
{
|
||||
level_deinit();
|
||||
missile_manager_free();
|
||||
|
||||
timer_stop(timer);
|
||||
}
|
||||
|
@ -78,9 +80,12 @@ static void
|
|||
update(void)
|
||||
{
|
||||
input_update();
|
||||
missile_manager_update(vecf(player_middle(&player)));
|
||||
player_update(&player);
|
||||
/* enter editor */
|
||||
if (input_pressed(K_EDITOR)) editor();
|
||||
/* debug: spawn missile */
|
||||
if (input_pressed(K_DEBUG)) missile_new(DWIDTH / 2, DHEIGHT / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -88,6 +93,7 @@ draw(void)
|
|||
{
|
||||
dclear(C_BLACK);
|
||||
level_draw();
|
||||
missile_manager_draw();
|
||||
player_draw(&player);
|
||||
level_draw_name();
|
||||
time_draw();
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
#include "missile.h"
|
||||
#include "conf.h"
|
||||
#include "level.h"
|
||||
#include <gint/display.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static struct MissileManager manager = {.missiles = NULL};
|
||||
|
||||
static void missile_update(struct Missile *, struct VecF target);
|
||||
static void missile_draw(const struct Missile *);
|
||||
|
||||
void
|
||||
missile_manager_init(void)
|
||||
{
|
||||
int i;
|
||||
missile_manager_free();
|
||||
/* debug: remove the `1 + ` later on */
|
||||
manager.n_missiles = 1 + level_count(TILE_MISSILE_LAUNCHER);
|
||||
manager.missiles = malloc(manager.n_missiles * sizeof(struct Missile));
|
||||
|
||||
i = manager.n_missiles;
|
||||
while (i-- > 0)
|
||||
manager.missiles[i].active = 0;
|
||||
}
|
||||
|
||||
void
|
||||
missile_manager_free(void)
|
||||
{
|
||||
if (manager.missiles != NULL) free(manager.missiles);
|
||||
}
|
||||
|
||||
void
|
||||
missile_manager_update(struct VecF target)
|
||||
{
|
||||
int i = manager.n_missiles;
|
||||
while (i-- > 0)
|
||||
if (manager.missiles[i].active)
|
||||
missile_update(&manager.missiles[i], target);
|
||||
}
|
||||
|
||||
void
|
||||
missile_manager_draw(void)
|
||||
{
|
||||
int i = manager.n_missiles;
|
||||
while (i-- > 0)
|
||||
if (manager.missiles[i].active)
|
||||
missile_draw(&manager.missiles[i]);
|
||||
}
|
||||
|
||||
struct Missile *
|
||||
missile_new(int x, int y)
|
||||
{
|
||||
int i = manager.n_missiles;
|
||||
struct Missile *m;
|
||||
while (i-- > 0 && manager.missiles[i].active)
|
||||
;
|
||||
m = &manager.missiles[(i > 0) ? (i) : (0)];
|
||||
|
||||
m->active = 1;
|
||||
m->pos.x = x;
|
||||
m->pos.y = y;
|
||||
m->spd.x = 0.0f;
|
||||
m->spd.y = 0.0f;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
static void
|
||||
missile_update(struct Missile *m, struct VecF target)
|
||||
{
|
||||
const struct VecF diff = {target.x - m->pos.x, target.y - m->pos.y};
|
||||
const struct VecF dir = normalize(diff);
|
||||
|
||||
/* acceleration */
|
||||
m->spd.x += dir.x * MISSILE_ACCEL;
|
||||
m->spd.y += dir.y * MISSILE_ACCEL;
|
||||
|
||||
/* friction */
|
||||
m->spd.x *= 1 - MISSILE_FRICTION;
|
||||
m->spd.y *= 1 - MISSILE_FRICTION;
|
||||
|
||||
/* move */
|
||||
m->pos.x += m->spd.x;
|
||||
m->pos.y += m->spd.y;
|
||||
}
|
||||
|
||||
static void
|
||||
missile_draw(const struct Missile *m)
|
||||
{
|
||||
dpixel(m->pos.x + 0.5f, m->pos.y + 0.5f, C_RED);
|
||||
}
|
|
@ -170,7 +170,7 @@ player_update(struct Player *p)
|
|||
}
|
||||
|
||||
void
|
||||
player_draw(struct Player *p)
|
||||
player_draw(const struct Player *p)
|
||||
{
|
||||
draw_rectangle(C_WHITE, p->pos.x + DRAW_OFF_X, p->pos.y, PLAYER_WIDTH,
|
||||
PLAYER_HEIGHT);
|
||||
|
@ -199,6 +199,13 @@ player_move(struct Player *p, struct Vec spd)
|
|||
p->pos.y -= sign_y;
|
||||
}
|
||||
|
||||
struct Vec
|
||||
player_middle(const struct Player *p)
|
||||
{
|
||||
return (struct Vec){p->pos.x + PLAYER_WIDTH / 2,
|
||||
p->pos.y + PLAYER_HEIGHT / 2};
|
||||
}
|
||||
|
||||
static void
|
||||
reset_speed(struct Player *p, int x, int y)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#include "vec.h"
|
||||
#include <math.h>
|
||||
|
||||
struct VecF
|
||||
vecf(struct Vec v)
|
||||
{
|
||||
return (struct VecF){v.x, v.y};
|
||||
}
|
||||
|
||||
struct Vec
|
||||
vec(struct VecF v)
|
||||
{
|
||||
return (struct Vec){v.x, v.y};
|
||||
}
|
||||
|
||||
struct VecF
|
||||
normalize(struct VecF v)
|
||||
{
|
||||
const float len = sqrt(v.x * v.x + v.y * v.y);
|
||||
v.x /= len;
|
||||
v.y /= len;
|
||||
return v;
|
||||
}
|
Loading…
Reference in New Issue