NaaLaa

Full Version: Questions about Naala in general
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I'm opening this post to start asking things about Naalaa, because the sprite in this example flickers—how can I prevent it?
Code:
'INITIALIZATION
set window "Dino Simplified",640,480
load image 1,"data_dino/ground.png" 'length = 2400 px
load image 2,"data_dino/ground.png"
load image 3,"data_dino/dino1.png"

speed = 10
ground1X = 0    ; ground1Y = 400
ground2X = 2400 ; ground2Y = 400
dinoX    = 40   ; dinoY    = 330

'MAIN PROGRAM
do
   'ESC TO QUIT
    if keydown(KEY_ESCAPE) then end

   'MOVING BACKGROUND
    cls
    draw image 1,ground1X,ground1Y
    draw image 2,ground2X,ground2Y
               
    if ground1X = -2400 then
        ground1X = 0
        ground2X = 2400
    else
        ground1X = ground1X - speed
        ground2X = ground2X - speed       
    endif

    'DINO
    draw image 3,dinoX,dinoY
   
    'WAIT BEFORE LOOPING
    wait 60
loop
Ok. First...

After the window has been setup, add the next line 'set redraw off' (without the quotes)

set window "Dino Simplified",640,480
set redraw off

Second. 'WAIT BEFORE LOOPING
Instead of wait 60 use...

redraw
fwait 60

I hope this helps...

J
because when I compile in cmd with n7 game.n7 in this code it gives me this error? n7: game.n7:17: error: Expected ':' but in the naalaa editor it compiles fine
Code:
' Snowflakes
' ----------

include "list.n7"

#win32

constant BG_R = 16, BG_G = 24, BG_B = 64

set window "Snowflakes", 480*screenw()/screenh(), 480, true
set redraw off

snowflakeImage = loadimage("snowflake.png")

stars = List()
for i = 1 to 200
    stars.Add([x: rnd()*2 - 1, y: rnd()*2 - 1, z: 0.1 + rnd()*0.9])
next
Oh wow, it was that the code was converting it to Unix format instead of Windows XD!
Good morning, what type of font does naalaa use? It is very sharp/clean. I try to imitate it but I can't.
(02-18-2026, 03:08 PM)oskarg Wrote: [ -> ]Good morning, what type of font does naalaa use? It is very sharp/clean. I try to imitate it but I can't.

The default font is built into the source code. It's a bitmap font created using some font editor that I once wrote.
Hello, can someone translate this code to Naalaa so I can have it as a base template? Thanks in advance. 
Code:
-------------------------------------------------
-- CONSTANTES DE ESTADO
-------------------------------------------------
local STATE_MENU = 1
local STATE_PLAYING = 2
local STATE_GAMEOVER = 3

-------------------------------------------------
-- VARIABLES GLOBALES DEL JUEGO
-------------------------------------------------
local gameState = STATE_MENU
local width, height
local stars = {}
local defaultFont, titleFont

-- Variables del jugador
local player = {
    x = 0, y = 0,
    width = 50, height = 30,
    speed = 300,
    shootCooldown = 0,
    lives = 2,
    invincibleTime = 0
}

-- Variables de juego
local bullets = {}
local enemies = {}
local score = 0
local level = 1
local enemiesDestroyed = 0
local enemySpeedBase = 100
local enemySpawnRate = 1.0
local enemySpawnTimer = 0

-------------------------------------------------
-- LOVE CALLBACKS
-------------------------------------------------
function love.load()
    width = love.graphics.getWidth()
    height = love.graphics.getHeight()

    loadFonts()
    createStars()
end

function love.update(dt)
    updateStars(dt)

    if gameState == STATE_PLAYING then
        updateGame(dt)
    end
end

function love.draw()
    drawStars()

    if gameState == STATE_MENU then
        drawMenu()
    elseif gameState == STATE_PLAYING then
        drawGame()
    elseif gameState == STATE_GAMEOVER then
        drawGameOver()
    end
end

function love.keypressed(key)
    if key == "return" or key == "kpenter" then
        if gameState == STATE_MENU then
            startGame()
        elseif gameState == STATE_GAMEOVER then
            gameState = STATE_MENU
        end
    end
end

-------------------------------------------------
-- FUNCIONES DE INICIALIZACIÓN
-------------------------------------------------
function loadFonts()
    defaultFont = love.graphics.newFont(14)
    titleFont = love.graphics.newFont(24)
    love.graphics.setFont(defaultFont)
end

