Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Looking for a space shooter game written old NaaLaa
#1
Hi there! I’m looking for an old NaaLaa (probably v4 or before) game. If I’m not wrong, there was a 2D space shooter written in NaaLaa that I used to play around 2011 or 2010. It was a typical space shooter with bugs/space ships flying around, shooting and all that. I don’t remember whether it came bundled with NaaLaa or if someone shared a link on the old forum.

Sad note: I used to have old versions of NaaLaa and some programs on my old HDD. I tried connecting it to my Linux machine, and idiot me tried to recover the partition… now it’s all gone ?
Don’t Count Your Chickens Before They Hatch
Reply
#2
This one ?

Code:
rem ==================================================================
rem Blastemroids
rem
rem Enemy and player sprites by Ari Feldman, other sprites by Marcus.
rem ==================================================================

visible:
    vNextFrameTime
    vFrameHold

visible:
    rem Enemy data.
    CEL_SIZE = 20
    GRID_WIDTH = 12
    GRID_HEIGHT = 6
    vEnemies[GRID_WIDTH][GRID_HEIGHT][7]
    ENEMY_TYPE = 0
    ENEMY_STATE = 1
    ENEMY_STAMINA = 2
    ENEMY_X = 3
    ENEMY_Y = 4
    ENEMY_BASE_FRAME = 5
    ENEMY_FRAME = 6
    vEnemiesF#[GRID_WIDTH][GRID_HEIGHT][5]
    ENEMY_X1 = 0
    ENEMY_Y1 = 1
    ENEMY_X2 = 2
    ENEMY_Y2 = 3
    ENEMY_PARAM = 4
    vNextAttackTimer
    vEnemyCount
    vGridMotionAngle# = 0.0
    vGridOffsetY

    rem Enemy bullets.
    MAX_ENEMY_BULLETS = 8
    vEnemyBullets[MAX_ENEMY_BULLETS][2]
    BULLET_ACTIVE = 0
    BULLET_FRAME = 1
    vEnemyBulletsF#[MAX_ENEMY_BULLETS][4]
    BULLET_X = 0
    BULLET_Y = 1
    BULLET_DX = 2
    BULLET_DY = 3
    vEnemyBulletCounter
    vEnemyBulletTimer = 400

    rem Player.
    vPlayerX
    vPlayerY
    vPlayerBulletType
    vPlayerBulletX
    vPlayerBulletY
    vPlayerShield
    vScore = 0
    vLevel = 1
    vLives = 3
    vGameOver = false
    vGameOverTimer = 0

    rem Explosions.
    MAX_EXPLOSIONS = 8
    vExplosions[MAX_EXPLOSIONS][4]
    EXP_FRAME = 0
    EXP_FRAME_COUNTER = 1
    EXP_X = 2
    EXP_Y = 3
    vExplosionCounter = 0

    rem Other.
    vScroll = 0
    vCentiCounter = 0

    rem Images.
    BACKGROUND_IMAGE = 0
    PLAYER_IMAGE = 1
    PLAYER_BULLETS_IMAGE = 2
    EXPLOSION_IMAGE = 3
    LOGO_IMAGE = 4
    GAME_OVER_IMAGE = 5
    ENEMY_BULLET_IMAGE = 10
    ENEMY_IMAGE_BASE = 10

    rem Sound.
    EXPLOSION_SOUND = 0
    ENEMY_HIT_SOUND = 1
    BULLET_SOUND = 2

hidden:

rem Init window.
set window 0, 0, 320, 240, true, true
set color 0, 0, 0
cls

rem Load.
proc Load
set redraw off


rem Init.
proc InitPlayer
proc InitEnemies 24 + vLevel*2
proc InitExplosions

play music 0

rem ==================================================================
rem Main loop.
rem ==================================================================
proc InitFrameHold 60
do
    rem Maintain constant speed.
    proc HoldFrame

    vCentiCounter = (vCentiCounter + 1)%100
    vScroll = (vScroll + 1)%240
    vGridMotionAngle = vGridMotionAngle + 0.5

    rem Init new level if all enemies are gone.
    if vEnemyCount = 0
        vLevel = vLevel + 1
        proc InitEnemies 24 + vLevel*2
    endif

    rem Update.
    proc UpdatePlayer
    proc UpdateEnemies
    proc UpdateEnemyBullets
    proc UpdateExplosions
    if vGameOver
        vGameOverTimer = vGameOverTimer - 1
        if vGameOverTimer = 0
            vGameOver = false
            vLevel = 0
            vScore = 0
            vEnemyCount = 0
            proc InitPlayer
        endif
    endif
    
    rem Draw.
    set color 255, 255, 255
    draw image BACKGROUND_IMAGE, 0, vScroll
    draw image BACKGROUND_IMAGE, 0, vScroll - 240
    proc DrawEnemies
    proc DrawEnemyBullets
    proc DrawPlayer
    proc DrawExplosions
    proc DrawScoreEtc
    if vGameOver
        set color 0, 0, 0, 128
        cls
        set color 255, 255, 255
        draw image GAME_OVER_IMAGE, (width(primary) - width(GAME_OVER_IMAGE))/2, 100
        set caret width(primary)/2, 140
    endif

    redraw
until keydown(27) or not running()

stop music 0

end

rem ==================================================================
rem Load data.
rem ==================================================================
procedure Load()
    rem create font 0, "impact", 16
    rem save font 0, "data/impact16.txt", "data/impact16.bmp"
    if javac()
        load font 0, "data/impact16.txt", "data/impact16.png"
    else
        load font 0, "data/impact16.txt", "data/impact16.bmp"
    endif

    set color 255, 255, 255

    load image LOGO_IMAGE, "data/logo.bmp"
    draw image LOGO_IMAGE, 160 - width(LOGO_IMAGE)/2, 60

    set caret 160, 100
    center "Use cursor keys to control your ship."
    center "Press space bar to shoot."
    center
    center "Loading . . ."
    wait 1000

    if javac()
        load music 0, "data/bgmusic.aif"
    else
        load music 0, "data/bgmusic.it"
    endif

    load image GAME_OVER_IMAGE, "data/gameover.bmp"
    set image colorkey GAME_OVER_IMAGE, 0, 0, 0

    create image BACKGROUND_IMAGE, 320, 240
    set image BACKGROUND_IMAGE
    set color 0, 0, 0
    cls
    for i = 0 to 199
        set color 255, 255, 255, rnd(256)
        draw pixel rnd(320), rnd(240)
    next
    set image primary

    load image PLAYER_IMAGE, "data/player.bmp"
    set image colorkey PLAYER_IMAGE, 0, 0 ,0
    set image grid PLAYER_IMAGE, 2, 1

    load image PLAYER_BULLETS_IMAGE, "data/player_bullets.bmp"
    set image colorkey PLAYER_BULLETS_IMAGE, 0, 0, 0

    load image EXPLOSION_IMAGE, "data/explosion.bmp"
    set image colorkey EXPLOSION_IMAGE, 0, 0, 0
    set image grid EXPLOSION_IMAGE, 8, 1

    load image ENEMY_IMAGE_BASE + 1, "data/enemy_0.bmp"
    load image ENEMY_IMAGE_BASE + 2, "data/enemy_1.bmp"
    load image ENEMY_IMAGE_BASE + 3, "data/enemy_2.bmp"
    set image colorkey ENEMY_IMAGE_BASE + 1, 0, 0 ,0
    set image colorkey ENEMY_IMAGE_BASE + 2, 0, 0 ,0
    set image colorkey ENEMY_IMAGE_BASE + 3, 0, 0 ,0
    set image grid ENEMY_IMAGE_BASE + 1, 12, 1
    set image grid ENEMY_IMAGE_BASE + 2, 12, 1
    set image grid ENEMY_IMAGE_BASE + 3, 12, 1

    load image ENEMY_BULLET_IMAGE, "data/enemy_bullet.bmp"
    set image colorkey ENEMY_BULLET_IMAGE, 0, 0, 0
    set image grid ENEMY_BULLET_IMAGE, 2, 1

    load sound EXPLOSION_SOUND, "data/explosion.wav"
    load sound ENEMY_HIT_SOUND, "data/enemy_hit.wav"
    load sound BULLET_SOUND, "data/bullet.wav"
    
    set color 255, 255, 0
    center
    center "Click to start game!"
    wait mousebutton

