1
1
Fork 0
Browse Source

fix camera somewhat

emscriptem
alistair 4 years ago
parent
commit
a903cb6839
  1. 2
      Makefile
  2. 188
      src/draw.c
  3. 9
      src/game.c
  4. 6
      src/main.c
  5. 1
      src/types.h

2
Makefile

@ -6,6 +6,8 @@ ifndef target @@ -6,6 +6,8 @@ ifndef target
target=linux
endif
debug = true
ifeq ($(target),windows)
CC=x86_64-w64-mingw32-gcc
SDL_INCLUDE = -Dmain=SDL_main -Lsdllib -lSDL2main -lSDL2main -lSDL2 -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,-static -lpthread -lm

188
src/draw.c

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
#include "draw.h"
#include "game.h"
#include <SDL2/SDL_mutex.h>
#include <time.h>
Vect viewport_pos;
int width, height;
@ -9,6 +11,8 @@ int MAX_ONSCREEN_OBJECTS = 99; @@ -9,6 +11,8 @@ int MAX_ONSCREEN_OBJECTS = 99;
int num_onscreen = 0;
double time_delta = 0;
void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,int x, int y) {
/* draw a texture at x.y */
@ -35,6 +39,20 @@ void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,i @@ -35,6 +39,20 @@ void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,i
/*return (png_image);*/
/*}*/
double sigmoid(double x) {
return exp(x) / (exp(x) + 1);
}
struct timespec get_now_d() {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_nsec >= 1000000000) {
now.tv_nsec -= 1000000000;
}
return now;
}
Vect in_view(Vect V) {
Vect ret;
ret.x = V.x -viewport_pos.x;
@ -59,13 +77,9 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) { @@ -59,13 +77,9 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
player_rect.w = 20;
player_rect.h = 20;
if (red) {
SDL_SetRenderDrawColor(ren, 255, 0, 0, 255);
} else {
struct colour c = get_scene_at(viewport_pos, level).colours.bg;
struct colour c = get_scene_at(viewport_pos, level).colours.bg;
SDL_SetRenderDrawColor(ren, c.r, c.g, c.b, 255);
}
SDL_SetRenderDrawColor(ren, c.r, c.g, c.b, 255);
SDL_RenderDrawRect(ren, &player_rect);
SDL_RenderFillRect(ren, &player_rect);
@ -74,8 +88,8 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) { @@ -74,8 +88,8 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
if (!player.physics->strings[i].attached) {
continue;
}
Vect B;
B = in_view(player.physics->position);
Vect B = {x, y};
B = in_view(B);
Vect E;
E = in_view(player.physics->strings[i].end_point);
SDL_RenderDrawLine(ren, B.x, B.y, E.x, E.y);
@ -253,24 +267,133 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) { @@ -253,24 +267,133 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) {
return frac;
}
void update_viewport(double x, double y) {
void new_update_viewport(Body const * const pl) {
int const xmargin = 100; // pixels
int const ymargin = 100; // pixels
int const xmovmagin = width / 4;
int const ymovmagin = height / 3;
double const xrange = width - (2 * xmargin);
double const yrange = height - (2 * ymargin);
double const x_max = 2;
double const y_max = 3;
static Vect target = {};
static double dirchange = 0;
static Vect last_plpos = {};
if (last_plpos.x == 0 && last_plpos.y == 0)
last_plpos = player.physics->position;
printf("%f %f\n", pl->vel.x, pl->vel.y);
static Vect lmove = {};
Vect iv = in_view(pl->position);
printf("player pos: %f %f\n", pl->position.x, pl->position.y);
Vect left_pos = {0, 2 * height / 4};
left_pos = vect_add(pl->position, vect_scalar(left_pos, -1));
Vect right_pos = {7 * (width / 8), 2 * height / 4};
right_pos = vect_add(pl->position, vect_scalar(right_pos, -1));
bool recover = false;
Vect screen_dist = vect_add(in_view(pl->position), vect_scalar(lmove, -1));
if (iv.x > width
|| (iv.x < 0
|| iv.y > height
|| iv.y < 0))
recover = true;
Vect delta = vect_add(vect_scalar(player.physics->position, -1), last_plpos);
double dist_change = vect_mag(delta);
if (true || (recover) //|| vect_mag((Vect){pl->vel.x, 0}) > 0.4
|| (dist_change > width / 100)) {
if (iv.x < width / 6) {
printf("RIGHT\n");
target = right_pos;
} else {
printf("LEFT\n");
target = left_pos;
}
lmove = target;
last_plpos = player.physics->position;
}
if (recover)
viewport_pos = target;
// emergency
/*if (!(iv.x > width / 3 && iv.x < (2 * (width / 3)))) {*/
/*if (!(iv.y > height / 3 && iv.y < (2 * (height / 3)))) {*/
/*if ( true ||*/
/*( in_view(pl->position).x > xmargin + xrange */
/*|| in_view(pl->position).x < xmargin)*/
/*) */
/*{*/
/*double m = (width / 2) / (2.0 * x_max);*/
/*double x = m * v;*/
/*target.x = pl->position.x - x;*/
/*}*/
//target.y = pl->position.y - height/2; // + y;
printf("viewport pos: %f %f\n", iv.x, iv.y);
printf("target pos: %f %f\n", target.x, iv.y);
/*}*/
/*}*/
double v = pl->vel.x;
if (v > x_max)
v = x_max;
if (v < -x_max)
v = -x_max;
if (v < 0)
v = -v;
// move towards target a set proportion
Vect urgency = vect_add(target, vect_scalar(player.physics->position, -1));
Vect p = vect_add(target, vect_scalar(viewport_pos, -1));
printf("drawtime: %f", time_delta);
double proportion = (sigmoid(time_delta) / 100);
proportion = 2 * player.physics->vel.x / (width);
proportion = proportion < 0 ? -proportion : proportion;
printf("prop: %f", proportion);
proportion > 0.4 ? proportion = 0.4 : 0;
proportion < 0 ? proportion = 0.000001 : 0;
p = vect_scalar(p, proportion);
viewport_pos = vect_add(viewport_pos, p);
}
void update_viewport(Body *pl) {
float xmargin = 0.5;
float ymargin = 0.2;
if (player.physics->position.x - viewport_pos.x > (1-xmargin) * width) {
viewport_pos.x = - ((1-xmargin) * width - player.physics->position.x);
if (pl->position.x - viewport_pos.x > (1-xmargin) * width) {
viewport_pos.x = - ((1-xmargin) * width - pl->position.x);
}
if (player.physics->position.x - viewport_pos.x < xmargin * width) {
viewport_pos.x = -(xmargin * width - player.physics->position.x);
if (pl->position.x - viewport_pos.x < xmargin * width) {
viewport_pos.x = -(xmargin * width - pl->position.x);
}
if (player.physics->position.y - viewport_pos.y > (1-ymargin) * height) {
viewport_pos.y = -((1-ymargin) * height - player.physics->position.y);
if (pl->position.y - viewport_pos.y > (1-ymargin) * height) {
viewport_pos.y = -((1-ymargin) * height - pl->position.y);
}
if (player.physics->position.y - viewport_pos.y < ymargin * height) {
viewport_pos.y = -(ymargin * height - player.physics->position.y);
if (pl->position.y - viewport_pos.y < ymargin * height) {
viewport_pos.y = -(ymargin * height - pl->position.y);
}
}
@ -426,8 +549,26 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -426,8 +549,26 @@ void redraw_buffer(SDL_Renderer * ren) {
/*}*/
/*}*/
int col = 0;
Body lplayer;
if (SDL_LockMutex(player.physics->lock) == 0){
lplayer = *player.physics;
SDL_UnlockMutex(player.physics->lock);
} else {
return;
}
new_update_viewport(&lplayer);
static struct timespec last = {};
static struct timespec now;
now = get_now_d();
time_delta = now.tv_nsec - last.tv_nsec;
time_delta *= 0.000001; // convert to ms from ns
last = now;
//SDL_GetMouseState(&newmousex, &newmousey);
update_viewport(player.physics->position.x, player.physics->position.y);
struct environment scene = get_scene_at(viewport_pos, level);
draw_environment(ren, &scene);
@ -438,11 +579,6 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -438,11 +579,6 @@ void redraw_buffer(SDL_Renderer * ren) {
thing = world.get(i);
switch (thing.kind) {
case PLAYER:
draw_player(ren, (*thing.player).physics->position.x, (*thing.player).physics->position.y, thing.player->colliding);
draw_collision_poly(ren, thing.player->physics);
draw_forces(ren, thing.player->physics);
continue;
case STATIC_WALL_W:
draw_wall(ren, thing.wall);
draw_collision_poly(ren, thing.wall->physics);
@ -471,6 +607,12 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -471,6 +607,12 @@ void redraw_buffer(SDL_Renderer * ren) {
}
}
draw_player(ren, lplayer.position.x, lplayer.position.y,
lplayer.colliding);
draw_collision_poly(ren, &lplayer);
draw_forces(ren, &lplayer);
/*if (newmousex != mousex || newmousey != mousey) {*/ /*mousey = newmousey;*/
/*mousex = newmousex;*/
/*for (int i = 0; i < 256; i++) {*/

9
src/game.c

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
#include "game.h"
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_mutex.h>
#define FLOOR_THICKNESS 200
#define MAX_ROPE_GRAB_LEN 80000
@ -225,6 +226,7 @@ player_st get_player(int x, int y) { @@ -225,6 +226,7 @@ player_st get_player(int x, int y) {
// physics settings
get_new_physics(&player.physics);
player.physics->dynamics = true;
player.physics->lock = SDL_CreateMutex();
player.physics->position.x = x;
player.physics->position.y = y;
@ -1266,6 +1268,10 @@ void advance_thing(Body * thing) { @@ -1266,6 +1268,10 @@ void advance_thing(Body * thing) {
double oldy = thing->position.y;
thing->next_position.x += (thing->vel.x * 1/2 * (double)time_delta);
thing->next_position.y += (thing->vel.y * 1/2 * (double)time_delta);
if (thing->lock) {
SDL_LockMutex(thing->lock);
}
thing->position = thing->next_position;
if (!thing->collision_poly[0].y) {
@ -1273,6 +1279,9 @@ void advance_thing(Body * thing) { @@ -1273,6 +1279,9 @@ void advance_thing(Body * thing) {
}
thing->updateCollisionPoly(thing);
if (thing->lock) {
SDL_UnlockMutex(thing->lock);
}
}

6
src/main.c

@ -39,8 +39,8 @@ void redraw(struct SDL_Renderer * ren) { @@ -39,8 +39,8 @@ void redraw(struct SDL_Renderer * ren) {
int physics_loop(void *ptr) {
while (true) {
SDL_Delay(10);
step(10);
SDL_Delay(5);
}
}
@ -73,10 +73,12 @@ int game(void) { @@ -73,10 +73,12 @@ int game(void) {
SDL_Thread *physics_thread;
int ignore;
// physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
bool once = true;
startgame(ren);
// physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
while (!close) {
SDL_Event event;

1
src/types.h

@ -82,6 +82,7 @@ typedef struct BodyStruct{ @@ -82,6 +82,7 @@ typedef struct BodyStruct{
// position in viewport (pixels)
SDL_Point screen_pos;
SDL_mutex * lock;
// SI Unit kinematics
/*------------------*/

Loading…
Cancel
Save