function createStars()
    stars = {}
    for i = 1, 100 do
        table.insert(stars, {
                x = math.random(0, width),
                y = math.random(0, height),
                speed = math.random(50, 150),
                size = math.random(1, 3)
            })
    end
end

function startGame()
    -- Reiniciar jugador
    player.x = width / 2 - 25
    player.y = height - 60
    player.width = 50
    player.height = 30
    player.speed = 300
    player.shootCooldown = 0
    player.lives = 2
    player.invincibleTime = 0

    -- Reiniciar listas
    bullets = {}
    enemies = {}

    -- Reiniciar puntuación y nivel
    score = 0
    level = 1
    enemiesDestroyed = 0

    -- Reiniciar spawn
    enemySpeedBase = 100
    enemySpawnRate = 1.0
    enemySpawnTimer = 0

    gameState = STATE_PLAYING
end

-------------------------------------------------
-- FUNCIONES DE UPDATE
-------------------------------------------------
function updateGame(dt)
    updatePlayer(dt)
    updateBullets(dt)
    updateEnemies(dt)
    handleSpawning(dt)
end

function updateStars(dt)
    for _, star in ipairs(stars) do
        star.y = star.y + star.speed * dt
        if star.y > height then
            star.y = 0
            star.x = math.random(0, width)
        end
    end
end

function updatePlayer(dt)
    -- Movimiento
    if love.keyboard.isDown("left", "a") then
        player.x = player.x - player.speed * dt
    end
    if love.keyboard.isDown("right", "d") then
        player.x = player.x + player.speed * dt
    end

    -- Limitar al área de juego
    player.x = math.max(0, math.min(width - player.width, player.x))

    -- Cooldown de disparo
    if player.shootCooldown > 0 then
        player.shootCooldown = player.shootCooldown - dt
    end

    -- Tiempo de invencibilidad
    if player.invincibleTime > 0 then
        player.invincibleTime = player.invincibleTime - dt
    end

    -- Disparar
    if love.keyboard.isDown("space") and player.shootCooldown <= 0 then
        table.insert(bullets, {
                x = player.x + player.width/2 - 2.5,
                y = player.y,
                width = 5,
                height = 10,
                speed = 500
            })
        player.shootCooldown = 0.25
    end
end

function updateBullets(dt)
    for i = #bullets, 1, -1 do
        local b = bullets[i]
        b.y = b.y - b.speed * dt

        if b.y < -10 then
            table.remove(bullets, i)
        end
    end
end

function updateEnemies(dt)
    local currentSpeed = enemySpeedBase + (level * 25)

    for i = #enemies, 1, -1 do
        local e = enemies[i]
        e.y = e.y + currentSpeed * dt

        local hit = false

        -- Colisión bala vs enemigo
        for j = #bullets, 1, -1 do
            if checkCollision(bullets[j], e) then
                table.remove(bullets, j)
                hit = true
                score = score + 10
                enemiesDestroyed = enemiesDestroyed + 1

                if enemiesDestroyed % 10 == 0 then
                    level = level + 1
                end
                break
            end
        end

        if hit then
            table.remove(enemies, i)

        elseif player.invincibleTime <= 0 and checkCollision(e, player) then
            table.remove(enemies, i)
            player.lives = player.lives - 1
            player.invincibleTime = 2

            if player.lives <= 0 then
                gameState = STATE_GAMEOVER
            end

        elseif e.y > height then
            table.remove(enemies, i)
        end
    end
end

function handleSpawning(dt)
    enemySpawnTimer = enemySpawnTimer - dt

    if enemySpawnTimer <= 0 then
        spawnEnemy()
        enemySpawnTimer = enemySpawnRate
    end
end

function spawnEnemy()
    local width = 40
    table.insert(enemies, {
            x = math.random(0, width - width),
            y = -50,
            width = width,
            height = 30
        })
end

-------------------------------------------------
-- FUNCIONES DE DIBUJO
-------------------------------------------------
function drawStars()
    love.graphics.setColor(1, 1, 1)
    for _, star in ipairs(stars) do
        love.graphics.circle("fill", star.x, star.y, star.size)
    end
end

function drawMenu()
    love.graphics.setColor(0, 0, 0, 0.5)
    love.graphics.rectangle("fill", 0, 0, width, height)

    love.graphics.setColor(1, 1, 1)
    love.graphics.setFont(titleFont)
    love.graphics.printf("INICIA JUEGO", 0, 200, width, "center")

    love.graphics.setFont(defaultFont)
    love.graphics.printf("Pulsa ENTER", 0, 280, width, "center")
