Skip to main content
This example demonstrates how to create a window with multiple screens and manage transitions between them. It’s perfect for understanding the fundamentals of game state management in Talon.

Overview

The basic window example shows:
  • Window initialization and configuration
  • Screen state management
  • Drawing text and shapes
  • Handling keyboard input
  • Game loop structure

Complete Code

import "raylib" for Color, Raylib, Rectangle, Vector2, Camera2D, KeyCode, Texture2D
import "builtin" for Build

// Automatic reloads are very crucial for ui buildings
// Here is talon running in hot reload mode

var title = "Title Screen Changed 2"
var color = Color.Yellow

class GameScreen {
  static Logo { 0 }
  static Title { 1 }
  static GamePlay { 2 }
  static Ending { 3 }
}

var screenWidth = 1000 
var screenHeight = 1000

Raylib.initWindow(screenWidth, screenHeight, "raylib [core] example - basic screen manager")

var currentScreen = GameScreen.Logo

var framesCounter = 0

Raylib.setTargetFPS(60)

while (!Raylib.windowShouldClose() && !Build.shouldStop()) {
  if (currentScreen == GameScreen.Logo) {
    framesCounter = framesCounter + 1
   // if (framesCounter > 120) {
   //   currentScreen = GameScreen.Title
   // }
  }

  if (currentScreen == GameScreen.Title) {
    if (Raylib.isKeyPressed(KeyCode.KEY_ENTER)) {
      currentScreen = GameScreen.GamePlay
    }
  }

  if (currentScreen == GameScreen.GamePlay) {
    if (Raylib.isKeyPressed(KeyCode.KEY_ENTER)) {
      currentScreen = GameScreen.Ending
    }
  }

  Raylib.beginDrawing()

  Raylib.clearBackground(Color.RayWhite)

  if (currentScreen == GameScreen.Logo) {
    Raylib.drawText(title, 20, 20, 60, color)
    Raylib.drawText("Wait for 3 seconds...", 290, 220, 20, Color.Gray)
  }

  if (currentScreen == GameScreen.Title) {
    Raylib.drawRectangle(0, 0, screenWidth, screenHeight, Color.Green)
    Raylib.drawText("TITLE SCREEN 4", 20, 20, 40, Color.Blue)
    Raylib.drawText("PRESS ENTER or TAP to JUMP to GAMEPLAY SCREEN", 120, 220, 20, Color.DarkGreen)
  }

  if (currentScreen == GameScreen.GamePlay) {
    Raylib.drawText("GAMEPLAY SCREEN", 20, 20, 40, Color.Purple)
    Raylib.drawText("PRESS ENTER or TAP to JUMP to ENDING SCREEN", 130, 220, 20, Color.Maroon)
  }

  if (currentScreen == GameScreen.Ending) {
    Raylib.drawText("GAMEPLAY SCREEN", 20, 20, 40, Color.DarkBlue)
    Raylib.drawText("PRESS ENTER or TAP to RETURN to TITLE SCREEN", 130, 220, 20, Color.Maroon)
  }

  Raylib.endDrawing()
}

Raylib.closeWindow()

Code Walkthrough

1. Screen State Management

class GameScreen {
  static Logo { 0 }
  static Title { 1 }
  static GamePlay { 2 }
  static Ending { 3 }
}
Define an enumeration-style class to represent different game screens. This pattern makes it easy to manage multiple states in your game.

2. Window Initialization

var screenWidth = 1000 
var screenHeight = 1000

Raylib.initWindow(screenWidth, screenHeight, "raylib [core] example - basic screen manager")
Raylib.setTargetFPS(60)
Initialize the game window with specified dimensions and set the target frame rate to 60 FPS for smooth rendering.

3. Game Loop with Hot Reload

while (!Raylib.windowShouldClose() && !Build.shouldStop()) {
  // Game logic and rendering
}
The main game loop continues until the window is closed or hot reload triggers a stop. The Build.shouldStop() check enables Talon’s hot reload feature.

4. State Transitions

if (currentScreen == GameScreen.Title) {
  if (Raylib.isKeyPressed(KeyCode.KEY_ENTER)) {
    currentScreen = GameScreen.GamePlay
  }
}
Handle user input to transition between screens. Each screen can respond to different inputs to move to the next state.

5. Rendering Different Screens

Raylib.beginDrawing()
Raylib.clearBackground(Color.RayWhite)

if (currentScreen == GameScreen.Logo) {
  Raylib.drawText(title, 20, 20, 60, color)
  Raylib.drawText("Wait for 3 seconds...", 290, 220, 20, Color.Gray)
}

Raylib.endDrawing()
Each frame, clear the background and draw content based on the current screen state. All drawing must happen between beginDrawing() and endDrawing() calls.

Key Concepts

  • State Management: Use a simple state variable to control which screen is displayed
  • Hot Reload: The Build.shouldStop() check allows code changes to be applied without restarting
  • Frame Counter: Track elapsed frames for timing events (like auto-advancing screens)
  • Input Handling: Use isKeyPressed() for one-time key press detection
  • Render Loop: Always wrap drawing code in beginDrawing()/endDrawing() blocks

Try It Yourself

  1. Auto-advance the logo screen: Uncomment lines 31-33 to automatically transition after 2 seconds
  2. Add more screens: Extend the GameScreen class and add new states
  3. Customize colors: Change the background colors for each screen
  4. Add animations: Use the framesCounter to create animated effects

Build docs developers (and LLMs) love