]> git.ayabusa.dev Git - catzattack.git/commitdiff
finished neko
authorayabusa <lebgpub@gmail.com>
Mon, 22 Sep 2025 18:30:32 +0000 (20:30 +0200)
committerayabusa <lebgpub@gmail.com>
Mon, 22 Sep 2025 18:30:32 +0000 (20:30 +0200)
.vscode/settings.json
build.sh
res/main
res/oneko.gif [new file with mode: 0644]
res/real_oneko.gif [new file with mode: 0644]
src/main.c
src/neko.c

index 5d84152950f0f62db703f70e7f1051e30bb9ca59..dfb5941cb5f9b3849290c80833c2cca2db0d52ee 100644 (file)
@@ -7,6 +7,7 @@
         "array": "c",
         "string": "c",
         "string_view": "c",
-        "shape.h": "c"
+        "shape.h": "c",
+        "xfixes.h": "c"
     }
 }
\ No newline at end of file
index ee0dd38d90b0bf116896f188ab4d6ac7ca8c5e04..06d556293f29f4911b6c03fc4034c6baf228802a 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -5,4 +5,5 @@ echo gcc src/main.c -o res/main $(pkg-config --cflags --libs sdl3 x11 xfixes sdl
 gcc src/main.c src/neko.c -I src/ -o res/main $(pkg-config --cflags --libs sdl3 x11 xfixes sdl3-image) -lm
 
 echo Running...
-DISPLAY=:1 ./res/main
+#DISPLAY=:1 ./res/main
+./res/main
index 059b97b768f4dba4600c74caa795342516fb702e..141aa85699d80e47b4ec486eeb3c3a9b26f5bb14 100755 (executable)
Binary files a/res/main and b/res/main differ
diff --git a/res/oneko.gif b/res/oneko.gif
new file mode 100644 (file)
index 0000000..a009c2c
Binary files /dev/null and b/res/oneko.gif differ
diff --git a/res/real_oneko.gif b/res/real_oneko.gif
new file mode 100644 (file)
index 0000000..8f17625
Binary files /dev/null and b/res/real_oneko.gif differ
index faeaeeb12880b662e1b81c1fabe680237d76159a..a64bf3e01fc0e194df71b926ef4bb4c205a2a74b 100644 (file)
@@ -97,6 +97,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 
     make_window_clickthrough();
     set_override_redirect();
+    SDL_SetDefaultTextureScaleMode(renderer, SDL_SCALEMODE_PIXELART);
 
     neko_init(renderer, window);
 
index 0f40fb7f7fd6e0735006915047322170ad63e406..67211df06d906cc59c4e20f8b1d7d98e7b3db8a5 100644 (file)
@@ -2,7 +2,6 @@
 #include "common.h"
 #include <math.h>
 
-static SDL_Texture *texture = NULL;
 static int texture_width = 0;
 static int texture_height = 0;
 
@@ -12,19 +11,40 @@ static float speed = 5.0;
 
 #define TIME_BEFORE_SPLEEP 3000
 #define TIME_BEFORE_RUNNING 1000
+#define TIME_ANIM_INTERVAL 300
 
 enum CatState {
-    SLEEPING,
-    RUNNING,
-    WAKING_UP,
-    STAND_BY,
-} cat_state = RUNNING;
+    ST_SLEEPING,
+    ST_RUNNING,
+    ST_WAKING_UP,
+    ST_STAND_BY,
+} cat_state = ST_RUNNING;
+
+enum CatFrames {
+    STAND_BY=0,
+    WAKING_UP=1,
+    UP=2,
+    DOWN=4,
+    LEFT=6,
+    RIGHT=8,
+    UP_LEFT=10,
+    UP_RIGHT=12,
+    DOWN_RIGHT=14,
+    DOWN_LEFT=16,
+    SLEEPING=18,
+};
 
 static int state_timer;