end

function drawGame()
    drawPlayer()
    drawBullets()
    drawEnemies()
    drawUI()
end

function drawPlayer()
    if player.invincibleTime > 0 and math.floor(player.invincibleTime * 10) % 2 ~= 0 then
        return
    end

    love.graphics.setColor(0, 1, 0)
    love.graphics.polygon("fill",
        player.x + player.width / 2, player.y,
        player.x, player.y + player.height,
        player.x + player.width, player.y + player.height)
end

function drawBullets()
    love.graphics.setColor(0, 1, 1)
    for _, b in ipairs(bullets) do
        love.graphics.rectangle("fill", b.x, b.y, b.width, b.height)
    end
end

function drawEnemies()
    love.graphics.setColor(1, 0, 0)
    for _, e in ipairs(enemies) do
        love.graphics.rectangle("fill", e.x, e.y, e.width, e.height)
    end
end

function drawUI()
    love.graphics.setColor(1, 1, 1)
    love.graphics.print("Puntos: " .. score, 10, 10)
    love.graphics.print("Fase: " .. level, 10, 30)
    love.graphics.print("Vidas: " .. player.lives, 10, 50)
end

function drawGameOver()
    love.graphics.setColor(0, 0, 0, 0.7)
    love.graphics.rectangle("fill", 0, 0, width, height)

    love.graphics.setColor(1, 0, 0)
    love.graphics.setFont(titleFont)
    love.graphics.printf("GAME OVER", 0, 200, width, "center")

    love.graphics.setFont(defaultFont)
    love.graphics.setColor(1, 1, 1)
    love.graphics.printf("Puntuación: " .. score, 0, 260, width, "center")
end

-------------------------------------------------
-- FUNCIONES UTILITARIAS
-------------------------------------------------
function checkCollision(a, b)
    return a.x < b.x + b.width and
    a.x + a.width > b.x and
    a.y < b.y + b.height and
    a.y + a.height > b.y
end

Perfect, I already have it XD 
Code:
' -------------------------------------------------
' CONSTANTES DE ESTADO
' -------------------------------------------------
constant STATE_MENU = 1
constant STATE_PLAYING = 2
constant STATE_GAMEOVER = 3

' -------------------------------------------------
' VARIABLES GLOBALES DEL JUEGO (declaradas como visible)
' -------------------------------------------------
visible gameState = STATE_MENU
visible screenWidth = 800
visible screenHeight = 600
visible dt = 0.016          ' Simulando 60 FPS aprox (1/60)

' Variables del jugador
visible player_x = 0
visible player_y = 0
visible player_w = 50.0
visible player_h = 30.0
visible player_speed = 300.0
visible player_shootCooldown = 0.0
visible player_lives = 2
visible player_invincibleTime = 0.0

' Variables de juego
visible score = 0
visible level = 1
visible enemiesDestroyed = 0
visible enemySpeedBase = 100.0
visible enemySpawnRate = 1.0
visible enemySpawnTimer = 0.0

' -------------------------------------------------
' POOLS DE OBJETOS (arrays globales)
' -------------------------------------------------
visible MAX_STARS = 100
visible star_x
visible star_y
visible star_speed
visible star_size

visible MAX_BULLETS = 50
visible bullet_x
visible bullet_y
visible bullet_w = 5.0
visible bullet_h = 10.0
visible bullet_speed = 500.0
visible bullet_active

visible MAX_ENEMIES = 50
visible enemy_x
visible enemy_y
visible enemy_w = 40.0
visible enemy_h = 30.0
visible enemy_active

' Inicialización de arrays (después de declararlos como visible)
star_x = fill(0, MAX_STARS)
star_y = fill(0, MAX_STARS)
star_speed = fill(0, MAX_STARS)
star_size = fill(0, MAX_STARS)

bullet_x = fill(0, MAX_BULLETS)
bullet_y = fill(0, MAX_BULLETS)
bullet_active = fill(0, MAX_BULLETS)

enemy_x = fill(0, MAX_ENEMIES)
enemy_y = fill(0, MAX_ENEMIES)
enemy_active = fill(0, MAX_ENEMIES)

' -------------------------------------------------
' CONFIGURACIÓN INICIAL Y BUCLE PRINCIPAL
' -------------------------------------------------
set window "Space Shooter", screenWidth, screenHeight
set redraw off

createStars()