endproc

rem ==================================================================
rem Init player.
rem ==================================================================
procedure InitPlayer()
    vLives = 3
    vPlayerX = 160 - width(PLAYER_IMAGE)/2
    vPlayerY = 250
    vPlayerShield = 200
    vPlayerBulletType = 0
    vGameOver = false
endproc

rem ==================================================================
rem Update player.
rem ==================================================================
procedure UpdatePlayer()
    if vGameOver then return;
    if keydown(37) then vPlayerX = vPlayerX - 2
    if keydown(39) then vPlayerX = vPlayerX + 2
    if vPlayerY > 210 then vPlayerY = vPlayerY - 1
    if vPlayerX < 0 then vPlayerX = 0
    if vPlayerX > 320 - width(PLAYER_IMAGE) then vPlayerX = 320 - width(PLAYER_IMAGE)
    if keydown(" ") and vPlayerBulletType = 0
        vPlayerBulletType = 1
        vPlayerBulletX = vPlayerX
        vPlayerBulletY = vPlayerY + 8
        play sound BULLET_SOUND
    endif
    if vPlayerShield > 0 then vPlayerShield = vPlayerShield - 1

    if vPlayerBulletType > 0
        vPlayerBulletY = vPlayerBulletY - 4
        if vPlayerBulletY < -height(PLAYER_BULLETS_IMAGE) then vPlayerBulletType = 0
    endif
endproc

rem ==================================================================
rem Draw player
rem ==================================================================
procedure DrawPlayer()
    if vGameOver then return
    if vPlayerShield = 0 or vCentiCounter%8 < 4 then draw image PLAYER_IMAGE, vPlayerX, vPlayerY, (vCentiCounter%10)/5
    if vPlayerBulletType > 0
        draw image PLAYER_BULLETS_IMAGE, vPlayerBulletX, vPlayerBulletY
    endif
endproc

rem ==================================================================
rem Lose a life.
rem ==================================================================
procedure LoseLife()
    if vPlayerShield = 0
        proc AddExplosion vPlayerX + width(PLAYER_IMAGE)/2, vPlayerY + height(PLAYER_IMAGE)/2
        vLives = vLives - 1
        vPlayerY = 250
        vPlayerX = 160 - width(PLAYER_IMAGE)/2
        vPlayerShield = 200
        if vLives < 0
            vGameOver = true
            vGameOverTimer = 300
        endif
    endif
endproc

rem ==================================================================
rem Draw score etc.
rem ==================================================================
procedure DrawScoreEtc()
    set color 255, 255, 255
    set caret 4, 4
    write "Level:   "
    set color 128, 255, 255
    write vLevel
    set caret 64, 4
    set color 255, 255, 255
    write "Score:   "
    set color 255, 255, 128
    write vScore

    set color 255, 255, 255
    for i = 0 to vLives - 1
        draw image PLAYER_IMAGE, 320 - (i + 1)*(width(PLAYER_IMAGE) + 4), 4, 0
    next
endproc

rem ==================================================================
rem Init explosions.
rem ==================================================================
procedure InitExplosions()
    vExplosionCounter = 0
    for i = 0 to MAX_EXPLOSIONS - 1
        vExplosions[i][EXP_FRAME] = -1
    next
endproc

rem ==================================================================
rem Add an explosion at (x, y).
rem ==================================================================
procedure AddExplosion(x, y)
    vExplosions[vExplosionCounter][EXP_FRAME] = 0
    vExplosions[vExplosionCounter][EXP_FRAME_COUNTER] = 0
    vExplosions[vExplosionCounter][EXP_X] = x - width(EXPLOSION_IMAGE)/2
    vExplosions[vExplosionCounter][EXP_Y] = y - height(EXPLOSION_IMAGE)/2
    vExplosionCounter = (vExplosionCounter + 1)%MAX_EXPLOSIONS
    play sound EXPLOSION_SOUND
endproc

rem ==================================================================
rem Update explosions.
rem ==================================================================
procedure UpdateExplosions()
    for i = 0 to MAX_EXPLOSIONS - 1
        if vExplosions[i][EXP_FRAME] >= 0
            vExplosions[i][EXP_FRAME_COUNTER] = (vExplosions[i][EXP_FRAME_COUNTER] + 1)%4
            if vExplosions[i][EXP_FRAME_COUNTER] = 0
                vExplosions[i][EXP_FRAME] = vExplosions[i][EXP_FRAME] + 1
                if vExplosions[i][EXP_FRAME] = 8 then vExplosions[i][EXP_FRAME] = -1
            endif
        endif
    next
endproc

rem ==================================================================
rem Draw explosions.
rem ==================================================================
procedure DrawExplosions()
    for i = 0 to MAX_EXPLOSIONS - 1
        if vExplosions[i][EXP_FRAME] >= 0
            draw image EXPLOSION_IMAGE, vExplosions[i][EXP_X], vExplosions[i][EXP_Y], vExplosions[i][EXP_FRAME]
        endif
    next
endproc

