Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 37
» Latest member: Ludwig
» Forum threads: 181
» Forum posts: 1,428

Full Statistics

Online Users
There are currently 64 online users.
» 0 Member(s) | 62 Guest(s)
Bing, Google

Latest Threads
Print Using
Forum: Programming
Last Post: johnno56
Yesterday, 09:46 AM
» Replies: 2
» Views: 35
Naalaanoid (another arkan...
Forum: NaaLaa 7 Code
Last Post: kevin
03-18-2025, 03:27 PM
» Replies: 6
» Views: 167
Bridge (simple physics)
Forum: NaaLaa 7 Code
Last Post: Marcus
03-16-2025, 06:27 PM
» Replies: 3
» Views: 91
Primitive Angry Bird
Forum: NaaLaa 7 Code
Last Post: johnno56
03-16-2025, 11:52 AM
» Replies: 8
» Views: 333
Mystify
Forum: NaaLaa 7 Code
Last Post: Marcus
03-10-2025, 04:45 PM
» Replies: 7
» Views: 493
3d text
Forum: NaaLaa 7 Code
Last Post: 1micha.elok
03-08-2025, 01:12 PM
» Replies: 2
» Views: 236
Mystify
Forum: NaaLaa 6 Code
Last Post: johnno56
03-08-2025, 12:19 PM
» Replies: 2
» Views: 222
Tree
Forum: NaaLaa 7 Code
Last Post: 1micha.elok
03-07-2025, 03:22 AM
» Replies: 5
» Views: 470
syntax help / example
Forum: NaaLaa 7 Code
Last Post: johnno56
03-03-2025, 10:12 AM
» Replies: 3
» Views: 364
Color Wheel
Forum: NaaLaa 7 Code
Last Post: 1micha.elok
03-02-2025, 11:35 PM
» Replies: 6
» Views: 551

 
  Print Using
Posted by: johnno56 - Yesterday, 01:00 AM - Forum: Programming - Replies (2)

I am trying to convert a QB64 program and I have encountered the command PRINT USING.

Does anyone know of a procedure to format text to simulate the command?

eg: PRINT USING "#,###,#00  Lives: #  <--JAKE"; score2; lives2

if the score is 1234 and lives are 3: output would be:   1,234  Lives: 3 <--JAKE

Print this item

  Naalaanoid (another arkanoid clone)
Posted by: Marcus - 03-16-2025, 05:56 PM - Forum: NaaLaa 7 Code - Replies (6)

Here's another arkanoid clone!

   

Code:
' naalaanoid.n7
' -------------

#win32

include "tilemap.n7"
include "sfx.n7"
include "file.n7"

' Level generation thing.
visible SEED = 241' 239
' Bonuses.
constant BIG_PADDLE = 1, SMALL_PADDLE = 2, SPEED_UP = 3, SPEED_DOWN = 4, MULTIBALL = 5, CANNONS = 6

' Images.
visible vTilemapImage
visible vBgImage
visible vRedBrickImage, vGreenBrickImage, vBlueBrickImage, vYellowBrickImage, vMagentaBrickImage
visible vCyanBrickImage, vBrickHitImage
visible vPaddleImage, vCannonImage
visible vBallImage, vBulletImage
visible vBigPaddleBonusImage, vSmallPaddleBonusImage, vSpeedUpBonusImage, vSpeedDownBonusImage
visible vMultiballBonusImage, vCannonsBonusImage
visible vNaalaanoidTextImage, vGetReadyTextImage, vGameOverTextImage

' Colors.
visible vRedColor = [157, 40, 92], vGreenColor = [0, 118, 69], vBlueColor = [0, 110, 138]
visible vYellowColor = [179, 175, 12], vMagentaColor = [149, 31, 169], vCyanColor = [71, 193, 197]
visible vWhiteColor = [252, 252, 252], vBlackColor = [0, 0, 0], vGrayColor = [185, 185, 185]
visible vDarkRedColor = [90, 0, 24], vDarkGreenColor = [0, 57, 36], vDarkBlueColor = [9, 19, 128]
visible vDarkMagentaColor = [85, 0, 86]

' Sound effects.
visible vPaddleSound, vBrickHitSound, vBrickDestroyedSound, vWallSound, vLifeLostSound, vBonusSound
visible vShootSound

' Sprite lists.
visible vBalls = []
visible vBullets = []
visible vAnims = []
visible vBonuses = []

' Flying texts.
visible vFlyingTexts = FlyingTexts(64)

' Stats.
visible vScore, vTopScore
visible vBrickCount, vBricksLeft

' Create window.
set window "Naalaanoid", 256, 240, false, int((screenh() - 160)/240)
set redraw off

' Create and set save folder.
folder = GetPathCombined(GetAppDataDirectory(), "naalaa7")
CreateDirectory(folder)
saveFilename = GetPathCombined(folder, "naalaanoid.bin")
f = openfile(saveFilename, true)
if typeof(f)
    vTopScore = fread(f, 32)
    free file f
else
    vTopScore = 0
endif

' Generate assets.
CreateAssets()
vBgImage = createimage(256, 240)
create font 1, "courier new", 13
set font 1

TM_SetImage(vTilemapImage)
TM_SetBorder(true, true, true, false)
for i = 0 to 17  TM_SetObstacle(i, true)

do
    ' Show title screen, returns false if user wants to quit.
    if not TextScreen(vNaalaanoidTextImage, ["TOP SCORE: " + str(vTopScore, 5), "",
            "PRESS ESC TO QUIT"])  break
    level = 1
    lives = 3
    vScore = 0

    do
        ' Init level.
        BuildLevel(level)
        TextScreen(vGetReadyTextImage, ["STAGE " + str(level, 2)])
        clear vAnims
        clear vBonuses
        clear vBalls
        clear vBullets
        vFlyingTexts.Clear()
        paddleX = mousex()
        paddleY = 248
        paddleW = 40
        paddleWantedW = 40
        paddleBullets = 0
        vBalls[0] = Ball(paddleX, paddleY - 3, 0, -1)
        vBalls[0].SetCaptured(true)
        helpTimer = -1   
        do
            ' Fetch ball.
            if sizeof(vBalls)
                paddleY = max(paddleY - 1, 208)
            elseif vBricksLeft > 0
                paddleY = min(paddleY + 2, 248)
                if paddleY = 248
                    lives = lives - 1
                    if lives >= 0
                        vBalls[0] = Ball(paddleX, paddleY - 3, 0, -1)
                        vBalls[0].SetCaptured(true)
                    else
                        break
                    endif
                endif
            endif
            ' Change paddle size.
            if paddleW < paddleWantedW  paddleW = min(paddleW + 1, paddleWantedW)
            elseif paddleW > paddleWantedW  paddleW = max(paddleW - 1, paddleWantedW)
            ' Move.
            paddleX = TM_ToWorldX(min(max(mousex(), 8), 216))
            ' Launch ball or fire bullets.
            if mousebutton(0, true)
                if sizeof(vBalls) = 1 and vBalls[0].captured and paddleY < 216
                    vBalls[0].SetCaptured(false)
                    vBalls[0].SetDir((vBalls[0].X() - paddleX)/paddleW, -0.5)
                elseif paddleBullets > 0
                    paddleBullets = paddleBullets - 1
                    vBullets[sizeof(vBullets)] = Bullet(paddleX - paddleW/2 + 5, paddleY - 4)
                    vBullets[sizeof(vBullets)] = Bullet(paddleX + paddleW/2 - 5, paddleY - 4)
                    play sound vShootSound
                endif
            endif
            ' Add helping powerups every now and then if there are few bricks left.
            if vBricksLeft/vBrickCount < 0.25
                helpTimer = helpTimer - 1
                if helpTimer <= 0
                    if sizeof(vBalls) <= 2 and paddleBullets <= 0
                        helpTimer = 10*60
                        if rnd(2) = 0  AddBonus(MULTIBALL, rnd(13)*16 + 8, -8)
                        else  AddBonus(CANNONS, rnd(13)*16 + 8, -8)
                    else
                        helpTimer = 3*60
                    endif
                endif
            endif
            ' Update sprites.
            before = sizeof(vBalls)
            UpdateSprites(vBalls)
            if sizeof(vBalls) = 0 and before > 0  play sound vLifeLostSound
            UpdateSprites(vBullets)
            UpdateSprites(vBonuses)
            UpdateSprites(vAnims)
            vFlyingTexts.Update()
            ' Update captured balls and collisions with paddle.
            foreach b in vBalls
                if b.captured
                    b.SetPos(min(max(b.X(), paddleX - paddleW/2), paddleX + paddleW/2), paddleY - 3)
                elseif b.dy > 0 and b.y + 6 >= paddleY and b.y < paddleY + 8
                    x = b.x + 3;  dx = x - paddleX
                    if |dx| < paddleW/2 + 3
                        b.SetDir(dx/paddleW, -0.5)
                        play sound vPaddleSound
                    endif
                endif
            next
            ' Pick up bonuses.
            i = 0
            px = paddleX - paddleW/2
            while i < sizeof(vBonuses)
                p = vBonuses[i]
                if p.x + 16 >= px and p.x < px + paddleW and p.y + 8 >= paddleY and p.y < paddleY + 8
                    vScore = vScore + 10
                    select p.type
                    case BIG_PADDLE
                        if paddleWantedW < 80  paddleWantedW = paddleWantedW + 8
                        txt = "BIG PADDLE"
                    case SMALL_PADDLE
                        if paddleWantedW > 24 paddleWantedW = paddleWantedW - 8
                        txt = "SMALL PADDLE"
                    case SPEED_UP
                        foreach b in vBalls  b.IncSpeed()
                        txt = "SPEED UP"
                    case SPEED_DOWN
                        foreach b in vBalls  b.DecSpeed()
                        txt = "SPEED DOWN"
                    case MULTIBALL
                        foreach b in vBalls  if not b.captured
                            a = atan2(b.dy, b.dx)
                            vBalls[sizeof(vBalls)] = Ball(b.X(), b.Y(), cos(a + PI/4), sin(a + PI/4))
                            vBalls[sizeof(vBalls)] = Ball(b.X(), b.Y(), cos(a - PI/4), sin(a - PI/4))
                        endif
                        txt = "MULTIBALL"                    
                    case CANNONS
                        paddleBullets = paddleBullets + 10
                        txt = "CANNONS"
                    endsel
                    free key vBonuses, i
                    vFlyingTexts.Add(txt, 1, p.X(), p.Y(), 0.5, 2)
                    play sound vBonusSound
                else
                    i = i + 1
                endif
            wend
           
            ' Draw.
            set color 255, 255, 255
            draw image vBgImage, 0, 0
            TM_Render()
            DrawPaddle(TM_ToScreenX(paddleX), TM_ToScreenY(paddleY), paddleW, paddleBullets > 0)
            draw image vBgImage, 0, paddleY, 0, paddleY, 8, 240 - paddleY
            draw image vBgImage, 216, paddleY, 216, paddleY, 256 - 216, 240 - paddleY
            DrawSprites(vAnims)
            DrawSprites(vBalls)
            DrawSprites(vBullets)
            DrawSprites(vBonuses)
            vFlyingTexts.Draw()
            clear clip rect
            set caret 256 - 16, 0
            set color vWhiteColor;  center "STAGE"
            set color vBlueColor;  center str(level, 2)
            center
            set color vWhiteColor;  center "LIVES"
            set color vRedColor;  center max(lives, 0)
            center
            set color vWhiteColor;  center "SCORE"
            set color vYellowColor;  center str(vScore, 5)
           
            redraw
            fwait 60
        until vBricksLeft = 0 and vFlyingTexts.IsEmpty() or keydown(KEY_ESCAPE, true)
        if vBricksLeft = 0  level = level + 1
        else  break
    loop
    if lives < 0
        if vScore > vTopScore
            vTopScore = vScore
            f = createfile(saveFilename, true)
            if typeof(f)
                write file f, vScore, 32
                free file f
            endif
            TextScreen(vGameOverTextImage, ["NEW HIGH SCORE: " + str(vScore, 5)])
        else
            TextScreen(vGameOverTextImage, ["SCORE: " + str(vScore, 5)])
        endif
    endif
loop

' TextScreen
' ----------
function TextScreen(img, texts)
    set color 0, 0, 0;  cls;  redraw;  wait 500
    blinkTimer = 40
    abort = false
    do
        if keydown(KEY_ESCAPE, true)
            abort = true
            break
        endif
        if mousebutton(0, true)  break
        blinkTimer = (blinkTimer - 1)%80
        set color 0, 0, 0;  cls
        set color 255, 255, 255
        draw image img, (width(primary) - width(img))/2, height(primary)/3 - height(img)/2
        set caret width(primary)/2, height(primary)/2 - sizeof(texts)*fheight()/2
        set color vWhiteColor;  for i = 0 to sizeof(texts) - 1  center texts[i]
        center
        if blinkTimer < 40
            set caret width(primary)/2, 2*height(primary)/3 - fheight()/2
            center "CLICK TO CONTINUE ..."
        endif
        redraw
        fwait 60
    loop
    set color 0, 0, 0;  cls;  redraw;  wait 500
    return not abort
endfunc

' UpdateSprites
' -------------
function UpdateSprites(list)
    i = 0
    while i < sizeof(list)  if list[i].Update()  i = i + 1
    else  free key list, i
endfunc

' DrawSprites
' -----------
function DrawSprites(list)
    if sizeof(list)  for i = 0 to sizeof(list) - 1  list[i].Draw()
endfunc

' BuildLevel
' ----------
function BuildLevel(level)
    ' Build level from random rectangles.
    if level = 1  blobCount = 2
    else  blobCount = 3 + min(int((level - 1)*0.6), 24);  levelHeight = 16 + min(int(level/2), 6)
    randomize SEED + level
    TM_InitMap(13, levelHeight)
    TM_SetView(8, 8, 13*16, levelHeight*8)
    for i = 1 to blobCount
        bw = 1 + rnd(5);  bh = 1 + rnd(5);  bx = rnd(7);  by = 1 + rnd(levelHeight - bh - 1)
        innerCel = rnd(min(6 + 6*int((level - 1)*0.5), 18))
        outerCel = rnd(min(6 + 6*int((level)*0.5), 18))
        for y = by to by + bh - 1  for x = bx to bx + bw - 1  if x <= 6
            if x = bx or x = bx + bw - 1 or y = by or y = by + bh - 1  cel = outerCel
            else  cel = innerCel
            TM_SetCel(x, y, cel)
            if x < 6  TM_SetCel(6 + (6 - x), y, cel)
        endif
    next
    ' Count bricks and add powerups.
    vBrickCount = 0
    for y = 0 to levelHeight - 1  for x = 0 to 12  if TM_GetCel(x, y) >= 0
        vBrickCount = vBrickCount + 1
        if rnd(5) = 0  TM_SetFlag(x, y, 1 + rnd(6))
    endif
    vBricksLeft = vBrickCount
   
    ' Create background image.
    patternImage = createimage(16, 16)
    set image patternImage
    select rnd(4)
    case 0  set color vDarkRedColor
    case 1  set color vDarkGreenColor
    case 2  set color vDarkBlueColor
    case 3  set color vDarkMagentaColor
    endsel
    cls
    set color 0, 0, 0
    for i = 1 to 4
        select rnd(3)
            case 0  draw ellipse rnd(16), rnd(16), rnd(12), rnd(12), false
            case 1  draw rect rnd(16), rnd(16), rnd(12), rnd(12), false
            case 2  draw line rnd(16), rnd(16), rnd(16), rnd(16)
        endsel
    next
    set image primary
    set image vBgImage
    set color 0, 0, 0;  cls
    set color 255, 255, 255
    for y = 0 to 14  for x = 0 to 12  draw image patternImage, 8 + x*16, 8 + y*16
    free image patternImage
    set color vGrayColor
    draw rect 0, 8, 8, 232, true;  draw rect 216, 8, 8, 232, true;  draw rect 8, 0, 208, 8, true
    set clip rect 0, 0, 8, 8;  draw ellipse 8, 8, 8, 8, true
    set clip rect 216, 0, 8, 8;  draw ellipse 215, 8, 8, 8, true
    clear clip rect
    set color 0, 0, 0
    draw line 8, 7, 215, 7;  draw line 7, 8, 7, 240;  draw line 216, 8, 216, 240
    set image primary
endfunc

' Ball
' ----
function Ball(x, y, dx, dy)
    b = []
    b.SetCaptured = function(value)
        this.captured = value
    endfunc
    b.SetPos = function(x, y)
        this.x = min(max(x - 3, 0), 202)
        this.y = y - 3
    endfunc
    b.X = function();  return this.x + 3;  endfunc
    b.Y = function();  return this.y + 3;  endfunc
    b.SetDir = function(dx, dy)
        k = 1/sqr(dx*dx + dy*dy)
        this.dx = k*dx
        this.dy = k*dy
    endfunc
    b.IncSpeed = function()
        this.spd = this.spd + 0.5
        this.spdt = 0
    endfunc
    b.DecSpeed = function()
        this.spd = max(this.spd - 0.5, 1)
        if this.spd < 2  this.spdt = 60*10
    endfunc
    b.Update = function()
        if this.captured  return true
        if this.spdt > 0
            this.spdt = this.spdt - 1
            if this.spdt = 0  this.IncSpeed()
        endif
        ' Move one unit at a time for the brick hits to work better.
        move = this.spd
        res = -1
        while move > 0
            spd = min(move, 1)
            move = move - 1
            TM_MoveSprite(this, this.dx*spd, this.dy*spd)
            if TM_CollisionUp()
                ixl = floor((this.x)/16);  ixr = floor((this.x + 5)/16);  y = floor((this.y - 4)/8)
                res = max(res, HitBrick(ixl, y))
                if ixr <> ixl  res = max(res, HitBrick(ixr, y))
                this.dy = |this.dy|
            elseif TM_CollisionDown()
                ixl = floor((this.x)/16);  ixr = floor((this.x + 5)/16);  y = floor((this.y + 10)/8)
                res = max(res, HitBrick(ixl, y))
                if ixr <> ixl  res = max(res, HitBrick(ixr, y))
                this.dy = - |this.dy|
            endif
            if TM_CollisionLeft()
                iyt = floor((this.y)/8);  iyb = floor((this.y + 5)/8);  x = floor((this.x - 8)/16)
                res = max(res, HitBrick(x, iyt))
                if iyb <> iyt  res = max(res, HitBrick(x, iyb))
                this.dx = |this.dx|
            elseif TM_CollisionRight()
                iyt = floor((this.y)/8);  iyb = floor((this.y + 5)/8);  x = floor((this.x + 14)/16)
                res = max(res, HitBrick(x, iyt))
                if iyb <> iyt  res = max(res, HitBrick(x, iyb))
                this.dx = -|this.dx|
            endif
        wend
        ' Prevent ball from going too much horizontally.
        if |this.dy| < 0.1
            if this.dy < 0  this.SetDir(this.dx, -0.15)
            else  this.SetDir(this.dx, 0.15)
        endif
        'endif
        if res = 0  play sound vWallSound
        elseif res = 1  play sound vBrickHitSound
        elseif res = 2  play sound vBrickDestroyedSound
        a = atan2(this.dy, this.dx)
        return this.y < 240
    endfunc
    b.Draw = function()
        draw image vBallImage, TM_ToScreenX(this.x), TM_ToScreenY(this.y)
    endfunc
    b.captured = false
    b.r = 3
    b.w = 6
    b.h = 6
    b.spd = 2
    b.spdt = 0
    b.SetPos(x, y)
    b.SetDir(dx, dy)
   
    return b
endfunc

' Bullet
' ------
function Bullet(x, y)
    return [x: x - width(vBulletImage)/2, y: y - height(vBulletImage)/2,
            w: width(vBulletImage), h: height(vBulletImage),
            Update: function()
                TM_MoveSprite(this, 0, -4)
                if TM_CollisionUp()
                    ixl = floor(this.x/16);  ixr = floor((this.x + 4)/16)
                    iy = floor((this.y - 4)/8)
                    res = HitBrick(ixl, iy)
                    if ixr <> ixl  res = max(res, HitBrick(ixr, iy))
                    if res = 0  play sound vWallSound
                    elseif res = 1  play sound vBrickHitSound
                    elseif res = 2  play sound vBrickDestroyedSound
                    return false
                endif
                return true
            endfunc,
            Draw: function()
                draw image vBulletImage, TM_ToScreenX(this.x), TM_ToScreenY(this.y)
            endfunc]
endfunc

' AddAnim
' -------
function AddAnim(img, x, y, spd, startCel)
    vAnims[sizeof(vAnims)] = [
            img: img, cel: startCel, x: x, y: y, spd: spd,
            Update: function()
                this.cel = this.cel + this.spd
                return this.cel < cels(this.img)
            endfunc,
            Draw: function()
                draw image this.img, this.x, this.y, int(this.cel)
            endfunc]
endfunc

' HitBrick
' --------
function HitBrick(x, y)
    cel = TM_GetCel(x, y)
    if cel >= 0
        cel = cel - 6
        if cel >= 0
            TM_SetCel(x, y, cel)
            AddAnim(vBrickHitImage, 8 + x*16, 8 + y*8, 0.25, 1 - int(cel/6))
            return 1
        else
            vBricksLeft = vBricksLeft - 1
            vScore = vScore + 5
            TM_SetCel(x, y, -1)
            pu = TM_GetFlag(x, y)
            if pu > 0  AddBonus(pu, x*16 + 8, y*8 + 4)
            vFlyingTexts.Add(5, 1, x*16 + 8, y*8 + 4, 0.5, 1)
            return 2
        endif
    else
        return 0
    endif
endfunc

' AddBonus
' --------
function AddBonus(type, x, y)
    select type
        case BIG_PADDLE  img = vBigPaddleBonusImage
        case SMALL_PADDLE  img = vSmallPaddleBonusImage
        case SPEED_UP  img = vSpeedUpBonusImage
        case SPEED_DOWN  img = vSpeedDownBonusImage
        case MULTIBALL  img = vMultiballBonusImage
        case CANNONS  img = vCannonsBonusImage
        default  img = unset
    endsel
    assert img, "AddBonus: Invalid type"
    vBonuses[sizeof(vBonuses)] = [
            type: type, img: img, x: x - 8, y: y - 4, spd: 1,
            X: function();  return this.x + 8;  endfunc,
            Y: function();  return this.y + 4;  endfunc,
            Update: function()
                this.y = this.y + this.spd
                return this.y < 240
            endfunc,
            Draw: function()
                draw image this.img, TM_ToScreenX(this.x), TM_ToScreenY(this.y)
            endfunc]
endfunc

' DrawPaddle
' ----------
function DrawPaddle(x, y, w, cannons)
    x = x - int(w/2)
    draw image vPaddleImage, x, y, 0
    draw image vPaddleImage, x + w - 8, y, 2
    set clip rect x + 8, 0, w - 16, height(primary)
    for i = 1 to int(w/8) - 1  draw image vPaddleImage, x + i*8, y, 1
    clear clip rect
    if cannons
        h = height(vCannonImage)
        draw image vCannonImage, x + 2, y - h
        draw image vCannonImage, x + w - 2 - width(vCannonImage), y - h
    endif
endfunc

' CreateAssets
' ------------
function CreateAssets()
    ' Brick images.
    brickBitmap = [
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3],
            [1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
            [1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3],
            [1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
            [1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3],
            [1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1]]
    vRedBrickImage = Create3ColorImage(brickBitmap, [vRedColor, vWhiteColor, vBlackColor])
    vGreenBrickImage = Create3ColorImage(brickBitmap, [vGreenColor, vWhiteColor, vBlackColor])
    vBlueBrickImage = Create3ColorImage(brickBitmap, [vBlueColor, vWhiteColor, vBlackColor])
    vYellowBrickImage = Create3ColorImage(brickBitmap, [vYellowColor, vWhiteColor, vBlackColor])
    vMagentaBrickImage = Create3ColorImage(brickBitmap, [vMagentaColor, vWhiteColor, vBlackColor])
    vCyanBrickImage = Create3ColorImage(brickBitmap, [vCyanColor, vWhiteColor, vBlackColor])
    set image grid vRedBrickImage, 1, 3
    set image grid vGreenBrickImage, 1, 3
    set image grid vBlueBrickImage, 1, 3
    set image grid vYellowBrickImage, 1, 3
    set image grid vMagentaBrickImage, 1, 3
    set image grid vCyanBrickImage, 1, 3
    vTilemapImage = createimage(16*6, 24)
    set image vTilemapImage
    set color 255, 255, 255
    draw image vRedBrickImage, 0, 0
    draw image vGreenBrickImage, 16, 0
    draw image vBlueBrickImage, 32, 0
    draw image vYellowBrickImage, 48, 0
    draw image vMagentaBrickImage, 64, 0
    draw image vCyanBrickImage, 80, 0
    set image primary
    set image grid vTilemapImage, 6, 3
    ' Brick hit anim.
    vBrickHitImage = Create3ColorImage([
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
            [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
            [vWhiteColor, unset, unset])
    set image grid vBrickHitImage, 1, 3
    ' Paddle.
    vPaddleImage = Create3ColorImage([
            [0, 0, 2, 2, 2, 2, 2, 3,  1, 1, 1, 1, 1, 1, 1, 1,  3, 2, 2, 2, 2, 2, 0, 0],
            [0, 2, 2, 2, 2, 2, 2, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 2, 2, 2, 2, 2, 2, 0],
            [2, 2, 2, 2, 2, 2, 2, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 2, 2, 2, 2, 2, 2, 2],
            [2, 2, 2, 2, 2, 2, 2, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 2, 2, 2, 2, 2, 2, 2],
            [2, 2, 2, 2, 2, 2, 2, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 2, 2, 2, 2, 2, 2, 2],
            [3, 2, 2, 2, 2, 2, 2, 3,  1, 1, 1, 1, 1, 1, 1, 1,  3, 2, 2, 2, 2, 2, 2, 3],
            [0, 3, 2, 2, 2, 2, 2, 3,  1, 1, 1, 1, 1, 1, 1, 1,  3, 2, 2, 2, 2, 2, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3,  3, 3, 3, 3, 3, 3, 3, 3,  3, 3, 3, 3, 3, 3, 0, 0]],
            [vGrayColor, vRedColor, vBlackColor])
    set image grid vPaddleImage, 3, 1
    ' Cannon.
    vCannonImage = Create3ColorImage([
            [0, 0, 1, 1, 0, 0],
            [0, 0, 3, 3, 0, 0],
            [0, 0, 1, 1, 0, 0],
            [0, 0, 1, 1, 0, 0],
            [0, 0, 1, 1, 0, 0],
            [1, 1, 1, 1, 1, 1]],
            [vGrayColor, vWhiteColor, vBlackColor])
    ' Ball.
    vBallImage = Create3ColorImage([
            [0, 1, 1, 1, 1, 0],
            [1, 1, 2, 1, 1, 1],
            [1, 2, 2, 2, 1, 1],
            [1, 1, 2, 1, 1, 1],
            [1, 1, 1, 1, 1, 1],
            [0, 1, 1, 1, 1, 0]],
            [vGrayColor, vWhiteColor, vBlackColor])
    'Bullet.
    vBulletImage = Create3ColorImage([
            [0, 3, 3, 0],
            [3, 2, 2, 3],
            [3, 1, 1, 3],
            [3, 1, 1, 3],
            [0, 2, 2, 0],
            [0, 2, 2, 0],
            [0, 3, 3, 0]],
            [vWhiteColor, vYellowColor, vRedColor])
    ' Powerups.
    vBigPaddleBonusImage = Create3ColorImage([
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0],
            [1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1],
            [1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1],
            [1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1],
            [3, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3],
            [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0]],
            [vGreenColor, vWhiteColor, vBlackColor])
    vSmallPaddleBonusImage = Create3ColorImage([
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0],
            [1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1],
            [1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1],
            [1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1],
            [3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3],
            [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0]],
            [vRedColor, vWhiteColor, vBlackColor])
    vSpeedUpBonusImage = Create3ColorImage([
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [0, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0],
            [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [3, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 3],
            [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0]],
            [vMagentaColor, vWhiteColor, vBlackColor])
    vSpeedDownBonusImage = Create3ColorImage([
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [0, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1],
            [3, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 3],
            [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0]],
            [vYellowColor, vWhiteColor, vBlackColor])
    vMultiballBonusImage = Create3ColorImage([
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [0, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 0],
            [1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1],
            [1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1],
            [1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1],
            [3, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 3],
            [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0]],
            [vCyanColor, vWhiteColor, vBlackColor])
    vCannonsBonusImage = Create3ColorImage([
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
            [0, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0],
            [1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1],
            [1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
            [3, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3],
            [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0],
            [0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0]],
            [vBlueColor, vWhiteColor, vBlackColor])
    ' Cool texts.
    vNaalaanoidTextImage = CreateCoolText("NAALAANOID", 3, vWhiteColor, vBlueColor)
    vGetReadyTextImage = CreateCoolText("GET READY!", 2, vWhiteColor, vDarkGreenColor)
    vGameOverTextImage = CreateCoolText("GAME OVER!", 2, vWhiteColor, vRedColor)
    ' Sound effects (stealing from the example breakout3d.n7).
    sfx = SFX()
    vPaddleSound = sfx.SineWave(0.15, [350], [0.5, 0])
    vBrickHitSound = sfx.SquareWave(0.1, [800], [0.15, 0, 0])
    vBrickDestroyedSound = sfx.SquareWave(0.15, [500], [0.5, 0, 0])
    vWallSound = sfx.Noise(0.15, [100, 1000], [0.25, 0])
    vLifeLostSound = sfx.Noise(0.54, [1000, 5000], [0.75, 0])
    vBonusSound = sfx.SineWave(0.25, [500, 1500], [0.5, 0])
    vShootSound = sfx.SineWave(0.15, [1000, 2000, 1000], [0.4, 0])
endfunc

' Create3ColorImage
' -----------------
function Create3ColorImage(data, colors)
    img = createimage(sizeof(data[0]), sizeof(data))
    set image img
    for y = 0 to sizeof(data) - 1  for x = 0 to sizeof(data[0]) - 1
        if data[y][x] > 0  set color colors[data[y][x] - 1]
        else  set color 0, 0, 0, 0
        set pixel x, y
    next
    set image primary
    return img
endfunc

' CreateCoolText
' --------------
function CreateCoolText(txt, size, borderColor, fillColor)
    w = fwidth(txt);  h = fheight()
    tmp = createimage(w, h)
    set image tmp
    set caret 0, 0;  set color 255, 255, 255;  write txt
    set image primary
    res = createimage(w*size + 2, h*size + 2)
    set image res
    set color 0, 0, 0, 0;  for y = 0 to height(res) - 1  for x = 0 to width(res) - 1  set pixel x, y
    for y = 0 to h - 1  for x = 0 to w - 1  if pixeli(tmp, x, y)%256
        t = pixeli(tmp, x, y - 1)%256;  b = pixeli(tmp, x, y + 1)%256
        l = pixeli(tmp, x - 1, y)%256;  r = pixeli(tmp, x + 1, y)%256
        set color fillColor;  draw rect x*size, y*size, size, size, true
        set color borderColor
        if not t  draw line x*size, y*size - 1, x*size + size - 1, y*size - 1
        if not b  draw line x*size, y*size + size, x*size + size - 1, y*size + size
        if not l  draw line x*size - 1, y*size, x*size - 1, y*size + size - 1
        if not r  draw line x*size + size, y*size, x*size + size, y*size + size - 1
    endif
    set image primary
    free image tmp
    return res
endfunc

' FlyingTexts
' -----------
' Encapsulate flying texts.
function FlyingTexts(maxTexts)
    ft = []
    ft.texts = fill(
        [txt: unset,
        fnt: unset,
        x: 0,
        y: 0,
        spd: 0],
        maxTexts)
   
    ft.empty = true
    ' Clear
    ' -----
    ft.Clear = function()
        foreach t in this.texts  t.txt = unset
    endfunc
   
    ' IsEmpty
    ' -------
    ft.IsEmpty = function()
        return .empty
    endfunc
   
    ' Add
    ' ---
    ft.Add = function(txt, fnt, x, y, spd, duration)
        foreach t in this.texts  if not t.txt
            t.txt = txt
            t.fnt = fnt
            t.x = x
            t.y = y - fheight(fnt)/2
            t.spd = spd
            t.t = 60*duration
            break
        endif
    endfunc
   
    ' Update
    ' ------
    ft.Update = function()
        .empty = true
        foreach t in this.texts  if t.txt
            .empty = false
            t.t = t.t - 1
            if t.t > 0
                t.y = t.y - t.spd
            else
                t.txt = unset
            endif
        endif
    endfunc
   
    ' Draw
    ' ----
    ft.Draw = function()
        foreach t in this.texts  if t.txt
            set font t.fnt
            set caret TM_ToScreenX(t.x), TM_ToScreenY(t.y)
            center t.txt
        endif
    endfunc
   
    return ft
endfunc

Print this item

  Bridge (simple physics)
Posted by: 1micha.elok - 03-16-2025, 09:51 AM - Forum: NaaLaa 7 Code - Replies (3)

BRIDGE
A demo of simple physics

       
click the images to zoom in
How It Works
1. The circle falls due to gravity and collides with the bridge.
2. Upon collision, the circle applies a downward force to the bridge segment it lands on, proportional to its mass.
3. Springs pull the displaced segments back toward their rest positions, creating a bending effect
4. When the ball stops moving, increased damping stabilizes the bridge, preventing further vibrations

Code:
'=================================
'
'  BRIDGE
'  A demo of simple physics
'
'=================================

#win32
set window "bridge",800, 600,false 
set redraw off

' Gravity value
visible gravity = 0.5                      

' Parameters for the bridge
visible bridge  = []
bridge.segments = 15                     ' number of segments in the bridge
bridge.swidth   = 40                     ' width of each segment
bridge.sheight  = 10                     ' height of each segment
bridge.gap      = 5                      ' gap between segments
bridge.y        = height()/2             ' vertical position of the bridge

' Calculate total width of the bridge
bridge.total    = bridge.segments * bridge.swidth + (bridge.segments - 1) * bridge.gap

' Calculate starting x-coordinate to center the bridge horizontally
bridge.start    = (width() - bridge.total) / 2

' Bridge segment position
bridge.xs       = []
bridge.ys       = []
bridge.vy       = []
bridge.rest     = []                      ' Rest position of each segment 
bridge.spring   = []                      ' Spring elasticity

' Initialize bridge segments
for i = 0 to bridge.segments - 1
    bridge.xs[i]    = bridge.start + i * (bridge.swidth + bridge.gap)
    bridge.ys[i]    = bridge.y
    bridge.rest[i]  = bridge.y 
    bridge.vy[i]    = 0
    bridge.spring[i]= 0.1  
next

' Parameters for the falling circle
visible circle = []
circle.radius       = 15                        ' Radius of the circle
circle.x            = width()/2                 ' Initial x position of the circle
circle.y            = bridge.y-circle.radius    ' Initial y position of the circle
circle.vx           = 0                         ' Horizontal velocity
circle.vy           = 0                         ' Vertical velocity
circle.mass         = 0                    
circle.bounce       = 0.7                       ' Energy loss on collision
circle.velocity     = 0.1   

' Function to update the circle's position
function update_circle()
    ' Apply gravity to the vertical velocity
    circle.vy = circle.vy + gravity
   
    ' Update the circle's position based on velocity
    circle.x = circle.x + circle.vx
    circle.y = circle.y + circle.vy
   
endfunc

' Function to handle collisions between the circle and the bridge
function handle_collisions()
    for i = 0 to bridge.segments - 1
        ' Check if the circle overlaps with the current bridge segment
        if circle.x + circle.radius > bridge.xs[i] and
        circle.x - circle.radius < bridge.xs[i] + bridge.swidth and
           circle.y + circle.radius > bridge.ys[i] and
           circle.y - circle.radius < bridge.ys[i] + bridge.sheight then
            ' Collision detected: Reposition the circle and apply force to the bridge segment
            overlap = (circle.y + circle.radius) - bridge.ys[i]
            circle.y = bridge.ys[i] - circle.radius  ' Reposition the circle above the bridge
           
            ' Reverse and dampen vertical velocity
            circle.vy = circle.vy * -circle.bounce
           
            ' Stop bouncing if velocity is below the threshold
            if abs(circle.vy) < circle.velocity then
                circle.vy = 0
            endif
           
            ' Apply downward force to the bridge segment based on the circle's mass
            bridge.vy[i] = bridge.vy[i] + overlap * circle.mass * 0.01
        endif
    next
endfunc

' Simulate spring forces between bridge segments
function simulate_springs()
    for i = 1 to bridge.segments - 1
        ' Calculate displacement from rest position
        dy = bridge.ys[i] - bridge.rest[i]
       
        ' Apply spring force to pull the segment back to its rest position
        bridge.vy[i] = bridge.vy[i] - dy * bridge.spring[i]
    next
   
    ' Apply spring forces between adjacent segments
    for i = 1 to bridge.segments - 1
        ' Calculate displacement between adjacent segments
        dy = bridge.ys[i] - bridge.ys[i - 1]
        force = dy * bridge.spring[i]
       
        ' Apply spring force
        bridge.vy[i] = bridge.vy[i] - force
        bridge.vy[i - 1] = bridge.vy[i - 1] + force
    next   
   
endfunc

' Update bridge positions
function update_bridge()
    for i = 0 to bridge.segments - 1
        ' If the ball has stopped moving, increase damping to stabilize the bridge
        if abs(circle.vy) < circle.velocity then
           bridge.vy[i] = 0  ' Stronger damping when the ball stops
        else
            bridge.vy[i] = bridge.vy[i] * 0.99  ' Normal damping during movement
        endif       
       
        bridge.ys[i] = bridge.ys[i] + bridge.vy[i]
       
        ' Prevent the bridge from bending too far downward
        if bridge.ys[i] > bridge.rest[i] + 50 then
            bridge.ys[i] = bridge.rest[i] + 50
            bridge.vy[i] = 0
        endif
       
        ' Ensure the bridge doesn't go above its rest position
        if bridge.ys[i] < bridge.rest[i] then
            bridge.ys[i] = bridge.rest[i]
            bridge.vy[i] = 0
        endif
    next
endfunc


' Render the bridge and the circle
function render_scene()
    'clear screen
    set color 0,0,0;cls
   
    'white
    set color 255,255,255
   
    ' Draw the bridge
    for i = 0 to bridge.segments - 1
        draw rect bridge.xs[i], bridge.ys[i], bridge.swidth, bridge.sheight
    next
   
    ' Draw the circle
    draw ellipse circle.x, circle.y, circle.radius, circle.radius
endfunc


'--------------
' Main Loop
'--------------
while not keydown(KEY_ESCAPE,true)
    update_circle()      ' Update the circle's position
    handle_collisions()  ' Handle collisions with the bridge
    simulate_springs()
    update_bridge()
    render_scene()       ' Render the scene
   
    'control keys
    if keydown(KEY_1,true) then
        circle.mass = 10
        circle.y    = -50
    endif
    if keydown(KEY_2,true) then
        circle.mass = 150
        circle.y    = -50
    endif
    set caret 10, bridge.y+100
    set color 255,255,255
    wln "Simple Physics"
    wln "================================================"
    wln
    wln "Please watch how the bridge reacts to the circle"
    wln
    wln "Press Key 1 : weight = 10  (light)"
    wln "Press Key 2 : weight = 150 (heavy)"
    wln
    wln "Circle Mass = "+circle.mass
    wln

   
    fwait 10          
    redraw
wend

Print this item

  Primitive Angry Bird
Posted by: 1micha.elok - 03-13-2025, 03:45 AM - Forum: NaaLaa 7 Code - Replies (8)

       
click the images to zoom in

Code:
'====================================
' Primitive Angry Bird
' It's just a demo of simple physics
'
'
'====================================

' Screen dimensions
set window "Primitive Angry Bird", 1000, 600,false
set redraw off

'color definition
black       = [0,0,0]
white       = [255,255,255]
green       = [0,100,0]
lightgreen  = [0,255,0]
brown       = [255,100,10]
gray        = [100,100,100]
red         = [255,0,0]

' Gravity, Friction, Ground
gravity     = 0.1   
friction    = 0.99   ' Friction to slow down movement
groundLevel = 350   

' Bird,Pig,Boxes
visible bird        = []
visible pig         = []
visible boxes       = [] 
Initialize(groundLevel)

' Mouse
startX      = 0 
startY      = 0


'----------------
' Main game loop
'----------------
while not keydown(KEY_ESCAPE,true)
    ' clear screen
    set color black
    cls
   
    ' info box
    set color white
    set caret 10,420
    wln "--------------------"
    wln "Primitive Angry Bird"
    wln "--------------------"
    wln
    wln "Drag the red cirle by pressing your left mouse button"
    wln "Then hit the green circle !"
    wln
    wln "Control Keys :"
    wln "- SPACE BAR    = restart"
    wln "- ESCAPE       = quit"
   
    ' Draw ground
    set color green
    draw rect 0, groundLevel, 1000, 50,true
    set color white
    draw rect 0, groundLevel, 1000, 50
   
    ' Draw bird
    set color red
    draw ellipse bird.x, bird.y, bird.size,bird.size,true
    set color white
    draw ellipse bird.x, bird.y, bird.size,bird.size
   
    ' Draw pig
    set color lightgreen
    draw ellipse pig.x, pig.y, pig.size, pig.size,true
    set color white
    draw ellipse pig.x, pig.y, pig.size, pig.size
   
    ' Draw boxes
    for i = 0 to 2
        set color brown
        draw rect boxes[i].x, boxes[i].y, boxes.size, boxes.size, true
        set color white 
        draw rect boxes[i].x, boxes[i].y, boxes.size, boxes.size
    next
   
    ' Handle mouse input
    if not mousebutton(0) then
        ' Start dragging
        startX = mousex()
        startY = mousey()
    else
        ' Show trajectory line while dragging
        set color gray
        draw line bird.x, bird.y, mousex(), mousey()
       
        ' Release bird and calculate velocity
        bird.vx = (startX - mousex()) / 10
        bird.vy = (startY - mousey()) / 10       
    endif
   
    'Handle keyboard input to restart the game
    if keydown(KEY_SPACE,true) then Initialize(groundLevel)
           
    ' Update bird position
    ' Apply gravity
    bird.vy = bird.vy + gravity
       
    ' Update position
    bird.x = bird.x + bird.vx
    bird.y = bird.y + bird.vy
       
    ' Apply friction
    bird.vx = bird.vx * friction
    bird.vy = bird.vy * friction
       
    ' Check for ground collision
    if bird.y >= groundLevel - bird.size then
        bird.y = groundLevel - bird.size
        bird.vy = -bird.vy * 0.7  ' Bounce with reduced energy
    endif
       
    ' Check for pig collision
    distance = ((bird.x - pig.x)^2 + (bird.y - pig.y)^2)^0.5
    if distance <= bird.size + pig.size then
        pig.vx = bird.vx * 0.5  ' Transfer some velocity to the pig
        pig.vy = bird.vy * 0.5
        pig.hit = true
           
        ' Update position
        bird.x = width()+500
    endif
       
    ' Check for boxes and bird collisions
    for i = 0 to 2
        if bird.x + bird.size > boxes[i].x and bird.x - bird.size < boxes[i].x + boxes.size and
            bird.y + bird.size > boxes[i].y and bird.y - bird.size < boxes[i].y + boxes.size then
           
            ' Resolve overlap by moving bird away from box
            dx = bird.x - (boxes[i].x + boxes.size / 2)
            dy = bird.y - (boxes[i].y + boxes.size / 2)
            distance = (dx^2 + dy^2)^0.5
           
            if distance < bird.size + boxes.size / 2 then
                    ' Move bird away from box
                    overlap = (bird.size + boxes.size / 2) - distance
                    bird.x = bird.x + (dx / distance) * overlap
                    bird.y = bird.y + (dy / distance) * overlap
                   
                    ' Transfer velocity between bird and box
                    tempVx = bird.vx
                    tempVy = bird.vy
                    bird.vx = boxes[i].vx * 0.5
                    bird.vy = boxes[i].vy * 0.5
                    boxes[i].vx = tempVx * 0.5
                    boxes[i].vy = tempVy * 0.5
            endif
            boxes.hit = true
        endif
    next 
   
    if boxes.hit or pig.hit then
        ' Update pig position
        pig.y = pig.y + pig.vy
        pig.x = pig.x + pig.vx
       
        ' Apply gravity to pig
        pig.vy = pig.vy + gravity
    endif
   
    ' Check for ground collision for pig
    if pig.y >= groundLevel - pig.size then
        pig.y = groundLevel - pig.size
        pig.vy = -pig.vy * 0.5  ' Bounce with reduced energy
        pig.vx = -pig.vx * 0.5
    endif
   
    ' Update box positions
    if boxes.hit then
        for i = 0 to 2
            boxes[i].y = boxes[i].y + boxes[i].vy
            boxes[i].x = boxes[i].x + boxes[i].vx
           
            ' Apply gravity to boxes
            boxes[i].vy = boxes[i].vy + gravity
           
            ' Check for ground collision for boxes
            if boxes[i].y >= groundLevel - boxes.size then
                boxes[i].y = groundLevel - boxes.size
                boxes[i].vy = -boxes[i].vy * 0.01  ' Bounce with reduced energy
                boxes[i].vx = -boxes[i].vx * 0.01
            endif
        next
    endif
   
    'Check for collisions between boxes
    for i = 0 to 2
        for j = 0 to 2
            ' Check if boxes overlap
            if boxes[i].x < boxes[j].x + boxes.size and boxes[i].x + boxes.size > boxes[j].x and
               boxes[i].y < boxes[j].y + boxes.size and boxes[i].y + boxes.size > boxes[j].y then
               
                ' Resolve overlap by moving boxes apart
                dx = boxes[j].x - boxes[i].x
                dy = boxes[j].y - boxes[i].y
                overlapX = boxes.size - abs(dx)
                overlapY = boxes.size - abs(dy)
               
                if overlapX < overlapY then
                    ' Resolve horizontally
                    if dx < 0 then
                        boxes[i].x = boxes[i].x - overlapX+rnd(2,6)
                        boxes[j].x = boxes[j].x + overlapX+rnd(2,6)
                    else
                        boxes[i].x = boxes[i].x + overlapX+rnd(2,6)
                        boxes[j].x = boxes[j].x - overlapX+rnd(2,6)
                    endif
                else
                    ' Resolve vertically
                    if dy < 0 then
                        boxes[i].y = boxes[i].y - overlapY
                        boxes[j].y = boxes[j].y + overlapY
                    else
                        boxes[i].y = boxes[i].y + overlapY
                        boxes[j].y = boxes[j].y - overlapY
                    endif
                endif
            endif
        next
    next
   
    'Check for collisions between pig and boxes
    for i = 0 to 2
        'Check if pig overlaps with box
        if pig.x + pig.size > boxes[i].x and pig.x - pig.size < boxes[i].x + boxes.size and
           pig.y + pig.size > boxes[i].y and pig.y - pig.size < boxes[i].y + boxes.size then
            ' Resolve overlap
            dx = (pig.x - (boxes[i].x + boxes.size / 2))
            dy = (pig.y - (boxes[i].y + boxes.size / 2))
            distance = (dx^2 + dy^2)^0.5
           
            if distance < pig.size + boxes.size / 2 then
                ' Move pig away from box
                overlap = (pig.size + boxes.size / 2) - distance
                pig.x = pig.x + (dx / distance) * overlap
                pig.y = pig.y + (dy / distance) * overlap
               
                ' Transfer velocity between pig and box
                tempVx = pig.vx
                tempVy = pig.vy
                pig.vy = boxes[i].vx * 0.5
                pig.vy = boxes[i].vy * 0.5
                boxes[i].vx = tempVx * 0.5
                boxes[i].vy = tempVy * 0.5
            endif
        endif
    next
   
    ' Reset bird if it goes off-screen
    if bird.x < 0 or bird.x > width() or bird.y > height() or bird.y < 0 then
        bird.x = 100
        bird.y = groundLevel - bird.size
        bird.vx = 0
        bird.vy = 0
    endif
   
    ' Refresh screen
    fwait 60
    redraw
wend


'----------
' FUNCTION
'----------
function Initialize(groundLevel)
    ' Bird properties
    bird.size   = 10                       
    bird.x      = 100                       
    bird.y      = groundLevel - bird.size   
    bird.vx     = 0                         ' Horizontal velocity
    bird.vy     = 0                         ' Vertical velocity
   
    ' Pig properties
    pig.size    = 15                                   
    pig.x       = 700                                   ' Pig's x position
    pig.y       = groundLevel - pig.size - 3 * 30       ' Pig's y position (on top of boxes)
    pig.vx      = 0                                     ' Pig's horizontal velocity
    pig.vy      = 0                                     ' Pig's vertical velocity
    pig.hit     = false
   
    ' Box properties (stack of 3 boxes)
    boxes.size     = 30                                 ' Size of each box (width and height)   
    for i = 0 to 2
        boxes[i] = []
        boxes[i].x = pig.x-pig.size                      ' Staggered x positions
        boxes[i].y = groundLevel - (i + 1) * boxes.size  ' Stacked y positions
        boxes[i].vx = 0                                  ' Horizontal velocity
        boxes[i].vy = 0                                  ' Vertical velocity
    next
    boxes.hit = false
endfunc

Print this item

  3d text
Posted by: Marcus - 03-08-2025, 12:05 PM - Forum: NaaLaa 7 Code - Replies (2)

Johnno posted an old screensaver effect, so I'm doing the same Smile

It's a voxel text based on the pixels of a string printed with the default naalaa font.


Code:
' 3dtext.n7
' ---------

include "s3d.n7"

res = 480

set window "3D Text", res*min(screenw()/screenh(), 2), res, true
set redraw off

S3D_SetView(primary, rad(90), 0.1, 50)

mesh = Create3DText("NaaLaa VII", 4, 255, 255, 255, 64, 64, 96)

a = 0
while not keydown(KEY_ESCAPE)
    ay = (ay + 1)%360
    ax = (ax + 0.55)%360
   
    set color 0, 0, 0, 64
    cls
    S3D_Clear()
    S3D_Translate(0, 0, 4.5)
    S3D_Scale(0.1, 0.1, 0.1)
    S3D_RotateY(sin(rad(ay))*rad(65))
    S3D_RotateX(sin(rad(ax))*rad(22.5))
    S3D_RotateZ(sin(rad(ax*2))*rad(22.5))
    S3D_Mesh(mesh, 0)
    redraw
    fwait 60
wend

' Create3DText
' ------------
function Create3DText(txt, thickness, rtop, gtop, btop, rbtm, gbtm, bbtm)
    tex = createimage(64, 1)
    set image tex
    for x = 0 to width(tex) - 1
        p = x/width(tex)
        set color rtop*(1 - p) + rbtm*p, gtop*(1 - p) + gbtm*p, btop*(1 - p) + bbtm*p
        set pixel x, 0
    next
    set image primary
    w = fwidth(txt)
    h = fheight()
    tmpImage = createimage(w, h)
    set image tmpImage
    set color 255, 255, 255
    set caret 0, 0
    write txt
    set image primary
    maxy = 0
    for y = 0 to height(tmpImage) - 1  for x = 0 to width(tmpImage) - 1
        if Red(pixeli(tmpImage, x, y)) maxy = max(maxy, y)
    next
    mesh = S3D_BeginMesh()
    S3D_Begin(S3D_QUADS)
    S3D_Texture(tex)
    ht = thickness/2
    for y = 0 to height(tmpImage) - 1  for x = 0 to width(tmpImage) - 1
        if Red(pixeli(tmpImage, x, y))
            t = Red(pixeli(tmpImage, x, y - 1))
            b = Red(pixeli(tmpImage, x, y + 1))
            l = Red(pixeli(tmpImage, x - 1, y))
            r = Red(pixeli(tmpImage, x + 1, y))
            vx = x - w/2; vy = y - h/2
            tt = y/maxy; tb = (y + 1)/maxy
            S3D_Color(160, 160, 160)
            S3D_Vertex(vx, vy, -ht, tt, 0)
            S3D_Vertex(vx + 1, vy, -ht, tt, 0)
            S3D_Vertex(vx + 1, vy + 1, -ht, tb, 0)
            S3D_Vertex(vx, vy + 1, -ht, tb, 0)
            if not t
                S3D_Color(255, 255, 255)
                S3D_Vertex(vx, vy, ht, tt, 0)
                S3D_Vertex(vx + 1, vy, ht, tt, 0)
                S3D_Vertex(vx + 1, vy, -ht, tt, 0)
                S3D_Vertex(vx, vy, -ht, tt, 0)
            endif
            if not b
                S3D_Color(64, 64, 64)
                S3D_Vertex(vx, vy + 1, ht, tb, 0)
                S3D_Vertex(vx, vy + 1, -ht, tb, 0)
                S3D_Vertex(vx + 1, vy + 1, -ht, tb, 0)
                S3D_Vertex(vx + 1, vy + 1, ht, tb, 0)
            endif
            if not l
                S3D_Color(255, 255, 255)
                S3D_Vertex(vx, vy, ht, tt, 0)
                S3D_Vertex(vx, vy, -ht, tt, 0)
                S3D_Vertex(vx, vy + 1, -ht, tb, 0)
                S3D_Vertex(vx, vy + 1, ht, tb, 0)
            endif
            if not r
                S3D_Color(64, 64, 64)
                S3D_Vertex(vx + 1, vy, ht, tt, 0)
                S3D_Vertex(vx + 1, vy + 1, ht, tb, 0)
                S3D_Vertex(vx + 1, vy + 1, -ht, tb, 0)
                S3D_Vertex(vx + 1, vy, -ht, tt, 0)
            endif
        endif
    next
    S3D_End()
    S3D_EndMesh()
    free image tmpImage
    return mesh
endfunc

' Pixeli helpers.
function Alpha(c); return int(c/16777216); endfunc
function Red(c); return int((c/65536))%256; endfunc
function Green(c); return int((c/256))%256; endfunc
function Blue(c); return c%256; endfunc

Print this item

  Mystify
Posted by: johnno56 - 03-07-2025, 10:54 PM - Forum: NaaLaa 6 Code - Replies (2)

As well as the N7 version... Let's not forget about its younger cousin... N6

J


.zip   mystify.nala.zip (Size: 798 bytes / Downloads: 5)

Print this item

  Mystify
Posted by: johnno56 - 03-07-2025, 01:30 PM - Forum: NaaLaa 7 Code - Replies (7)

Cast your minds back to early Windows days (Win95) and the almost hypnotic Mystify screen saver....

Messing around with a Javascript tutorial to recreate Mystify and figured I might see if N7 could do the same.

I have included the HTML and Javascript files (for comparison) as well as my version for N7...

Feel free to tinker....

J


.zip   mystify.zip (Size: 1.59 KB / Downloads: 8)

Print this item

  Tree
Posted by: 1micha.elok - 03-04-2025, 09:36 AM - Forum: NaaLaa 7 Code - Replies (5)

           
click the image to zoom in

Code:
'---------------------------------------------------------------------
'Tree V2
'
'Steps :
'1.Draw the trunk
'2.At the end of the trunk, split by some angle and draw some branches
'3.Repeat at the end of each branch
'
'REFERENCE
'https://rosettacode.org/wiki/Fractal_tree
'---------------------------------------------------------------------

#win32
set window "Tree V2",600*screenw()/screenh(),600,false
set redraw off

'color definition
green = [0,255,0]
black = [0,0,0]


'---------------
' MAIN PROGRAM
'---------------
counter = 0
do
    'clear screen
    set color black ; cls
    set color green
   
    'Tree(x1, y1, angle, level,enlarge)
    Tree(width()/2, height()-50, 270, 7,18)
   
    set caret 10,10
    wln "Info Box"
    wln "========================"
    wln "Press RETURN to continue"
    wln "Press ESCAPE to exit"
    wln
    wln counter
    counter = counter + 1
     
    redraw
   
    'pause
    do;wait 1;if keydown(KEY_ESCAPE,true) end;until keydown(KEY_RETURN,true)
loop


'-----------
' FUNCTIONS
'-----------
function Tree(x1, y1, angle, level,enlarge)   
    if level > 0 then
        x2 = x1 + cos(rad(angle)) * level * enlarge + rnd(3,4)
        y2 = y1 + sin(rad(angle)) * level * enlarge + rnd(3,4)
       
        'draw trunk/branch
        trunk(x1,y1,x2,y2,level)
       
        'split branch
        if rnd(0,1) then Tree(x2, y2, angle - rnd(15,48), level - 1,enlarge)
        Tree(x2, y2, angle + rnd(15,48), level - 1,enlarge)
        if rnd(0,1) then Tree(x2, y2, angle, level-1, enlarge)
        if rnd(0,1) then Tree(x2, y2, angle + rnd(10,30), level-1, enlarge)
    endif
endfunc


function trunk(x1,y1,x2,y2,t)
    'reduce thickness
    t = t/1.1

    for x = x1 to x2 step 0.01
        'equation of a line passing through 2 points
        y = (y2-y1)/(x2-x1)*(x-x1)+y1
        draw ellipse x,y,t,t,true                         
    next
endfunc

Print this item

  syntax help / example
Posted by: 1micha.elok - 02-26-2025, 02:35 PM - Forum: NaaLaa 7 Code - Replies (3)

           
click the image to zoom in

Code:
'====================================================================
'HELPME.N7
'- An attempt to make a simple syntax help/example
'- Run on windows system
'- Console mode only
'
'INSTRUCTIONS
'- Place this file in the same folder as NED.EXE
'- Compile and Run helpme.n7
'- Examples
'  Help me : abs[ENTER]        to see the example of absolute value
'  Help me : ex3_loops[ENTER]  to see the example of using loops
'  Help me : dir help[ENTER]   to see functions/commands in examples\help
'  Help me : dir basic[ENTER]  to see functions/commands in examples\basic
'  Help me : exit[ENTER]       to exit this HELPME.N7
'====================================================================

include "file.n7"

path = []

'Main Loop
do
    write "Help me : ";temp=rln()
    if lower(temp) = "exit" then end
    if lower(temp) = "dir help" then system "dir examples\help\*.n7 /w"
    if lower(temp) = "dir basic" then system "dir examples\basic\*.n7 /w"
   
    path[1] = "examples/help/"+temp+".n7"
    path[2] = "examples/basic/"+temp+".n7"
   
    if ReadAllText(path[1])=unset and ReadAllText(path[2])=unset and
        temp<>"dir help" and temp<>"dir basic" then
        pln "Not found"
    elseif temp <> "dir"
        pln
        if ReadAllText(path[1])<>unset then
            pln ReadAllText(path[1])
        else
            pln ReadAllText(path[2])
        endif
    endif
   
    pln "--------------------------------------"
    system "pause"
    system "cls"
loop

Print this item

  Color Wheel
Posted by: 1micha.elok - 02-26-2025, 01:13 AM - Forum: NaaLaa 7 Code - Replies (6)

   
click the image to zoom in

Code:
'color wheel
'converted to N7
'https://rosettacode.org/wiki/Color_wheel#Go

#win32
set window "Color Wheel",500,500,false
set redraw off

visible tau = 2 * PI
visible r,g,b

'--------------
' main program
'--------------
set color 0,0,0; cls
colorWheel()
redraw
while not keydown(KEY_ESCAPE) fwait 60

'-----------
' functions
'------------
function hsb2rgb(hue, sat, bri)
    'convert hue,saturation,brightness to RGB value
    u = int(bri*255 + 0.5)
    if sat = 0 then
        r = u
        g = u
        b = u
    else
        h = (hue - floor(hue)) * 6
        f = h - floor(h)
        p = int(bri*(1-sat)*255 + 0.5)
        q = int(bri*(1-sat*f)*255 + 0.5)
        t = int(bri*(1-sat*(1-f))*255 + 0.5)
       
        select int(h)
        case 0
            r = u; g = t; b = p
        case 1
            r = q; g = u; b = p
        case 2
            r = p ; g = u ; b = t
        case 3
            r = p ; g = q ; b = u
        case 4
            r = t ; g = p ; b = u
        case 5
            r = u ; g = p ; b = q
        endsel
       
    endif
endfunc

function colorWheel()
    'calculate center and radius
    centerX = width()/2
    centerY = height()/2
    radius = centerX-20
    if centerY < radius then
        radius = centerY-20
    endif
   
    'draw pixels for each RGB value
    for y = 0 to height()
        dy = (y - centerY)
        for x = 0 to width()
            dx = (x - centerX)
            dist = sqr(dx*dx + dy*dy)
            if dist <= radius then
                theta = atan2(dy, dx)
                hue = (theta + PI) / tau
                hsb2rgb(hue, 1, 1)
               
                set color r,g,b
                set pixel x,y
            endif
        next
    next
   
endfunc

Print this item