' Bucle Principal (Game Loop)
do
    ' Calcular físicas / lógica
    updateStars()
   
    if gameState = STATE_MENU then
        if keydown(KEY_RETURN, 1) then
            startGame()
        endif
    elseif gameState = STATE_PLAYING then
        updateGame()
    elseif gameState = STATE_GAMEOVER then
        if keydown(KEY_RETURN, 1) then
            gameState = STATE_MENU
            wait 200          ' Pequeña pausa para no saltar directo al juego
        endif
    endif
   
    ' Dibujado general
    set color 0, 0, 0
    draw rect 0, 0, screenWidth, screenHeight, true        ' Limpiar fondo
   
    drawStars()
   
    if gameState = STATE_MENU then
        drawMenu()
    elseif gameState = STATE_PLAYING then
        drawGame()
    elseif gameState = STATE_GAMEOVER then
        drawGameOver()
    endif
   
    redraw
    fwait 60          ' Pausa para mantener 60 frames por segundo
   
until keydown(KEY_ESCAPE, 1)   ' Salir cuando se presione ESCAPE

' -------------------------------------------------
' FUNCIONES DE INICIALIZACIÓN
' -------------------------------------------------
function createStars()
    for i = 0 to MAX_STARS - 1
        star_x[i] = rnd(0, screenWidth)
        star_y[i] = rnd(0, screenHeight)
        star_speed[i] = rnd(50, 150)
        star_size[i] = rnd(1, 3)
    next
endfunc

function startGame()
    ' Reiniciar jugador
    player_x = screenWidth / 2 - 25
    player_y = screenHeight - 60
    player_lives = 2
    player_shootCooldown = 0.0
    player_invincibleTime = 0.0
   
    ' Reiniciar pools
    for i = 0 to MAX_BULLETS - 1
        bullet_active[i] = 0
    next
    for i = 0 to MAX_ENEMIES - 1
        enemy_active[i] = 0
    next
   
    ' Reiniciar puntuación y nivel
    score = 0
    level = 1
    enemiesDestroyed = 0
    enemySpeedBase = 100.0
    enemySpawnRate = 1.0
    enemySpawnTimer = 0.0
   
    gameState = STATE_PLAYING
endfunc

' -------------------------------------------------
' FUNCIONES DE UPDATE
' -------------------------------------------------
function updateGame()
    updatePlayer()
    updateBullets()
    updateEnemies()
    handleSpawning()
endfunc

function updateStars()
    for i = 0 to MAX_STARS - 1
        star_y[i] = star_y[i] + star_speed[i] * dt
        if star_y[i] > screenHeight then
            star_y[i] = 0
            star_x[i] = rnd(0, screenWidth)
        endif
    next
endfunc

function updatePlayer()
    ' Movimiento - flechas y teclas WASD
    if keydown(KEY_LEFT) or keydown(KEY_A) then
        player_x = player_x - player_speed * dt
    endif
    if keydown(KEY_RIGHT) or keydown(KEY_D) then
        player_x = player_x + player_speed * dt
    endif
   
    ' Limitar al área de juego
    if player_x < 0 then player_x = 0
    if player_x > screenWidth - player_w then player_x = screenWidth - player_w
   
    ' Timers
    if player_shootCooldown > 0.0 then
        player_shootCooldown = player_shootCooldown - dt
    endif
   
    if player_invincibleTime > 0.0 then
        player_invincibleTime = player_invincibleTime - dt
    endif
   
    ' Disparar - barra espaciadora (se mantiene KEY_SPACE para disparar)
    if keydown(KEY_SPACE) and player_shootCooldown <= 0.0 then
        for i = 0 to MAX_BULLETS - 1
            if bullet_active[i] = 0 then
                bullet_x[i] = player_x + player_w / 2 - bullet_w / 2
                bullet_y[i] = player_y
                bullet_active[i] = 1
                player_shootCooldown = 0.25
                break
            endif
        next
    endif
endfunc

function updateBullets()
    for i = 0 to MAX_BULLETS - 1
        if bullet_active[i] = 1 then
            bullet_y[i] = bullet_y[i] - bullet_speed * dt
            if bullet_y[i] < -10.0 then
                bullet_active[i] = 0
            endif
        endif
    next
endfunc