rem ==================================================================
rem Init enemies.
rem ==================================================================
procedure InitEnemies(count)
    vNextAttackTimer = 400

    rem Clear.
    for y = 0 to GRID_HEIGHT - 1
        for x = 0 to GRID_WIDTH - 1
            vEnemies[x][y][ENEMY_TYPE] = 0
        next
    next
    
    rem Add enemies.
    count = min(count, GRID_WIDTH*GRID_HEIGHT)/2
    for i = 0 to count - 1
        do
            x = rnd(GRID_WIDTH/2)
            y = rnd(GRID_HEIGHT)
        until vEnemies[x][y][ENEMY_TYPE] = 0
        type = rnd(3) + 1
        vEnemies[x][y][ENEMY_TYPE] = type
        vEnemies[x][y][ENEMY_STAMINA] = type
        vEnemies[x][y][ENEMY_STATE] = 0
        vEnemies[x][y][ENEMY_BASE_FRAME] = 0
        vEnemies[x][y][ENEMY_FRAME] = rnd(60)
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_TYPE] = type
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_STAMINA] = type
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_STATE] = 0
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_BASE_FRAME] = 0
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_FRAME] = rnd(60)
    next

    vEnemyCount = count*2

    vEnemyBulletCounter = 0
    for i = 0 to MAX_ENEMY_BULLETS - 1
        vEnemyBullets[i][BULLET_ACTIVE] = 0
    next
    vGridOffsetY = -200
endproc

rem ==================================================================
rem Add an enemy bullet moving from (x, y) to player's position.
rem ==================================================================
procedure AddEnemyBullet(x, y)
    vEnemyBullets[vEnemyBulletCounter][BULLET_ACTIVE] = true
    vEnemyBullets[vEnemyBulletCounter][BULLET_FRAME] = 0
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_X] = float(x)
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_Y] = float(y)
    dx# = float(vPlayerX) - float(x)
    dy# = float(vPlayerY) - float(y)
    k# = 1.0/sqr(dx*dx + dy*dy)
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_DX] = dx*k*2.0
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_DY] = dy*k*2.0
    vEnemyBulletCounter = (vEnemyBulletCounter + 1)%MAX_ENEMY_BULLETS
endproc

rem ==================================================================
rem Update enemy bullets.
rem ==================================================================
procedure UpdateEnemyBullets()
    for i = 0 to MAX_ENEMY_BULLETS - 1
        if vEnemyBullets[i][BULLET_ACTIVE]
            vEnemyBullets[i][BULLET_FRAME] = (vEnemyBullets[i][BULLET_FRAME] + 1)%20
            vEnemyBulletsF[i][BULLET_X] = vEnemyBulletsF[i][BULLET_X] + vEnemyBulletsF[i][BULLET_DX]
            vEnemyBulletsF[i][BULLET_Y] = vEnemyBulletsF[i][BULLET_Y] + vEnemyBulletsF[i][BULLET_DY]
            if not vGameOver
                if ImageCol(ENEMY_BULLET_IMAGE, int(vEnemyBulletsF[i][BULLET_X]), int(vEnemyBulletsF[i][BULLET_Y]), PLAYER_IMAGE, vPlayerX, vPlayerY)
                    vEnemyBullets[i][BULLET_ACTIVE] = false
                    proc LoseLife
                endif
            endif
        endif
    next
endproc

rem ==================================================================
rem Draw enemy bullets.
rem ==================================================================
procedure DrawEnemyBullets()
    for i = 0 to MAX_ENEMY_BULLETS - 1
        if vEnemyBullets[i][BULLET_ACTIVE]
            draw image ENEMY_BULLET_IMAGE, int(vEnemyBulletsF[i][BULLET_X]), int(vEnemyBulletsF[i][BULLET_Y]), vEnemyBullets[i][BULLET_FRAME]/10
        endif
    next
endproc

rem ==================================================================
rem Return the x coordinate of an enemy at grid position (x, y).
rem ==================================================================
function GridX(x, y)
    return (320 - GRID_WIDTH*CEL_SIZE)/2 + x*CEL_SIZE + int(cos(vGridMotionAngle + float(y*24))*24.0)
endfunc

rem ==================================================================
rem Return the y coordinate of an enemy at a certain grid y.
rem ==================================================================
function GridY(y)
    return 24 + y*CEL_SIZE + vGridOffsetY
endfunc

rem ==================================================================
rem Update enemies.
rem ==================================================================
procedure UpdateEnemies()
    if vGridOffsetY < 0 then vGridOffsetY = vGridOffsetY + 1
    vEnemyBulletTimer = vEnemyBulletTimer - 1
    rem Update enemy attacks.
    vNextAttackTimer = vNextAttackTimer - 1
    if vNextAttackTimer <= 0
        rem Look for enemies that can attack and add them to a list.
        attackers[GRID_WIDTH*GRID_HEIGHT]
        count = 0
        for y = 0 to GRID_HEIGHT - 1
            for x = 0 to GRID_WIDTH - 1
                if vEnemies[x][y][ENEMY_TYPE] > 0 and vEnemies[x][y][ENEMY_STATE] = 0
                    rem Add enemy to list of possible attackers. Convert its position
                    rem in the grid to an index.
                    attackers[count] = y*GRID_WIDTH + x
                    count = count + 1
                endif
            next    
        next
        rem Any one interested?
        if count > 0
            rem Get any enemy from the list.
            enemy = attackers[rnd(count)]
            rem Convert its position back to the 2D grid.
            x = enemy%GRID_WIDTH
            y = enemy/GRID_WIDTH
            rem Init its attack curve.
            vEnemies[x][y][ENEMY_STATE] = 1
            vEnemiesF[x][y][ENEMY_PARAM] = 0.0
            vEnemiesF[x][y][ENEMY_X1] = float(rnd(320))
            vEnemiesF[x][y][ENEMY_X2] = float(rnd(320))
            vEnemiesF[x][y][ENEMY_Y1] = 400.0
            vEnemiesF[x][y][ENEMY_Y2] = float(GridY(y) - 100)
            rem Wait some until next attack.
            vNextAttackTimer = max(200 + rnd(100) - vLevel*50, 50)
        else
            vNextAttackTimer = 50
        endif
    endif

    rem Move enemies.
    for y = 0 to GRID_HEIGHT - 1
        for x = 0 to GRID_WIDTH - 1
            if vEnemies[x][y][ENEMY_TYPE] > 0
                vEnemies[x][y][ENEMY_FRAME] = (vEnemies[x][y][ENEMY_FRAME] + 1)%60
                gx = GridX(x, y)
                gy = GridY(y)
                rem Is it attacking?
                if vEnemies[x][y][ENEMY_STATE] = 1
                    rem Shoot?
                    prm# = vEnemiesF[x][y][ENEMY_PARAM]
                    if vEnemyBulletTimer <= 0 and ((prm > 0.05 and prm < 0.1) or prm > 0.75)
                        vEnemyBulletTimer = 50 + rnd(100)
                        proc AddEnemyBullet vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y]
                    endif
                    rem Update position.
                    vEnemiesF[x][y][ENEMY_PARAM] = vEnemiesF[x][y][ENEMY_PARAM] + 0.0025
                    rem Back at where it started?
                    if vEnemiesF[x][y][ENEMY_PARAM] >= 1.0
                        vEnemies[x][y][ENEMY_STATE] = 0
                        vEnemies[x][y][ENEMY_X] = gx + 2
                        vEnemies[x][y][ENEMY_Y] = gy + 6
                        vEnemies[x][y][ENEMY_BASE_FRAME] = 0
                    else
                        p[] = FlyingEnemyPos(vEnemiesF[x][y][ENEMY_PARAM], float(gx), float(gy), vEnemiesF[x][y][ENEMY_X1], vEnemiesF[x][y][ENEMY_Y1], vEnemiesF[x][y][ENEMY_X2], vEnemiesF[x][y][ENEMY_Y2])
                        vEnemies[x][y][ENEMY_X] = p[0] + 4
                        vEnemies[x][y][ENEMY_Y] = p[1] + 6
                        vEnemies[x][y][ENEMY_BASE_FRAME] = FlyingEnemyDir(vEnemiesF[x][y][ENEMY_PARAM], float(gx), float(gy), vEnemiesF[x][y][ENEMY_X1], vEnemiesF[x][y][ENEMY_Y1], vEnemiesF[x][y][ENEMY_X2], vEnemiesF[x][y][ENEMY_Y2])
                    endif
                else
                    vEnemies[x][y][ENEMY_X] = gx + 2
                    vEnemies[x][y][ENEMY_Y] = gy + 6
                endif

                if ImageCol(vEnemies[x][y][ENEMY_TYPE] + ENEMY_IMAGE_BASE, vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y], PLAYER_IMAGE, vPlayerX, vPlayerY)
                    proc LoseLife
                endif

                rem Hit by player bullet?
                if vPlayerBulletType > 0
                    if ImageCol(vEnemies[x][y][ENEMY_TYPE] + ENEMY_IMAGE_BASE, vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y], PLAYER_BULLETS_IMAGE, vPlayerBulletX, vPlayerBulletY)
                        vPlayerBulletType = 0
                        vEnemies[x][y][ENEMY_STAMINA] = vEnemies[x][y][ENEMY_STAMINA] - 1
                        if vEnemies[x][y][ENEMY_STAMINA] = 0
                            img = ENEMY_IMAGE_BASE + vEnemies[x][y][ENEMY_TYPE]
                            proc AddExplosion vEnemies[x][y][ENEMY_X] + width(img)/2, vEnemies[x][y][ENEMY_Y] + height(img)/2
                            if vEnemies[x][y][ENEMY_STATE] = 1
                                vScore = vScore + 20*vEnemies[x][y][ENEMY_TYPE]
                            else
                                vScore = vScore + 10*vEnemies[x][y][ENEMY_TYPE]
                            endif
                            vEnemies[x][y][ENEMY_TYPE] = 0
                            vEnemyCount = vEnemyCount - 1
                        else
                            play sound ENEMY_HIT_SOUND
                        endif
                    endif
                endif

            endif
        next
    next
