Hypno - Just a color cycling hypnotic effect using Raylib


package ray_hypno

import rl "vendor:raylib"

WIN_W :: 800
WIN_H :: 600
CX :: WIN_W/2
CY :: WIN_H/2
START_RAD :: f32(WIN_W*3.1415992)
STP :: f32(8.5)

randcolor :: proc() -> rl.Color{
    return rl.Color{
        u8(rl.GetRandomValue(0,255)), 
        u8(rl.GetRandomValue(0,255)), 
        u8(rl.GetRandomValue(0,255)),
        255
    }
}

main :: proc(){
    using rl
    InitWindow(WIN_W,WIN_H,"Raylib hypno")
    SetTargetFPS(60)
    ToggleFullscreen()

    // define array for colors
    cols:[dynamic]rl.Color
    defer delete(cols)

    // add color set  to array
    sz:=START_RAD
    for{
        append(&cols,BLACK)
        sz-=STP
        if sz<=6 do break
    }

    // Preparation
    current_col:=BLACK
    target_col:=randcolor()
    lerpfac:f32=0.0

    // main loop
    for !WindowShouldClose(){

        // cycle colors
        if lerpfac<1.0{lerpfac+=0.03}
        current_col=ColorLerp(current_col,target_col,lerpfac)
        ordered_remove(&cols,0)
        append(&cols,current_col)
        if GetRandomValue(1,1000)>850{
            target_col=randcolor()
            lerpfac=0
        }
        radx:f32=START_RAD
        yratio:f32=WIN_W/WIN_H

        // draw
        BeginDrawing()
        ClearBackground(BLACK)
        for c in cols{
            DrawEllipse(CX,CY,radx,radx/yratio,c)
            radx-=STP
        }
        EndDrawing()
    }

    // Done
    CloseWindow()
}
1 Like

Since helping with the previous example, I’ve been hooked on playing around with Raylib and Odin. I blame you :wink: These two packages go together like :pie: and :ice_cream:

Thought I’d share something I’ve been doing. If you want to display at your native screen resolution without all your background windows changing size, try the following. Just ESC to exit the display.

package ray_hypno

import rl "vendor:raylib"

STP :: f32(8.5)

randcolor :: proc() -> rl.Color{
    return rl.Color{
        u8(rl.GetRandomValue(0,255)), 
        u8(rl.GetRandomValue(0,255)), 
        u8(rl.GetRandomValue(0,255)),
        255
    }
}

WindowConfig := rl.ConfigFlags{ .FULLSCREEN_MODE }

main :: proc(){
  using rl
  SetConfigFlags(WindowConfig)
  InitWindow(0,0,"Raylib hypno")
  render_size: [2]i32 = {GetRenderWidth(), GetRenderHeight()}

  WIN_W := render_size.x
  WIN_H := render_size.y
  CX := WIN_W/2
  CY := WIN_H/2
  START_RAD := f32(WIN_W)*3.1415992
  
  SetTargetFPS(60)
  //ToggleFullscreen()

  // define array for colors
  cols:[dynamic]rl.Color
  defer delete(cols)

  // add color set  to array
  sz:=START_RAD
  for{
      append(&cols,BLACK)
      sz-=STP
      if sz<=6 do break
  }

  // Preparation
  current_col:=BLACK
  target_col:=randcolor()
  lerpfac:f32=0.0

  // main loop
  for !WindowShouldClose(){

      // cycle colors
      if lerpfac<1.0{lerpfac+=0.03}
      current_col=ColorLerp(current_col,target_col,lerpfac)
      ordered_remove(&cols,0)
      append(&cols,current_col)
      if GetRandomValue(1,1000)>850{
          target_col=randcolor()
          lerpfac=0
      }
      radx:f32=START_RAD
      yratio:=f32(WIN_W)/f32(WIN_H)

      // draw
      BeginDrawing()
      ClearBackground(BLACK)
      for c in cols{
          DrawCircle(CX,CY,radx/yratio,c)
          radx-=STP
      }
      EndDrawing()
  }

  // Done
  CloseWindow()
}

Very nice! I also think Odin and Raylib are a great combination.
For now I am slowly getting the hang of Raylib, and putting together simple starter templates. Based of your idea I now have a full screen starter template:

package ray_fullscreen

import rl "vendor:raylib"

main :: proc(){
    using rl
    SetConfigFlags(ConfigFlags{.FULLSCREEN_MODE})
    InitWindow(0,0,"Raylib full screen")
    SW,SH :i32 = GetRenderWidth(),GetRenderHeight()

    SetTargetFPS(10)

    // main loop
    for !WindowShouldClose(){
        BeginDrawing()
        ClearBackground(BLUE)
        DrawText(TextFormat("Screen size %ix%i",SW,SH),10,10,40,YELLOW)
        EndDrawing()
    }
    
    // Cleanup
    CloseWindow()
}
1 Like

Nice. For what games usually refer to as “Windowed Fullscreen” which doesn’t change your display’s graphics mode, you can do another template called, say “ray_windowed_fullscreen”

SetConfigFlags(ConfigFlags{.WINDOW_UNDECORATED, .BORDERLESS_WINDOWED_MODE, .WINDOW_TOPMOST, .WINDOW_MAXIMIZED})
1 Like

fyi, I found that using .WINDOW_TOPMOST prevents from ALT-TABing out of the window. This can be a problem if your program has issues and you need to end task. My mistake on the first recomendation. I’d change it to the follow instead.

SetConfigFlags(ConfigFlags{.WINDOW_UNDECORATED, .BORDERLESS_WINDOWED_MODE, .WINDOW_MAXIMIZED})

Thanks, and its a good catch to be aware of. I have updated my ‘borderless window’ template with a comment regarding the impact of using .WINDOW_TOPMOST