Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
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
Posts: 721
Threads: 76
Joined: Nov 2023
Reputation:
7
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
Logic is the beginning of wisdom.
Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
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
Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
Oh wow, it was that the code was converting it to Unix format instead of Windows XD!
Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
Good morning, what type of font does naalaa use? It is very sharp/clean. I try to imitate it but I can't.
Posts: 665
Threads: 83
Joined: Nov 2023
Reputation:
7
(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.
Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
02-20-2026, 07:12 PM
(This post was last modified: 02-20-2026, 08:09 PM by oskarg.)
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
Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
How do I avoid those small jumps that occur visually? What causes them?
Posts: 721
Threads: 76
Joined: Nov 2023
Reputation:
7
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
Logic is the beginning of wisdom.
Posts: 19
Threads: 2
Joined: Dec 2023
Reputation:
0
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.
|