endproc

rem ==================================================================
rem Return true if two image at specific locations intersect.
rem ==================================================================
function ImageCol(img0, x0, y0, img1, x1, y1)
    if x0 + width(img0) < x1 then return false
    if y0 + height(img0) < y1 then return false
    if x1 + width(img1) < x0 then return false
    if y1 + height(img1) < y0 then return false
    return true
endfunc

rem ==================================================================
rem Calculate position for an attacking enemy. It's a special case of
rem a cubic bezier curve, where the start and end point are the same.
rem ==================================================================
function FlyingEnemyPos[](param#, x#, y#, x1#, y1#, x2#, y2#)
    param = max#(param, 0.0)
    param = min#(param, 1.0)
    b0# = 1.0 - param
    b0 = b0*b0*b0
    b1# = 1.0 - param
    b1 = b1*b1
    b1 = b1*3.0*param
    b2# = 3.0*(1.0 - param)*param*param
    b3# = param*param*param
    return [int(b0*x + b1*x1 + b2*x2 + b3*x), int(b0*y + b1*y1 + b2*y2 + b3*y)]
endfunc

rem ==================================================================
rem Return direction for enemy (a base frame for its image grid).
rem Think I've messed up the code a little here ... never mind.
rem ==================================================================
function FlyingEnemyDir(param#, x#, y#, x1#, y1#, x2#, y2#)
    b0# = 1.0 - param
    b0 = -3.0*b0*b0
    b1# = 1.0 - param
    b1 = 3.0*b1 - 6.0*param*b1
    b2# = 6.0*param*(1.0 - param) - 3.0*param*param
    b3# = 3.0*param*param
    dx# = b0*x + b1*x1 + b2*x2 + b3*x
    dy# = b0*y + b1*y1 + b2*y2 + b3*y
    k# = 1.0/sqr(dx*dx + dy*dy)
    dx = dx*k
    dy = dy*k
    
    if dy <= 0.0
        if abs#(dx) < 0.25
            ret = 0
        else
            if dx < 0.0
                ret = 8
            else
                ret = 10
            endif
        endif
    else
        if abs#(dx) < 0.25
            ret = 2
        else
            if dx < 0.0
                ret = 6
            else
                ret = 4
            endif
        endif
    endif
    return ret
endproc

rem ==================================================================
rem Draw enemies.
rem ==================================================================
procedure DrawEnemies()
    for y = 0 to GRID_HEIGHT - 1
        for x = 0 to GRID_WIDTH - 1
            if vEnemies[x][y][ENEMY_TYPE] > 0
                set color 255, 255, 255
                draw image ENEMY_IMAGE_BASE + vEnemies[x][y][ENEMY_TYPE], vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y], vEnemies[x][y][ENEMY_BASE_FRAME] + vEnemies[x][y][ENEMY_FRAME]/30
            endif
        next
    next
endproc

rem ==================================================================
rem Init frame hold
rem ==================================================================
procedure InitFrameHold(speed)
    vNextFrameTime = time()
    vFrameHold = 1000/speed
endproc

rem ==================================================================
rem Hold frame to maintain constant speed.
rem ==================================================================
procedure HoldFrame()
    while time() < vNextFrameTime; wait 1; wend
    vNextFrameTime = vNextFrameTime + vFrameHold
endproc
Reply
#3
I think Blastemroids was one of the first games I wrote in naalaa Smile
Reply
#4
(02-12-2026, 08:44 AM)1micha.elok Wrote: This one ?

Code:
rem ==================================================================
rem Blastemroids
rem
rem Enemy and player sprites by Ari Feldman, other sprites by Marcus.
rem ==================================================================

visible:
    vNextFrameTime
    vFrameHold

visible:
    rem Enemy data.
    CEL_SIZE = 20
    GRID_WIDTH = 12
    GRID_HEIGHT = 6
    vEnemies[GRID_WIDTH][GRID_HEIGHT][7]
    ENEMY_TYPE = 0
    ENEMY_STATE = 1
    ENEMY_STAMINA = 2
    ENEMY_X = 3
    ENEMY_Y = 4
    ENEMY_BASE_FRAME = 5
    ENEMY_FRAME = 6
    vEnemiesF#[GRID_WIDTH][GRID_HEIGHT][5]
    ENEMY_X1 = 0
    ENEMY_Y1 = 1
    ENEMY_X2 = 2
    ENEMY_Y2 = 3
    ENEMY_PARAM = 4
    vNextAttackTimer
    vEnemyCount
    vGridMotionAngle# = 0.0
    vGridOffsetY

    rem Enemy bullets.
    MAX_ENEMY_BULLETS = 8
    vEnemyBullets[MAX_ENEMY_BULLETS][2]
    BULLET_ACTIVE = 0
    BULLET_FRAME = 1
    vEnemyBulletsF#[MAX_ENEMY_BULLETS][4]
    BULLET_X = 0
    BULLET_Y = 1
    BULLET_DX = 2
    BULLET_DY = 3
    vEnemyBulletCounter
    vEnemyBulletTimer = 400

    rem Player.
    vPlayerX
    vPlayerY
    vPlayerBulletType
    vPlayerBulletX
    vPlayerBulletY
    vPlayerShield
    vScore = 0
    vLevel = 1
    vLives = 3
    vGameOver = false
    vGameOverTimer = 0

    rem Explosions.
    MAX_EXPLOSIONS = 8
    vExplosions[MAX_EXPLOSIONS][4]
    EXP_FRAME = 0
    EXP_FRAME_COUNTER = 1
    EXP_X = 2
    EXP_Y = 3
    vExplosionCounter = 0

    rem Other.
    vScroll = 0
    vCentiCounter = 0

    rem Images.
    BACKGROUND_IMAGE = 0
    PLAYER_IMAGE = 1
    PLAYER_BULLETS_IMAGE = 2
    EXPLOSION_IMAGE = 3
    LOGO_IMAGE = 4
    GAME_OVER_IMAGE = 5
    ENEMY_BULLET_IMAGE = 10
    ENEMY_IMAGE_BASE = 10

    rem Sound.
    EXPLOSION_SOUND = 0
    ENEMY_HIT_SOUND = 1
    BULLET_SOUND = 2

hidden:

rem Init window.
set window 0, 0, 320, 240, true, true
set color 0, 0, 0
cls

rem Load.
proc Load
set redraw off


rem Init.
proc InitPlayer
proc InitEnemies 24 + vLevel*2
proc InitExplosions

play music 0

rem ==================================================================
rem Main loop.
rem ==================================================================
proc InitFrameHold 60
do
    rem Maintain constant speed.
    proc HoldFrame

    vCentiCounter = (vCentiCounter + 1)%100
    vScroll = (vScroll + 1)%240
    vGridMotionAngle = vGridMotionAngle + 0.5

    rem Init new level if all enemies are gone.
    if vEnemyCount = 0
        vLevel = vLevel + 1
        proc InitEnemies 24 + vLevel*2
    endif

    rem Update.
    proc UpdatePlayer
    proc UpdateEnemies
    proc UpdateEnemyBullets
    proc UpdateExplosions
    if vGameOver
        vGameOverTimer = vGameOverTimer - 1
        if vGameOverTimer = 0
            vGameOver = false
            vLevel = 0
            vScore = 0
            vEnemyCount = 0
            proc InitPlayer
        endif
    endif
    
    rem Draw.
    set color 255, 255, 255
    draw image BACKGROUND_IMAGE, 0, vScroll
    draw image BACKGROUND_IMAGE, 0, vScroll - 240
    proc DrawEnemies
    proc DrawEnemyBullets
    proc DrawPlayer
    proc DrawExplosions
    proc DrawScoreEtc
    if vGameOver
        set color 0, 0, 0, 128
        cls
        set color 255, 255, 255
        draw image GAME_OVER_IMAGE, (width(primary) - width(GAME_OVER_IMAGE))/2, 100
        set caret width(primary)/2, 140
    endif

    redraw
until keydown(27) or not running()

stop music 0

end

rem ==================================================================
rem Load data.
rem ==================================================================
procedure Load()
    rem create font 0, "impact", 16
    rem save font 0, "data/impact16.txt", "data/impact16.bmp"
    if javac()
        load font 0, "data/impact16.txt", "data/impact16.png"
    else
        load font 0, "data/impact16.txt", "data/impact16.bmp"
    endif

    set color 255, 255, 255

    load image LOGO_IMAGE, "data/logo.bmp"
    draw image LOGO_IMAGE, 160 - width(LOGO_IMAGE)/2, 60

    set caret 160, 100
    center "Use cursor keys to control your ship."
    center "Press space bar to shoot."
    center
    center "Loading . . ."
    wait 1000

    if javac()
        load music 0, "data/bgmusic.aif"
    else
        load music 0, "data/bgmusic.it"
    endif

    load image GAME_OVER_IMAGE, "data/gameover.bmp"
    set image colorkey GAME_OVER_IMAGE, 0, 0, 0

    create image BACKGROUND_IMAGE, 320, 240
    set image BACKGROUND_IMAGE
    set color 0, 0, 0
    cls
    for i = 0 to 199
        set color 255, 255, 255, rnd(256)
        draw pixel rnd(320), rnd(240)
    next
    set image primary

    load image PLAYER_IMAGE, "data/player.bmp"
    set image colorkey PLAYER_IMAGE, 0, 0 ,0
    set image grid PLAYER_IMAGE, 2, 1

    load image PLAYER_BULLETS_IMAGE, "data/player_bullets.bmp"
    set image colorkey PLAYER_BULLETS_IMAGE, 0, 0, 0

    load image EXPLOSION_IMAGE, "data/explosion.bmp"
    set image colorkey EXPLOSION_IMAGE, 0, 0, 0
    set image grid EXPLOSION_IMAGE, 8, 1

    load image ENEMY_IMAGE_BASE + 1, "data/enemy_0.bmp"
    load image ENEMY_IMAGE_BASE + 2, "data/enemy_1.bmp"
    load image ENEMY_IMAGE_BASE + 3, "data/enemy_2.bmp"
    set image colorkey ENEMY_IMAGE_BASE + 1, 0, 0 ,0
    set image colorkey ENEMY_IMAGE_BASE + 2, 0, 0 ,0
    set image colorkey ENEMY_IMAGE_BASE + 3, 0, 0 ,0
    set image grid ENEMY_IMAGE_BASE + 1, 12, 1
    set image grid ENEMY_IMAGE_BASE + 2, 12, 1
    set image grid ENEMY_IMAGE_BASE + 3, 12, 1

    load image ENEMY_BULLET_IMAGE, "data/enemy_bullet.bmp"
    set image colorkey ENEMY_BULLET_IMAGE, 0, 0, 0
    set image grid ENEMY_BULLET_IMAGE, 2, 1

    load sound EXPLOSION_SOUND, "data/explosion.wav"
    load sound ENEMY_HIT_SOUND, "data/enemy_hit.wav"
    load sound BULLET_SOUND, "data/bullet.wav"
    
    set color 255, 255, 0
    center
    center "Click to start game!"
    wait mousebutton

endproc

rem ==================================================================
rem Init player.
rem ==================================================================
procedure InitPlayer()
    vLives = 3
    vPlayerX = 160 - width(PLAYER_IMAGE)/2
    vPlayerY = 250
    vPlayerShield = 200
    vPlayerBulletType = 0
    vGameOver = false
endproc

rem ==================================================================
rem Update player.
rem ==================================================================
procedure UpdatePlayer()
    if vGameOver then return;
    if keydown(37) then vPlayerX = vPlayerX - 2
    if keydown(39) then vPlayerX = vPlayerX + 2
    if vPlayerY > 210 then vPlayerY = vPlayerY - 1
    if vPlayerX < 0 then vPlayerX = 0
    if vPlayerX > 320 - width(PLAYER_IMAGE) then vPlayerX = 320 - width(PLAYER_IMAGE)
    if keydown(" ") and vPlayerBulletType = 0
        vPlayerBulletType = 1
        vPlayerBulletX = vPlayerX
        vPlayerBulletY = vPlayerY + 8
        play sound BULLET_SOUND
    endif
    if vPlayerShield > 0 then vPlayerShield = vPlayerShield - 1

    if vPlayerBulletType > 0
        vPlayerBulletY = vPlayerBulletY - 4
        if vPlayerBulletY < -height(PLAYER_BULLETS_IMAGE) then vPlayerBulletType = 0
    endif
endproc

rem ==================================================================
rem Draw player
rem ==================================================================
procedure DrawPlayer()
    if vGameOver then return
    if vPlayerShield = 0 or vCentiCounter%8 < 4 then draw image PLAYER_IMAGE, vPlayerX, vPlayerY, (vCentiCounter%10)/5
    if vPlayerBulletType > 0
        draw image PLAYER_BULLETS_IMAGE, vPlayerBulletX, vPlayerBulletY
    endif
endproc

rem ==================================================================
rem Lose a life.
rem ==================================================================
procedure LoseLife()
    if vPlayerShield = 0
        proc AddExplosion vPlayerX + width(PLAYER_IMAGE)/2, vPlayerY + height(PLAYER_IMAGE)/2
        vLives = vLives - 1
        vPlayerY = 250
        vPlayerX = 160 - width(PLAYER_IMAGE)/2
        vPlayerShield = 200
        if vLives < 0
            vGameOver = true
            vGameOverTimer = 300
        endif
    endif
endproc

rem ==================================================================
rem Draw score etc.
rem ==================================================================
procedure DrawScoreEtc()
    set color 255, 255, 255
    set caret 4, 4
    write "Level:   "
    set color 128, 255, 255
    write vLevel
    set caret 64, 4
    set color 255, 255, 255
    write "Score:   "
    set color 255, 255, 128
    write vScore

    set color 255, 255, 255
    for i = 0 to vLives - 1
        draw image PLAYER_IMAGE, 320 - (i + 1)*(width(PLAYER_IMAGE) + 4), 4, 0
    next
endproc

rem ==================================================================
rem Init explosions.
rem ==================================================================
procedure InitExplosions()
    vExplosionCounter = 0
    for i = 0 to MAX_EXPLOSIONS - 1
        vExplosions[i][EXP_FRAME] = -1
    next
endproc

rem ==================================================================
rem Add an explosion at (x, y).
rem ==================================================================
procedure AddExplosion(x, y)
    vExplosions[vExplosionCounter][EXP_FRAME] = 0
    vExplosions[vExplosionCounter][EXP_FRAME_COUNTER] = 0
    vExplosions[vExplosionCounter][EXP_X] = x - width(EXPLOSION_IMAGE)/2
    vExplosions[vExplosionCounter][EXP_Y] = y - height(EXPLOSION_IMAGE)/2
    vExplosionCounter = (vExplosionCounter + 1)%MAX_EXPLOSIONS
    play sound EXPLOSION_SOUND
endproc

rem ==================================================================
rem Update explosions.
rem ==================================================================
procedure UpdateExplosions()
    for i = 0 to MAX_EXPLOSIONS - 1
        if vExplosions[i][EXP_FRAME] >= 0
            vExplosions[i][EXP_FRAME_COUNTER] = (vExplosions[i][EXP_FRAME_COUNTER] + 1)%4
            if vExplosions[i][EXP_FRAME_COUNTER] = 0
                vExplosions[i][EXP_FRAME] = vExplosions[i][EXP_FRAME] + 1
                if vExplosions[i][EXP_FRAME] = 8 then vExplosions[i][EXP_FRAME] = -1
            endif
        endif
    next
endproc

rem ==================================================================
rem Draw explosions.
rem ==================================================================
procedure DrawExplosions()
    for i = 0 to MAX_EXPLOSIONS - 1
        if vExplosions[i][EXP_FRAME] >= 0
            draw image EXPLOSION_IMAGE, vExplosions[i][EXP_X], vExplosions[i][EXP_Y], vExplosions[i][EXP_FRAME]
        endif
    next
endproc

rem ==================================================================
rem Init enemies.
rem ==================================================================
procedure InitEnemies(count)
    vNextAttackTimer = 400

    rem Clear.
    for y = 0 to GRID_HEIGHT - 1
        for x = 0 to GRID_WIDTH - 1
            vEnemies[x][y][ENEMY_TYPE] = 0
        next
    next
    
    rem Add enemies.
    count = min(count, GRID_WIDTH*GRID_HEIGHT)/2
    for i = 0 to count - 1
        do
            x = rnd(GRID_WIDTH/2)
            y = rnd(GRID_HEIGHT)
        until vEnemies[x][y][ENEMY_TYPE] = 0
        type = rnd(3) + 1
        vEnemies[x][y][ENEMY_TYPE] = type
        vEnemies[x][y][ENEMY_STAMINA] = type
        vEnemies[x][y][ENEMY_STATE] = 0
        vEnemies[x][y][ENEMY_BASE_FRAME] = 0
        vEnemies[x][y][ENEMY_FRAME] = rnd(60)
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_TYPE] = type
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_STAMINA] = type
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_STATE] = 0
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_BASE_FRAME] = 0
        vEnemies[GRID_WIDTH - 1 - x][y][ENEMY_FRAME] = rnd(60)
    next

    vEnemyCount = count*2

    vEnemyBulletCounter = 0
    for i = 0 to MAX_ENEMY_BULLETS - 1
        vEnemyBullets[i][BULLET_ACTIVE] = 0
    next
    vGridOffsetY = -200