function updateEnemies()
    currentSpeed = enemySpeedBase + (level * 25)
   
    for i = 0 to MAX_ENEMIES - 1
        if enemy_active[i] = 1 then
            enemy_y[i] = enemy_y[i] + currentSpeed * dt
            hit = 0
           
            ' Colisión bala vs enemigo
            for j = 0 to MAX_BULLETS - 1
                if bullet_active[j] = 1 then
                    if checkCollision(bullet_x[j], bullet_y[j], bullet_w, bullet_h, enemy_x[i], enemy_y[i], enemy_w, enemy_h) = 1 then
                        bullet_active[j] = 0
                        hit = 1
                        score = score + 10
                        enemiesDestroyed = enemiesDestroyed + 1
                       
                        if enemiesDestroyed % 10 = 0 then
                            level = level + 1
                        endif
                        break
                    endif
                endif
            next
           
            ' Resolución de colisiones
            if hit = 1 then
                enemy_active[i] = 0
            elseif player_invincibleTime <= 0.0 and checkCollision(enemy_x[i], enemy_y[i], enemy_w, enemy_h, player_x, player_y, player_w, player_h) = 1 then
                enemy_active[i] = 0
                player_lives = player_lives - 1
                player_invincibleTime = 2.0
               
                if player_lives <= 0 then
                    gameState = STATE_GAMEOVER
                endif
            elseif enemy_y[i] > screenHeight then
                enemy_active[i] = 0
            endif
        endif
    next
endfunc

function handleSpawning()
    enemySpawnTimer = enemySpawnTimer - dt
    if enemySpawnTimer <= 0.0 then
        spawnEnemy()
        enemySpawnTimer = enemySpawnRate
    endif
endfunc

function spawnEnemy()
    for i = 0 to MAX_ENEMIES - 1
        if enemy_active[i] = 0 then
            enemy_x[i] = rnd(0, screenWidth - enemy_w)
            enemy_y[i] = -50.0
            enemy_active[i] = 1
            break
        endif
    next
endfunc

' -------------------------------------------------
' FUNCIONES DE DIBUJO
' -------------------------------------------------
function drawStars()
    set color 255, 255, 255
    for i = 0 to MAX_STARS - 1
        ' En Nala se usa draw ellipse para círculos/elipses
        draw ellipse star_x[i], star_y[i], star_size[i], star_size[i], true
    next
endfunc

function drawMenu()
    set color 255, 255, 255
    set caret screenWidth / 2 - 60, 200
    write "INICIA JUEGO"
   
    set caret screenWidth / 2 - 70, 280
    write "Pulsa ENTER"
endfunc

function drawGame()
    drawPlayer()
    drawBullets()
    drawEnemies()
    drawUI()
endfunc

function drawPlayer()
    ' Parpadeo por invencibilidad
    if player_invincibleTime > 0.0 then
        if (int(player_invincibleTime * 10) % 2) <> 0 then
            return
        endif
    endif
   
    set color 0, 255, 0
    ' Dibujar la nave como un rectángulo verde
    draw rect player_x, player_y, player_w, player_h, true
endfunc

function drawBullets()
    set color 0, 255, 255
    for i = 0 to MAX_BULLETS - 1
        if bullet_active[i] = 1 then
            draw rect bullet_x[i], bullet_y[i], bullet_w, bullet_h, true
        endif
    next
endfunc

function drawEnemies()
    set color 255, 0, 0
    for i = 0 to MAX_ENEMIES - 1
        if enemy_active[i] = 1 then
            draw rect enemy_x[i], enemy_y[i], enemy_w, enemy_h, true
        endif
    next
endfunc

function drawUI()
    set color 255, 255, 255
    set caret 10, 10
    write "Puntos: " + str(score)
    set caret 10, 30
    write "Fase: " + str(level)
    set caret 10, 50
    write "Vidas: " + str(player_lives)
endfunc

function drawGameOver()
    set color 255, 0, 0
    set caret screenWidth / 2 - 40, 200
    write "GAME OVER"
   
    set color 255, 255, 255
    set caret screenWidth / 2 - 70, 260
    write "Pulsa ENTER"
   
    set caret screenWidth / 2 - 50, 290
    write "Puntuacion: " + str(score)
endfunc

' -------------------------------------------------
' FUNCIONES UTILITARIAS
' -------------------------------------------------
function checkCollision(ax, ay, aw, ah, bx, by, bw, bh)
    if ax < bx + bw and ax + aw > bx and ay < by + bh and ay + ah > by then
        return 1
    endif
    return 0
endfunc
How do I avoid those small jumps that occur visually? What causes them?
Small jumps? I played the game several times and did not notice any "jumps". Can you describe what you see? Maybe my eyesight is failing... lol

By the way, nicely done!

J
The movement slows down, it's as if it were processing too many elements on the screen. I've never understood why it happens to me, because even if I reduce the stars to 10, the player still slows down, causing FPS spikes.
Pages: 1 2