Commit a003e49d897cb390edebba78247414fe4de77173

Authored by Grzegorz Jabłoński
1 parent 7b5a6fc3

Added tapered bullet example

07-tapered_bullet/cannon.c 0 → 100644
  1 +#include "primlib.h"
  2 +#include <math.h>
  3 +#include <stdlib.h>
  4 +
  5 +struct target {
  6 + int x;
  7 + int y;
  8 + int speed_x;
  9 + int is_explosion;
  10 + int explosion_counter; // how many times we have already displayed an
  11 + // explosion animation
  12 + int color;
  13 +};
  14 +
  15 +// Draw explosion with the center at coordinates (x,y)
  16 +void drawExplosion(int x, int y, float scaling) {
  17 +
  18 + gfx_filledTriangle(x - 7 * scaling, y - 7 * scaling, x + 7 * scaling,
  19 + y + 7 * scaling, x + 22 * scaling, y - 22 * scaling, RED);
  20 + gfx_filledTriangle(x - 7 * scaling, y - 7 * scaling, x + 7 * scaling,
  21 + y + 7 * scaling, x - 22 * scaling, y + 22 * scaling, RED);
  22 + gfx_filledTriangle(x - 7 * scaling, y + 7 * scaling, x + 7 * scaling,
  23 + y - 7 * scaling, x - 22 * scaling, y - 22 * scaling, RED);
  24 + gfx_filledTriangle(x - 7 * scaling, y + 7 * scaling, x + 7 * scaling,
  25 + y - 7 * scaling, x + 22 * scaling, y + 22 * scaling, RED);
  26 +
  27 + gfx_filledTriangle(x - 13 * scaling, y, x + 13 * scaling, y, x,
  28 + y - 35 * scaling, RED);
  29 + gfx_filledTriangle(x - 13 * scaling, y, x + 13 * scaling, y, x,
  30 + y + 35 * scaling, RED);
  31 + gfx_filledTriangle(x, y - 13 * scaling, x, y + 13 * scaling, x - 35 * scaling,
  32 + y, RED);
  33 + gfx_filledTriangle(x, y - 13 * scaling, x, y + 13 * scaling, x + 35 * scaling,
  34 + y, RED);
  35 +}
  36 +
  37 +void draw_target(struct target *t) {
  38 + if (!t->is_explosion)
  39 + gfx_filledRect(t->x - 10, t->y - 10, t->x + 10, t->y + 10,
  40 + t->color); // target
  41 +
  42 + if (t->is_explosion) {
  43 + drawExplosion(t->x, t->y + t->explosion_counter * 10,
  44 + t->explosion_counter / 5.0);
  45 + }
  46 +}
  47 +
  48 +void move_target(struct target *t) {
  49 + if (!t->is_explosion) {
  50 + t->x += t->speed_x;
  51 +
  52 + if (t->x > gfx_screenWidth())
  53 + t->x = 0;
  54 +
  55 + if (t->x < 0)
  56 + t->x = gfx_screenWidth() - 1;
  57 + }
  58 +
  59 + if (t->is_explosion) {
  60 + t->explosion_counter += 1;
  61 + }
  62 +
  63 + if (t->is_explosion && (t->explosion_counter == 10)) {
  64 + t->is_explosion = 0;
  65 + t->x = 0;
  66 + }
  67 +}
  68 +
  69 +void draw_bullet(int x1, int y1, int x2, int y2, int width, double taper, int color) {
  70 + // define vector representing the central line
  71 + int dx = x2 - x1;
  72 + int dy = y2 - y1;
  73 +
  74 + // define vector perpendicular to the central line
  75 + int dy_p = dx;
  76 + int dx_p = dy;
  77 + double len = hypot(dx_p, dy_p);
  78 +
  79 + // scale its length to proper width
  80 + int dy_p_s = width / (2.0 * len) * dy_p;
  81 + int dx_p_s = width / (2.0 * len) * dx_p;
  82 +
  83 + // compute corners
  84 +
  85 + int x1c = x2 - dx_p_s * taper;
  86 + int y1c = y2 + dy_p_s * taper;
  87 +
  88 + int x2c = x2 + dx_p_s * taper;
  89 + int y2c = y2 - dy_p_s * taper;
  90 +
  91 + int x3c = x1 - dx_p_s;
  92 + int y3c = y1 + dy_p_s;
  93 +
  94 + int x4c = x1 + dx_p_s;
  95 + int y4c = y1 - dy_p_s;
  96 +
  97 + gfx_filledTriangle(x1c, y1c, x2c, y2c, x3c, y3c, color);
  98 + gfx_filledTriangle(x4c, y4c, x2c, y2c, x3c, y3c, color);
  99 +}
  100 +
  101 +int main() {
  102 + if (gfx_init())
  103 + exit(3);
  104 +
  105 + double angle = 90.0 * (M_PI / 180.0);
  106 +
  107 + double bullet_distance;
  108 + int is_shooting = 0;
  109 + double fire_angle;
  110 +
  111 + const int num_targets = 3;
  112 +
  113 + struct target t[num_targets];
  114 +
  115 + t[0].x = 0;
  116 + t[0].y = 40;
  117 + t[0].speed_x = 3;
  118 + t[0].is_explosion = 0;
  119 + t[0].color = MAGENTA;
  120 +
  121 + t[1].x = 1000;
  122 + t[1].y = 80;
  123 + t[1].speed_x = -5;
  124 + t[1].is_explosion = 0;
  125 + t[1].color = WHITE;
  126 +
  127 + t[2].x = 100;
  128 + t[2].y = 120;
  129 + t[2].speed_x = 7;
  130 + t[2].is_explosion = 0;
  131 + t[2].color = GREEN;
  132 +
  133 + while (1) {
  134 + double delta_angle = 2.0 * (M_PI / 180.0);
  135 + int x1_barrel = 150 * cos(angle - delta_angle);
  136 + int y1_barrel = 150 * sin(angle - delta_angle);
  137 + int x2_barrel = 150 * cos(angle + delta_angle);
  138 + int y2_barrel = 150 * sin(angle + delta_angle);
  139 + gfx_filledRect(0, 0, gfx_screenWidth() - 1, gfx_screenHeight() - 1, BLUE);
  140 +
  141 + gfx_filledCircle(gfx_screenWidth() / 2, gfx_screenHeight(), 100, YELLOW);
  142 + gfx_filledTriangle(gfx_screenWidth() / 2, gfx_screenHeight(),
  143 + gfx_screenWidth() / 2 + x1_barrel,
  144 + gfx_screenHeight() - y1_barrel,
  145 + gfx_screenWidth() / 2 + x2_barrel,
  146 + gfx_screenHeight() - y2_barrel, YELLOW);
  147 +
  148 + for (int i = 0; i < num_targets; ++i)
  149 + draw_target(&(t[i]));
  150 +
  151 + // bullet position wrt the center of the bottom of the screen
  152 + int x_bullet_begin = bullet_distance * cos(fire_angle);
  153 + int y_bullet_begin = bullet_distance * sin(fire_angle);
  154 +
  155 + int x_bullet_end = (bullet_distance + 30) * cos(fire_angle);
  156 + int y_bullet_end = (bullet_distance + 30) * sin(fire_angle);
  157 +
  158 + // bullet position wrt the top-left corner
  159 + int x_bullet_begin_tlc = gfx_screenWidth() / 2 + x_bullet_begin;
  160 + int y_bullet_begin_tlc = gfx_screenHeight() - y_bullet_begin;
  161 +
  162 + int x_bullet_end_tlc = gfx_screenWidth() / 2 + x_bullet_end;
  163 + int y_bullet_end_tlc = gfx_screenHeight() - y_bullet_end;
  164 +
  165 + if (is_shooting) {
  166 + draw_bullet(x_bullet_begin_tlc, y_bullet_begin_tlc, x_bullet_end_tlc,
  167 + y_bullet_end_tlc, 10, 0.5, RED);
  168 + }
  169 +
  170 + gfx_updateScreen();
  171 +
  172 + if (is_shooting) {
  173 + for (int i = 0; i < num_targets; ++i) {
  174 + if (hypot(x_bullet_begin_tlc - t[i].x, y_bullet_begin_tlc - t[i].y) <
  175 + 50) {
  176 + t[i].is_explosion = 1;
  177 + t[i].explosion_counter = 0;
  178 + }
  179 + }
  180 + bullet_distance += 10.0;
  181 + }
  182 +
  183 + for (int i = 0; i < num_targets; ++i)
  184 + move_target(&(t[i]));
  185 +
  186 + if (gfx_isKeyDown(SDLK_RIGHT))
  187 + angle -= 1.0 * (M_PI / 180.0);
  188 + if (gfx_isKeyDown(SDLK_LEFT))
  189 + angle += 1.0 * (M_PI / 180.0);
  190 + if (gfx_isKeyDown(SDLK_SPACE)) {
  191 + is_shooting = 1;
  192 + bullet_distance = 170.0;
  193 + fire_angle = angle;
  194 + }
  195 + SDL_Delay(10);
  196 + };
  197 + return 0;
  198 +}
... ...
07-tapered_bullet/makefile 0 → 100755
  1 +TARGET=cannon
  2 +
  3 +all: $(TARGET)
  4 +
  5 +%.o:%.c
  6 + gcc -g -I.. -Wall -pedantic `sdl2-config --cflags` -c $< -o $@
  7 +
  8 +%: %.c ../primlib.o %.c
  9 + gcc -g -I.. -Wall -pedantic `sdl2-config --cflags` ../primlib.o $< -o $@ -lSDL2_gfx `sdl2-config --libs` -lm
  10 +
  11 +../primlib.o: ../primlib.c ../primlib.h
  12 +
  13 +$(TARGET): $(TARGET).c ../primlib.h
  14 +
  15 +clean:
  16 + -rm $(TARGET)
0 17 \ No newline at end of file
... ...