commit a6ccaab60f0a46fc93dde60df6e6250f5866834a
Author: thing1 <l.standen@posteo.com>
Date: Wed, 24 Sep 2025 11:29:24 +0100
init commit
Diffstat:
| A | Makefile | | | 10 | ++++++++++ |
| A | tonk | | | 0 | |
| A | tonk.c | | | 164 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,10 @@
+all: tonk
+
+LIBS=-lraylib -lm
+CFLAGS=-ggdb
+
+tonk: tonk.c
+ cc tonk.c -o tonk ${LIBS} ${CFLAGS}
+
+clean:
+ rm tonk
diff --git a/tonk b/tonk
Binary files differ.
diff --git a/tonk.c b/tonk.c
@@ -0,0 +1,164 @@
+#include <raylib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <sys/param.h>
+#include <stdbool.h>
+
+#define TANK_WIDTH 20
+#define TANK_HEIGHT 50
+#define GUN_WIDTH 5
+#define GUN_HEIGHT 30
+#define MAX_SHOTS 100
+
+#define INDEG(rad) (rad * (180 / M_PI))
+#define CLAMP(val, lower, upper) ((val < lower) ? lower : ((val > upper) ? upper: val))
+
+typedef struct tank {
+ Vector2 pos;
+ float rot, gunrot;
+} tank;
+
+typedef struct shot {
+ Vector2 pos;
+ float speed, rot;
+ int bounces;
+ bool exists;
+} shot;
+
+void
+draw_tank(tank t) {
+ Rectangle tank_body = {t.pos.x, t.pos.y, TANK_WIDTH, TANK_HEIGHT};
+ Vector2 tank_origin = {TANK_WIDTH / 2, TANK_HEIGHT / 2};
+ DrawRectanglePro(tank_body, tank_origin, t.rot + 90, DARKGREEN);
+
+
+
+ Rectangle gun_body = {
+ t.pos.x + 5 * cos(t.rot * M_PI / 180),
+ t.pos.y + 5 * sin(t.rot * M_PI / 180),
+ GUN_WIDTH, GUN_HEIGHT};
+
+ Vector2 gun_origin = {GUN_WIDTH / 2, 0};
+ DrawRectanglePro(gun_body, gun_origin, t.gunrot + 90, GREEN);
+
+}
+
+void
+draw_shot(shot shot) {
+ DrawCircleV(shot.pos, 3, RED);
+}
+
+void
+update_tank(tank *t) {
+ float dx = t->pos.x - GetMouseX(), dy = t->pos.y - GetMouseY();
+ float rads = atan((float)(dy / dx));
+ if (rads > 0 && dy < 0) rads = rads + M_PI;
+ else if (rads < 0 && dx < 0) rads = rads + M_PI;
+ t->gunrot = INDEG(rads);
+
+ if (IsKeyDown(KEY_D))
+ t->rot += 0.01;
+ if (IsKeyDown(KEY_A))
+ t->rot -= 0.01;
+
+ if (IsKeyDown(KEY_S)) {
+ t->pos.x += 0.01 * cos(t->rot * M_PI / 180);
+ t->pos.y += 0.01 * sin(t->rot * M_PI / 180);
+ }
+ if (IsKeyDown(KEY_W)) {
+ t->pos.x -= 0.01 * cos(t->rot * M_PI / 180);
+ t->pos.y -= 0.01 * sin(t->rot * M_PI / 180);
+ }
+}
+
+void
+update_shots(shot *shots, int shot_count) {
+ for (int i = 0; i < shot_count; i++) {
+ shot *s = &shots[i];
+
+ if (s->pos.y > GetScreenHeight()) {
+ s->rot = -s->rot;
+ s->pos.y = GetScreenHeight() - 1;
+ s->bounces--;
+ }
+ else if (s->pos.y < 0) {
+ s->rot = -s->rot;
+ s->pos.y = 1;
+ s->bounces--;
+ }
+ if (s->pos.x > GetScreenWidth()) {
+ s->rot = 180-s->rot;
+ s->pos.x = GetScreenWidth() - 1;
+ s->bounces--;
+ }
+ else if (s->pos.x < 0) {
+ s->rot = 180-s->rot;
+ s->pos.x = 1;
+ s->bounces--;
+ }
+
+ if (s->bounces == 0) {
+ s->exists = false;
+ continue;
+ }
+
+ s->pos.x += s->speed * cos(s->rot * M_PI / 180);
+ s->pos.y += s->speed * sin(s->rot * M_PI / 180);
+
+ while (s->rot > 360)
+ s->rot -= 360;
+ }
+}
+
+void
+append_shot(shot *shots, int shot_count, Vector2 pos, float speed, float rot, int bounces, bool exists) {
+ shot new = {
+ {(pos.x + GUN_HEIGHT * cos(rot * M_PI / 180)),
+ (pos.y + GUN_HEIGHT * sin(rot * M_PI / 180))},
+ speed, rot, bounces, exists};
+
+ int i;
+ for (i = 0; i < shot_count; i++) {
+ if (!shots[i].exists)
+ break;
+ }
+
+ memcpy(&shots[i], &new, sizeof(shot));
+}
+
+int
+main() {
+ InitWindow(800, 800, "Tonks!");
+ //ToggleBorderlessWindowed();
+
+ tank t = {
+ {400, 400},
+ 0,
+ 0
+ };
+
+ shot *shots = alloca(MAX_SHOTS * sizeof(shot));
+ memset(shots, 0, MAX_SHOTS * sizeof(shot));
+
+ while (!WindowShouldClose()) {
+ BeginDrawing();
+ ClearBackground(RAYWHITE);
+
+ draw_tank(t);
+ for (int i = 0; i < MAX_SHOTS; i++) {
+ if (shots[i].exists)
+ draw_shot(shots[i]);
+ }
+ EndDrawing();
+
+ if (IsKeyPressed(KEY_SPACE))
+ append_shot(shots, MAX_SHOTS, t.pos, 0.1, t.gunrot + 180, 5, true);
+
+ update_tank(&t);
+ update_shots(shots, MAX_SHOTS);
+ }
+
+ CloseWindow();
+}