endproc

rem ==================================================================
rem Add an enemy bullet moving from (x, y) to player's position.
rem ==================================================================
procedure AddEnemyBullet(x, y)
    vEnemyBullets[vEnemyBulletCounter][BULLET_ACTIVE] = true
    vEnemyBullets[vEnemyBulletCounter][BULLET_FRAME] = 0
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_X] = float(x)
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_Y] = float(y)
    dx# = float(vPlayerX) - float(x)
    dy# = float(vPlayerY) - float(y)
    k# = 1.0/sqr(dx*dx + dy*dy)
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_DX] = dx*k*2.0
    vEnemyBulletsF[vEnemyBulletCounter][BULLET_DY] = dy*k*2.0
    vEnemyBulletCounter = (vEnemyBulletCounter + 1)%MAX_ENEMY_BULLETS
endproc

rem ==================================================================
rem Update enemy bullets.
rem ==================================================================
procedure UpdateEnemyBullets()
    for i = 0 to MAX_ENEMY_BULLETS - 1
        if vEnemyBullets[i][BULLET_ACTIVE]
            vEnemyBullets[i][BULLET_FRAME] = (vEnemyBullets[i][BULLET_FRAME] + 1)%20
            vEnemyBulletsF[i][BULLET_X] = vEnemyBulletsF[i][BULLET_X] + vEnemyBulletsF[i][BULLET_DX]
            vEnemyBulletsF[i][BULLET_Y] = vEnemyBulletsF[i][BULLET_Y] + vEnemyBulletsF[i][BULLET_DY]
            if not vGameOver
                if ImageCol(ENEMY_BULLET_IMAGE, int(vEnemyBulletsF[i][BULLET_X]), int(vEnemyBulletsF[i][BULLET_Y]), PLAYER_IMAGE, vPlayerX, vPlayerY)
                    vEnemyBullets[i][BULLET_ACTIVE] = false
                    proc LoseLife
                endif
            endif
        endif
    next