+static int anim_timer = 0;
+static int current_frame = 0; 
+
+static float diffx, diffy;
+
+static IMG_Animation *anim;
+static SDL_Texture **anim_textures;
 
 int neko_init(SDL_Renderer *renderer, SDL_Window *window){
-    SDL_Surface *surface = NULL;
-    char *neko_bmp_path = NULL;
+    char *neko_gif_path = NULL;
     
     /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
        engines refer to these as "sprites." We'll do a static texture (upload once, draw many
@@ -32,25 +52,26 @@ int neko_init(SDL_Renderer *renderer, SDL_Window *window){
 
     /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
        Load a .bmp into a surface, move it to a texture from there. */
-    SDL_asprintf(&neko_bmp_path, "%ssample.bmp", SDL_GetBasePath());  /* allocate a string of the full file path */
-    surface = SDL_LoadBMP(neko_bmp_path);
-    if (!surface) {
-        SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
+    SDL_asprintf(&neko_gif_path, "%sreal_oneko.gif", SDL_GetBasePath());
+    anim = IMG_LoadAnimation(neko_gif_path);
+    if (!anim) {
+        SDL_Log("Couldn't load %s: %s\n", neko_gif_path, SDL_GetError());
         return SDL_APP_FAILURE;
     }
+    SDL_free(neko_gif_path);  /* done with this, the file is loaded. */
 
-    SDL_free(neko_bmp_path);  /* done with this, the file is loaded. */
-
-    texture_width = surface->w;
-    texture_height = surface->h;
+    texture_width = anim->w;
+    texture_height = anim->h;
 
-    texture = SDL_CreateTextureFromSurface(renderer, surface);
-    if (!texture) {
-        SDL_Log("Couldn't create static texture: %s", SDL_GetError());
+    anim_textures = (SDL_Texture **)SDL_calloc(anim->count, sizeof(*anim_textures));
+    if (!anim_textures) {
+        SDL_Log("Couldn't allocate textures\n");
+        IMG_FreeAnimation(anim);
         return SDL_APP_FAILURE;
     }
-
-    SDL_DestroySurface(surface);  /* done with this, the texture has a copy of the pixels now. */
+    for (int i = 0; i < anim->count; ++i) {
+        anim_textures[i] = SDL_CreateTextureFromSurface(renderer, anim->frames[i]);
+    }
 
     SDL_AddTimer(50, move_cat, window);
 }
@@ -60,18 +81,74 @@ void neko_render(SDL_Renderer *renderer, SDL_Window *window){
 
     dst_rect.x = catx;
     dst_rect.y = caty;
-    dst_rect.h = WINDOW_HEIGHT/10;
-    dst_rect.w = WINDOW_HEIGHT/10;
-    SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
+    dst_rect.h = WINDOW_HEIGHT/15;
+    dst_rect.w = WINDOW_HEIGHT/15;
+
+    int texture_index = 0;
+    switch (cat_state)
+    {
+    case ST_SLEEPING:
+        texture_index = SLEEPING+current_frame;
+        break;
+    case ST_WAKING_UP:
+        texture_index = WAKING_UP;
+        break;
+    case ST_STAND_BY:
+        texture_index = STAND_BY;
+        break;
+    case ST_RUNNING:
+        // We do this to know if our cat is moving in diagonals
+        double angle = fabs(atan((double) (diffy/diffx)));
+        if(angle<SDL_PI_D/3 && angle>SDL_PI_D/6){ // Diagonals
+            if(diffy<0){
+                if(diffx<0){
+                    texture_index = DOWN_RIGHT+current_frame;
+                }else{
+                    texture_index = DOWN_LEFT+current_frame;
+                }
+            }else{
+                if(diffx<0){
+                    texture_index = UP_RIGHT+current_frame;
+                }else{
+                    texture_index = UP_LEFT+current_frame;
+                }
+            }
+        }else{ // pas diagonals
+            if(fabs(diffy) > fabs(diffx)){
+                if(diffy<0){
+                    texture_index = DOWN+current_frame;
+                }else{
+                    texture_index = UP+current_frame;
+                }
+            }else{
+                if(diffx<0){
+                    texture_index = RIGHT+current_frame;
+                }else{
+                    texture_index = LEFT+current_frame;
+                }
+            }
+        }
+        break;
+    
+    default:
+        break;
+    }
+
+    SDL_RenderTexture(renderer, anim_textures[texture_index], NULL, &dst_rect);
+
+    if(SDL_GetTicks()-anim_timer > TIME_ANIM_INTERVAL){
+        current_frame = (current_frame+1) % 2;
+        anim_timer=SDL_GetTicks();
+    }
 }
 
 void neko_quit(){
-    SDL_DestroyTexture(texture);
+    SDL_DestroyTexture(anim_textures[current_frame]);
 }
 
 Uint32 move_cat(void *window, SDL_TimerID timerID, Uint32 interval){
     float mousex, mousey;
-    float diffx, diffy, hypo;
+    float hypo;
     int windowx, windowy;
 
     SDL_GetGlobalMouseState(&mousex, &mousey);
@@ -82,31 +159,31 @@ Uint32 move_cat(void *window, SDL_TimerID timerID, Uint32 interval){
     hypo = sqrt(diffx*diffx + diffy*diffy); 
     switch (cat_state)
     {
-    case RUNNING:
+    case ST_RUNNING:
         if (hypo>50){
             catx -= (diffx*speed/hypo);
             caty -= (diffy*speed/hypo);
         }else{
-            cat_state = STAND_BY;
+            cat_state = ST_STAND_BY;
             state_timer = SDL_GetTicks();
         }
         break;
-    case STAND_BY:
+    case ST_STAND_BY:
         if (hypo>50){
-            cat_state = RUNNING;
+            cat_state = ST_RUNNING;
         }else if (SDL_GetTicks()-TIME_BEFORE_SPLEEP > state_timer){
-            cat_state = SLEEPING;
+            cat_state = ST_SLEEPING;
         }
         break;
-    case SLEEPING:
+    case ST_SLEEPING:
         if (hypo>50){
-            cat_state = WAKING_UP;
+            cat_state = ST_WAKING_UP;
             state_timer = SDL_GetTicks();
         }
         break;
-    case WAKING_UP:
+    case ST_WAKING_UP:
         if (SDL_GetTicks()-TIME_BEFORE_RUNNING > state_timer){
-            cat_state = RUNNING;
+            cat_state = ST_RUNNING;
         }
         break;