summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Manuel Tomas <jtomas1815@gmail.com>2022-01-26 01:58:42 -0300
committerJuan Manuel Tomas <jtomas1815@gmail.com>2022-01-26 01:58:42 -0300
commita8ff0d19d27697c931315da9d59d623dd71ceae7 (patch)
treeee3ea65adfe9853ae753512b7d609e824b4554df
parentaa470df479e629650ca1d675088664d4d22c1874 (diff)
downloadcannons-a8ff0d19d27697c931315da9d59d623dd71ceae7.tar.gz
cannons-a8ff0d19d27697c931315da9d59d623dd71ceae7.zip
Extract terrain concept
-rw-r--r--main.c102
1 files changed, 62 insertions, 40 deletions
diff --git a/main.c b/main.c
index 9bcd467..539180a 100644
--- a/main.c
+++ b/main.c
@@ -26,6 +26,28 @@ typedef struct {
int alive;
} Projectile;
+typedef struct {
+ float *mask;
+ int width;
+ int height;
+ int updated;
+} Terrain;
+
+void PaintTerrain(Terrain *t, float x, float y, float color, float size) {
+ for (int j = y - size; j < y + size; j++) {
+ for (int i = x - size; i < x + size; i++) {
+ float dj = y - j;
+ float di = x - i;
+ if (i > 0 && i < t->width && j > 0 && j < t->height
+ && dj * dj + di * di <= size * size / 2) {
+ size_t index = i + j * t->width;
+ t->mask[index] = color;
+ }
+ }
+ }
+ t->updated = 1;
+}
+
static inline double GetCurrentTimestamp() {
return (double) SDL_GetTicks64() / 1000.0;
}
@@ -53,41 +75,31 @@ SDL_Texture *CreateTiledTexture(SDL_Renderer *context, const char *filename, int
return texture;
}
-void PaintMask(float *mask, int width, int height, float x, float y, float color, float size) {
- for (int j = y - size; j < y + size; j++) {
- for (int i = x - size; i < x + size; i++) {
- float dj = y - j;
- float di = x - i;
- if (i > 0 && i < width && j > 0 && j < height
- && dj * dj + di * di <= size * size / 2) {
- size_t index = i + j * width;
- mask[index] = color;
- }
- }
- }
-}
-
void GameMain(SDL_Renderer *context) {
SDL_Texture *background = CreateTiledTexture(context, "background.bmp", WINDOW_W, WINDOW_H);
SDL_Texture *foreground = CreateTiledTexture(context, "foreground.bmp", WINDOW_W, WINDOW_H);
SDL_SetTextureBlendMode(foreground, SDL_BLENDMODE_MOD);
- SDL_Texture *terrain = SDL_CreateTexture(context,
+ SDL_Texture *terrain_texture = SDL_CreateTexture(context,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET,
WINDOW_W, WINDOW_H);
- SDL_SetTextureBlendMode(terrain, SDL_BLENDMODE_BLEND);
+ SDL_SetTextureBlendMode(terrain_texture, SDL_BLENDMODE_BLEND);
SDL_Texture *mask_texture = SDL_CreateTexture(context,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING,
WINDOW_W, WINDOW_H);
- float *mask = calloc(WINDOW_W * WINDOW_H, sizeof(float));
+ Terrain terrain = {0};
+ terrain.width = WINDOW_W;
+ terrain.height = WINDOW_H;
+ terrain.mask = calloc(WINDOW_W * WINDOW_H, sizeof(float));
for (int i = 0; i < 100 * WINDOW_W; i++) {
- mask[i] = 1.0;
+ terrain.mask[i] = 1.0;
}
+ terrain.updated = 1;
Cannon player = {0};
player.x = 100;
@@ -100,15 +112,12 @@ void GameMain(SDL_Renderer *context) {
int exit = 0;
while (!exit) {
- double new_t = GetCurrentTimestamp();
- double dt = (new_t - old_t) * 10;
- old_t = new_t;
-
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
exit = 1;
- } else if (event.type == SDL_KEYDOWN && event.key.state == SDL_PRESSED && event.key.keysym.sym == SDLK_SPACE && !projectile.alive) {
+ } else if (event.type == SDL_KEYDOWN && event.key.state == SDL_PRESSED &&
+ event.key.keysym.sym == SDLK_SPACE && !projectile.alive) {
projectile.alive = 1;
projectile.x = player.x;
projectile.y = player.y;
@@ -116,13 +125,20 @@ void GameMain(SDL_Renderer *context) {
projectile.vx = cos(player.angle) * player.power;
}
}
+ int simulation_frames = 10;
+ while (simulation_frames > 0) {
+ simulation_frames--;
+ double new_t = GetCurrentTimestamp();
+ double dt = (new_t - old_t);
+ old_t = new_t;
+
int mouse_x, mouse_y;
Uint32 mouse_state = SDL_GetMouseState(&mouse_x, &mouse_y);
float size = 20;
if (mouse_state & SDL_BUTTON_LMASK) {
- PaintMask(mask, WINDOW_W, WINDOW_H, mouse_x, WINDOW_H - mouse_y, 1.0, size);
+ PaintTerrain(&terrain, mouse_x, WINDOW_H - mouse_y, 1.0, size);
} else if (mouse_state & SDL_BUTTON_RMASK) {
- PaintMask(mask, WINDOW_W, WINDOW_H, mouse_x, WINDOW_H - mouse_y, 0.0, size);
+ PaintTerrain(&terrain, mouse_x, WINDOW_H - mouse_y, 0.0, size);
}
const Uint8 *keys = SDL_GetKeyboardState(0);
@@ -136,6 +152,7 @@ void GameMain(SDL_Renderer *context) {
player.angle += PI / 180 * dt;
}
if (keys[SDL_SCANCODE_S] && player.angle > 0) {
+
player.angle -= PI / 180 * dt;
}
@@ -143,11 +160,11 @@ void GameMain(SDL_Renderer *context) {
player.y = WINDOW_H - 1;
player.vy = 0;
}
- if (mask[(int)player.x + (int)player.y * WINDOW_W] == 0.0 &&
+ if (terrain.mask[(int)player.x + (int)player.y * WINDOW_W] == 0.0 &&
player.y >= 0) {
player.y += player.vy * dt;
player.vy += GRAVITY * dt;
- while (mask[(int)player.x + (int)player.y * WINDOW_W] != 0.0) {
+ while (terrain.mask[(int)player.x + (int)player.y * WINDOW_W] != 0.0) {
player.y += 1;
player.vy = 0;
}
@@ -156,45 +173,50 @@ void GameMain(SDL_Renderer *context) {
if (projectile.alive) {
if (projectile.y >= 0 && projectile.y < WINDOW_H &&
projectile.x >= 0 && projectile.x < WINDOW_W &&
- mask[(int)projectile.x + (int)projectile.y * WINDOW_W] == 0.0) {
+ terrain.mask[(int)projectile.x + (int)projectile.y * WINDOW_W] == 0.0) {
projectile.x += projectile.vx * dt;
projectile.y += projectile.vy * dt;
projectile.vy += GRAVITY * dt;
} else {
projectile.alive = 0;
- PaintMask(mask, WINDOW_W, WINDOW_H, projectile.x, projectile.y, 0.0, 40);
+ PaintTerrain(&terrain, projectile.x, projectile.y, 0.0, 40);
}
}
- void *pixels;
- int pitch;
- SDL_LockTexture(mask_texture, 0, &pixels, &pitch);
- Uint32 *p = (Uint32 *) pixels;
- for (int j = 0; j < WINDOW_H; j++) {
- for (int i = 0; i < WINDOW_W; i++) {
- p[i + j * WINDOW_W] = mask[i + (WINDOW_H - j) * WINDOW_W] ? 0xffffffff : 0x00000000;
+ if (terrain.updated) {
+ void *pixels;
+ int pitch;
+ SDL_LockTexture(mask_texture, 0, &pixels, &pitch);
+ Uint32 *p = (Uint32 *) pixels;
+ for (int j = 0; j < WINDOW_H; j++) {
+ for (int i = 0; i < WINDOW_W; i++) {
+ p[i + j * WINDOW_W] = terrain.mask[i + (WINDOW_H - j) * WINDOW_W] ? 0xffffffff : 0x00000000;
+ }
}
+ SDL_UnlockTexture(mask_texture);
+ terrain.updated = 0;
+ }
}
- SDL_UnlockTexture(mask_texture);
SDL_SetRenderDrawColor(context, 40, 40, 40, 255);
SDL_RenderClear(context);
SDL_RenderCopy(context, background, 0, 0);
- SDL_SetRenderTarget(context, terrain);
+ SDL_SetRenderTarget(context, terrain_texture);
SDL_SetRenderDrawColor(context, 0, 0, 0, 0);
SDL_RenderClear(context);
SDL_RenderCopy(context, mask_texture, 0, 0);
SDL_RenderCopy(context, foreground, 0, 0);
SDL_SetRenderTarget(context, 0);
- SDL_RenderCopy(context, terrain, 0, 0);
+ SDL_RenderCopy(context, terrain_texture, 0, 0);
SDL_SetRenderDrawColor(context, 255, 0, 0, 255);
SDL_Rect player_rect = {player.x - 5, WINDOW_H - player.y - 10, 10, 10 };
SDL_RenderFillRect(context, &player_rect);
- SDL_RenderDrawLine(context, player.x, WINDOW_H - player.y, player.x + cos(player.angle) * 100, WINDOW_H - player.y - sin(player.angle) * 100);
+ SDL_RenderDrawLine(context, player.x, WINDOW_H - player.y,
+ player.x + cos(player.angle) * 100, WINDOW_H - player.y - sin(player.angle) * 100);
if (projectile.alive) {
SDL_SetRenderDrawColor(context, 0, 255, 0, 255);