Crea un juego completo usando .NET Blazor y publícalo

Introducción

Soy desarrollador e instructor técnico con amplia experiencia en frontend y backend (React, .NET, WordPress) y en 2025 sigo viendo a Blazor como una opción muy atractiva para crear juegos ligeros directamente en C# y publicarlos como webapps. En esta guía te mostraré cómo crear un juego 2D simple (canvas-based) usando Blazor WebAssembly, optimizarlo para producción y desplegarlo a hosting estático (Azure Static Web Apps / GitHub Pages). Todo el contenido está actualizado al ecosistema .NET/Blazor de 2025 y contiene código real, buenas prácticas y solución de errores comunes. Microsoft Learn+1

¿Qué es Blazor (y por qué usarlo para juegos)?

Blazor es el framework de Microsoft para construir UIs interactivas usando C# y Razor, con soporte para ejecutarse en el navegador vía WebAssembly (Blazor WebAssembly) o desde servidor (Blazor Server). Para juegos sencillos o prototipos 2D, Blazor permite mantener toda la lógica en C# y aprovechar canvas o interop JS para renderizar gráficos. Microsoft+1

¿Por qué es importante en 2025?

  • Ecosistema maduro: .NET y Blazor han recibido mejoras de rendimiento y herramientas AOT que hacen WebAssembly más viable. Microsoft Learn
  • Productividad C#: Si vienes del mundo .NET, puedes mantener todo el stack en C# (lógica, UI, networking).
  • Despliegue sencillo: Blazor WASM puede publicarse como sitio estático en Azure Static Web Apps, GitHub Pages, S3, etc. Microsoft Learn+1

Qué vamos a construir (resumen del juego)

Un juego 2D tipo “evita obstáculos” con:

  • Lógica de juego en C# (componentes Blazor).
  • Render con <canvas> vía JS interop o Blazor.Extensions.Canvas.
  • Game loop usando requestAnimationFrame.
  • Controles por teclado/táctiles.
  • Publicación como app estática (Azure Static Web Apps / GitHub Pages).

Recuerda: este ejemplo es didáctico; para juegos complejos (3D, física intensiva) sigue siendo mejor un motor nativo (Unity, Unreal), pero Blazor brilla en prototipos, minijuegos y juegos integrados en webs. mstack+1

Requisitos previos

  • .NET SDK (net9.0 o superior recomendado).
  • Visual Studio 2022/2023 o VS Code con C# Dev Kit.
  • Node/npm (opcional, para algunas herramientas de deploy).
  • Conocimientos básicos de C#, Razor y HTML5 canvas.

Oficial: guía de inicio y docs de Blazor en la web de Microsoft. Microsoft+1

Paso a paso para implementarlo (con código real y comentado)

1. Crear el proyecto Blazor WASM (standalone)

dotnet new blazorwasm -o BlazorGame --no-https
cd BlazorGame

Usamos la plantilla Blazor WebAssembly Standalone: genera una app cliente que se puede publicar como sitio estático. Stack Overflow+1

2. Estructura de archivos (sugerida)

BlazorGame/
  wwwroot/
  Pages/
    Game.razor
  Shared/
  Program.cs

3. Componente Game.razor (UI + canvas)

@page "/game"
@implements IDisposable

<canvas id="gameCanvas" width="800" height="450" @ref="canvasRef" tabindex="0"></canvas>

@code {
    private ElementReference canvasRef;
    private DotNetObjectReference<Game>? objRef;
    private bool running = false;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);
            // Llama a JS para iniciar requestAnimationFrame y pasar el callback a C#
            await JS.InvokeVoidAsync("gameInterop.startLoop", canvasRef, objRef);
            running = true;
        }
    }

    [JSInvokable]
    public async Task FrameUpdate(double timestamp)
    {
        // Aquí actualizas lógica del juego (posiciones, colisiones)
        // y pides dibujar (puedes usar JS para dibujar o Blazor.Extensions.Canvas)
        await JS.InvokeVoidAsync("gameInterop.drawFrame", timestamp);
    }

    public void Dispose()
    {
        if (running) JS.InvokeVoidAsync("gameInterop.stopLoop");
        objRef?.Dispose();
    }
}

4.JavaScript interop (wwwroot/js/gameInterop.js)

// gameInterop.js
export function startLoop(canvas, dotnetRef) {
  let running = true;
  function loop(ts) {
    if (!running) return;
    // Llama al método C# FrameUpdate (puede ser asíncrono)
    dotnetRef.invokeMethodAsync('FrameUpdate', ts);
    requestAnimationFrame(loop);
  }
  requestAnimationFrame(loop);
  window._gameRunning = () => running = false;
}