endproc

rem ==================================================================
rem Draw enemy bullets.
rem ==================================================================
procedure DrawEnemyBullets()
    for i = 0 to MAX_ENEMY_BULLETS - 1
        if vEnemyBullets[i][BULLET_ACTIVE]
            draw image ENEMY_BULLET_IMAGE, int(vEnemyBulletsF[i][BULLET_X]), int(vEnemyBulletsF[i][BULLET_Y]), vEnemyBullets[i][BULLET_FRAME]/10
        endif
    next
endproc

rem ==================================================================
rem Return the x coordinate of an enemy at grid position (x, y).
rem ==================================================================
function GridX(x, y)
    return (320 - GRID_WIDTH*CEL_SIZE)/2 + x*CEL_SIZE + int(cos(vGridMotionAngle + float(y*24))*24.0)
endfunc

rem ==================================================================
rem Return the y coordinate of an enemy at a certain grid y.
rem ==================================================================
function GridY(y)
    return 24 + y*CEL_SIZE + vGridOffsetY
endfunc

rem ==================================================================
rem Update enemies.
rem ==================================================================
procedure UpdateEnemies()
    if vGridOffsetY < 0 then vGridOffsetY = vGridOffsetY + 1
    vEnemyBulletTimer = vEnemyBulletTimer - 1
    rem Update enemy attacks.
    vNextAttackTimer = vNextAttackTimer - 1
    if vNextAttackTimer <= 0
        rem Look for enemies that can attack and add them to a list.
        attackers[GRID_WIDTH*GRID_HEIGHT]
        count = 0
        for y = 0 to GRID_HEIGHT - 1
            for x = 0 to GRID_WIDTH - 1
                if vEnemies[x][y][ENEMY_TYPE] > 0 and vEnemies[x][y][ENEMY_STATE] = 0
                    rem Add enemy to list of possible attackers. Convert its position
                    rem in the grid to an index.
                    attackers[count] = y*GRID_WIDTH + x
                    count = count + 1
                endif
            next    
        next
        rem Any one interested?
        if count > 0
            rem Get any enemy from the list.
            enemy = attackers[rnd(count)]
            rem Convert its position back to the 2D grid.
            x = enemy%GRID_WIDTH
            y = enemy/GRID_WIDTH
            rem Init its attack curve.
            vEnemies[x][y][ENEMY_STATE] = 1
            vEnemiesF[x][y][ENEMY_PARAM] = 0.0
            vEnemiesF[x][y][ENEMY_X1] = float(rnd(320))
            vEnemiesF[x][y][ENEMY_X2] = float(rnd(320))
            vEnemiesF[x][y][ENEMY_Y1] = 400.0
            vEnemiesF[x][y][ENEMY_Y2] = float(GridY(y) - 100)
            rem Wait some until next attack.
            vNextAttackTimer = max(200 + rnd(100) - vLevel*50, 50)
        else
            vNextAttackTimer = 50
        endif
    endif

    rem Move enemies.
    for y = 0 to GRID_HEIGHT - 1
        for x = 0 to GRID_WIDTH - 1
            if vEnemies[x][y][ENEMY_TYPE] > 0
                vEnemies[x][y][ENEMY_FRAME] = (vEnemies[x][y][ENEMY_FRAME] + 1)%60
                gx = GridX(x, y)
                gy = GridY(y)
                rem Is it attacking?
                if vEnemies[x][y][ENEMY_STATE] = 1
                    rem Shoot?
                    prm# = vEnemiesF[x][y][ENEMY_PARAM]
                    if vEnemyBulletTimer <= 0 and ((prm > 0.05 and prm < 0.1) or prm > 0.75)
                        vEnemyBulletTimer = 50 + rnd(100)
                        proc AddEnemyBullet vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y]
                    endif
                    rem Update position.
                    vEnemiesF[x][y][ENEMY_PARAM] = vEnemiesF[x][y][ENEMY_PARAM] + 0.0025
                    rem Back at where it started?
                    if vEnemiesF[x][y][ENEMY_PARAM] >= 1.0
                        vEnemies[x][y][ENEMY_STATE] = 0
                        vEnemies[x][y][ENEMY_X] = gx + 2
                        vEnemies[x][y][ENEMY_Y] = gy + 6
                        vEnemies[x][y][ENEMY_BASE_FRAME] = 0
                    else
                        p[] = FlyingEnemyPos(vEnemiesF[x][y][ENEMY_PARAM], float(gx), float(gy), vEnemiesF[x][y][ENEMY_X1], vEnemiesF[x][y][ENEMY_Y1], vEnemiesF[x][y][ENEMY_X2], vEnemiesF[x][y][ENEMY_Y2])
                        vEnemies[x][y][ENEMY_X] = p[0] + 4
                        vEnemies[x][y][ENEMY_Y] = p[1] + 6
                        vEnemies[x][y][ENEMY_BASE_FRAME] = FlyingEnemyDir(vEnemiesF[x][y][ENEMY_PARAM], float(gx), float(gy), vEnemiesF[x][y][ENEMY_X1], vEnemiesF[x][y][ENEMY_Y1], vEnemiesF[x][y][ENEMY_X2], vEnemiesF[x][y][ENEMY_Y2])
                    endif
                else
                    vEnemies[x][y][ENEMY_X] = gx + 2
                    vEnemies[x][y][ENEMY_Y] = gy + 6
                endif

                if ImageCol(vEnemies[x][y][ENEMY_TYPE] + ENEMY_IMAGE_BASE, vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y], PLAYER_IMAGE, vPlayerX, vPlayerY)
                    proc LoseLife
                endif

                rem Hit by player bullet?
                if vPlayerBulletType > 0
                    if ImageCol(vEnemies[x][y][ENEMY_TYPE] + ENEMY_IMAGE_BASE, vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y], PLAYER_BULLETS_IMAGE, vPlayerBulletX, vPlayerBulletY)
                        vPlayerBulletType = 0
                        vEnemies[x][y][ENEMY_STAMINA] = vEnemies[x][y][ENEMY_STAMINA] - 1
                        if vEnemies[x][y][ENEMY_STAMINA] = 0
                            img = ENEMY_IMAGE_BASE + vEnemies[x][y][ENEMY_TYPE]
                            proc AddExplosion vEnemies[x][y][ENEMY_X] + width(img)/2, vEnemies[x][y][ENEMY_Y] + height(img)/2
                            if vEnemies[x][y][ENEMY_STATE] = 1
                                vScore = vScore + 20*vEnemies[x][y][ENEMY_TYPE]
                            else
                                vScore = vScore + 10*vEnemies[x][y][ENEMY_TYPE]
                            endif
                            vEnemies[x][y][ENEMY_TYPE] = 0
                            vEnemyCount = vEnemyCount - 1
                        else
                            play sound ENEMY_HIT_SOUND
                        endif
                    endif
                endif

            endif
        next
    next