export function drawFrame(ts) {
  const canvas = document.getElementById('gameCanvas');
  const ctx = canvas.getContext('2d');
  // Simple ejemplo: limpiar y dibujar un rectángulo que se mueve según timestamp
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  const x = (ts / 10) % canvas.width;
  ctx.fillStyle = '#0af';
  ctx.fillRect(x, canvas.height / 2 - 20, 40, 40);
}

export function stopLoop() {
  if (window._gameRunning) window._gameRunning();
}

En index.html registra el script y el módulo (o usa import desde Blazor). La lógica de juego se puede mantener en C# y ceder el dibujo a JS por rendimiento.

Comentarios:

  • Usar requestAnimationFrame para el game loop es la forma recomendada en browsers; muchas implementaciones Blazor usan este patrón para juegos 2D. mstack
  • Para dibujar desde C# hay bibliotecas como Blazor.Extensions.Canvas si prefieres una API C# directa (evita interop en cada frame). mstack

Buenas prácticas

  1. Minimiza el trabajo en C# por frame: la interop frecuente puede costar; delega dibujo pesado a JS o usa AOT. Microsoft Learn
  2. Usa AOT y publicación en Release para mejorar tiempo de arranque y rendimiento (especialmente en WASM). Microsoft Learn
  3. Optimiza assets (sprites en atlas, comprimir imágenes, usar WebP).
  4. Prueba en móviles y controla tasa de frames para ahorrar batería.
  5. Cache y PWA: considera convertirlo en PWA para jugar offline (manifest + service worker).

Errores comunes y cómo evitarlos

  • Lentitud por interop excesivo: evitar llamar C# ↔ JS en cada frame; agrupa llamadas o dibuja desde JS.
  • Tamaño de descarga grande: usar trimming y AOT selectivo (o lazy-load) para reducir payload WASM. Microsoft Learn
  • Problemas de publicación a hosting estático: asegúrate de copiar wwwroot y las rutas fallback (SPA) en el host; sigue la guía oficial. Microsoft Learn
  • iOS quirks: algunas versiones antiguas de iOS tienen limitaciones con WASM — prueba en dispositivos reales. (Recomendación práctica basada en la experiencia de la comunidad). Community | MonoGame

Publicación (deploy) — pasos rápidos

  1. dotnet publish -c Release -r browser-wasm (o el comando recomendado para tu versión). Luego copia el contenido wwwroot/publish al host. Microsoft Learn
  2. Azure Static Web Apps: crea un repo en GitHub y configura la integración — Microsoft tiene tutorial paso a paso para Blazor. (ideal para API serverless con Azure Functions si tu juego necesita backend). Microsoft Learn+1
  3. GitHub Pages / S3 / CloudFront: copia los archivos estáticos y configura fallback a index.html. Microsoft Learn+1

Consejo práctico: crea un pipeline CI que haga dotnet publish y publique el contenido publish/wwwroot al host elegido.

Ejemplos reales basados en experiencia práctica

  • Implementé un minijuego promocional para una web de cursos: usé Blazor WASM + JS interop para el render y Azure Static Web Apps para deploy. Resultado: integración rápida con APIs .NET y despliegue automático desde GitHub Actions (latencia de arranque reducida con AOT en Release). (Experiencia propia, resumen práctico). Microsoft Learn
  • Reutilicé patrones de requestAnimationFrame en varias demos (Connect-4, memoria, minijuegos) que se encuentran como ejemplos y tutoriales en la comunidad Blazor. YouTube+1

FAQs

P: ¿Blazor es adecuado para juegos 2D simples?
R: Sí — para prototipos y minijuegos es una buena opción. Para juegos con gráficos intensivos/3D usa motores especializados. mstack

P: ¿Cómo mejoro el rendimiento de mi juego Blazor WASM?
R: Usa dotnet publish en Release con AOT, reduce interop por frame y usa sprites/atlases optimizados. Microsoft Learn

P: ¿Dónde puedo alojar mi juego?
R: Azure Static Web Apps, GitHub Pages, S3 + CloudFront y proveedores similares funcionan muy bien. Microsoft Learn+1

P: ¿Hay frameworks para juegos en Blazor?
R: No hay un “Unity en Blazor”, pero hay recursos y proyectos que muestran cómo usar canvas, MonoGame (portados) o librerías JS desde Blazor. Explora repositorios de la comunidad y BlazorGames. blazorgames.net+1

Recursos oficiales y lecturas recomendadas

Te puede interesar...

Deja un comentario