endproc

rem ==================================================================
rem Return true if two image at specific locations intersect.
rem ==================================================================
function ImageCol(img0, x0, y0, img1, x1, y1)
    if x0 + width(img0) < x1 then return false
    if y0 + height(img0) < y1 then return false
    if x1 + width(img1) < x0 then return false
    if y1 + height(img1) < y0 then return false
    return true
endfunc

rem ==================================================================
rem Calculate position for an attacking enemy. It's a special case of
rem a cubic bezier curve, where the start and end point are the same.
rem ==================================================================
function FlyingEnemyPos[](param#, x#, y#, x1#, y1#, x2#, y2#)
    param = max#(param, 0.0)
    param = min#(param, 1.0)
    b0# = 1.0 - param
    b0 = b0*b0*b0
    b1# = 1.0 - param
    b1 = b1*b1
    b1 = b1*3.0*param
    b2# = 3.0*(1.0 - param)*param*param
    b3# = param*param*param
    return [int(b0*x + b1*x1 + b2*x2 + b3*x), int(b0*y + b1*y1 + b2*y2 + b3*y)]
endfunc

rem ==================================================================
rem Return direction for enemy (a base frame for its image grid).
rem Think I've messed up the code a little here ... never mind.
rem ==================================================================
function FlyingEnemyDir(param#, x#, y#, x1#, y1#, x2#, y2#)
    b0# = 1.0 - param
    b0 = -3.0*b0*b0
    b1# = 1.0 - param
    b1 = 3.0*b1 - 6.0*param*b1
    b2# = 6.0*param*(1.0 - param) - 3.0*param*param
    b3# = 3.0*param*param
    dx# = b0*x + b1*x1 + b2*x2 + b3*x
    dy# = b0*y + b1*y1 + b2*y2 + b3*y
    k# = 1.0/sqr(dx*dx + dy*dy)
    dx = dx*k
    dy = dy*k
    
    if dy <= 0.0
        if abs#(dx) < 0.25
            ret = 0
        else
            if dx < 0.0
                ret = 8
            else
                ret = 10
            endif
        endif
    else
        if abs#(dx) < 0.25
            ret = 2
        else
            if dx < 0.0
                ret = 6
            else
                ret = 4
            endif
        endif
    endif
    return ret
endproc

rem ==================================================================
rem Draw enemies.
rem ==================================================================
procedure DrawEnemies()
    for y = 0 to GRID_HEIGHT - 1
        for x = 0 to GRID_WIDTH - 1
            if vEnemies[x][y][ENEMY_TYPE] > 0
                set color 255, 255, 255
                draw image ENEMY_IMAGE_BASE + vEnemies[x][y][ENEMY_TYPE], vEnemies[x][y][ENEMY_X], vEnemies[x][y][ENEMY_Y], vEnemies[x][y][ENEMY_BASE_FRAME] + vEnemies[x][y][ENEMY_FRAME]/30
            endif
        next
    next
endproc

rem ==================================================================
rem Init frame hold
rem ==================================================================
procedure InitFrameHold(speed)
    vNextFrameTime = time()
    vFrameHold = 1000/speed
endproc

rem ==================================================================
rem Hold frame to maintain constant speed.
rem ==================================================================
procedure HoldFrame()
    while time() < vNextFrameTime; wait 1; wend
    vNextFrameTime = vNextFrameTime + vFrameHold
endproc

Ohh nice. I think so

(02-12-2026, 05:42 PM)Marcus Wrote: I think Blastemroids was one of the first games I wrote in naalaa Smile

Hey Marcus, do you happen to have a copy of this game? Just asking out of pure nostalgia.
Don’t Count Your Chickens Before They Hatch
Reply
#5
I'll have a look at a backup drive tomorrow!
Reply
#6
Hi, sorry to butt in, but I can see that this was included in the N6 distribution in the examples folder (examples/games). If you no longer have N6 installed, it can still be downloaded from Naalaa.com home page.
Hope this helps......

Edit - I just tried running the program here, and found that I had to change the lines with "set image colorkey" in, replacing "0,0,0" with "true" in each case. Not sure why (perhaps I have an older version), but it seems to run fine with those changes.
Reply
#7
(02-13-2026, 05:05 PM)kevin Wrote: Hi, sorry to butt in, but I can see that this was included in the N6 distribution in the examples folder (examples/games). If you no longer have N6 installed, it can still be downloaded from Naalaa.com home page.
Hope this helps......

Edit - I just tried running the program here, and found that I had to change the lines with "set image colorkey" in, replacing "0,0,0" with "true" in each case. Not sure why (perhaps I have an older version), but it seems to run fine with those changes.

Is it?

[Image: froc-froccoli.gif]

let me check

Yessssss! This is the one ?. Thanks everyone.

[Image: Screenshot-2026-02-13-233745.png]

Absolute Nostalgia. I remember my college days.
Don’t Count Your Chickens Before They Hatch
Reply
#8
I think that i tried this shooter
looking great!!!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)