Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help with isometric game example please
#1
Hi, I'm sure that i remember an excellent isometric game example being posted here, showing a knight (I think), moving between various isometric rooms. I think it was written by Marcus, but I can't find it anywhere? Does anyone have it please, or can anyone point me in the right direction to find it? 
Many thanks - Kevin.
Reply
#2
I'm afraid that example is long gone, it was on the old forum.

Going for Pac-mania this time? Big Grin

https://youtu.be/4Rzfco6rpy0?si=ajJy54dt7oPjqCQV
Reply
#3
Thanks Marcus, I was afraid of that, as I couldn't find anything searching the current website.
No worries, I have got the isometric view rendering working today, but would have been interesting to see the code in the example.
I'm actually looking at a Zaxxon type shootemup, but no idea if anything will come of it......
Reply
#4
Nice, and good luck! A while ago I was thinking about making something zaxxon-like but using s3d. I wanted to make a 3d space shootemup before returning to 2d. But I went for Star Fox instead. I was also wondering if it would be possible to make something defender like but in 3d, an infinite but repeating scroll over a landscape based on a heightmap.
Reply
#5
(09-25-2025, 07:06 PM)kevin Wrote: Hi, I'm sure that i remember an excellent isometric game example being posted here, showing a knight (I think), moving between various isometric rooms. I think it was written by Marcus, but I can't find it anywhere? Does anyone have it please, or can anyone point me in the right direction to find it? 
Many thanks - Kevin.

Code:
rem ========================================================
rem Isometric test, from retrogamecoding.org.
rem
rem All the code presented here is the mix of a potential
rem library for isometric games.
rem
rem By Marcus.
rem ========================================================


import "Speed.lib"
import "Keycodes.lib"
import "Math.lib"

constant:
    rem Reserved images.
    ISO_TILES_IMAGE        325734
    ISO_BLOCK_IMAGE_BASE    325735

    ISO_MAX_SPRITES            100
    ISO_BUCKET_SIZE            8

    LEFT        12
    RIGHT        0
    DOWN        4
    UP            8

visible:
    iso_MapW
    iso_MapH
    iso_Floor[][]
    iso_Blocks[][]
    iso_Buckets[][][]
    iso_SpriteCount
    iso_Sprites?[ISO_MAX_SPRITES]
    iso_TileW
    iso_TileH
    iso_BaseX
    iso_BaseY
    iso_BlockImages
    iso_BlockHeights[]
    iso_Factor#

    iso_Steps[][]
    
    markX
    markY
hidden:

set window 32, 32, 320, 240, false, 2
set redraw off

if not ISO_LoadMap("Isometric_assets/map.txt") then end

load image 0, "Isometric_assets/marker.bmp"
set image colorkey 0, true

load image 1, "Isometric_assets/player.bmp"
set image colorkey 1, true
set image grid 1, 4, 4

player?
player.tx = 2
player.ty = 2
player.x# = float(player.tx) + 0.5
player.y# = float(player.ty) + 0.5
player.dir = LEFT
player.movep# = -1.0

proc ISO_SetSprite 0, 1, LEFT, player.x#, player.y#, 0, 5

steps = 0
step = 0
stepTimer = 0
movingByPath = false
path[16][2]

frame = 0
frameTimer = 0
do
    if player.movep# < 0.0
        if keydown(VK_LEFT)
            if player.dir = LEFT and player.tx > 0 and iso_Blocks[player.tx - 1][player.ty] < 0
                player.movep# = 0.0
            else
                player.dir = LEFT
            endif
        elseif keydown(VK_RIGHT)
            if player.dir = RIGHT and player.tx < iso_MapW - 1 and iso_Blocks[player.tx + 1][player.ty] < 0
                player.movep# = 0.0
            else
                player.dir = RIGHT
            endif
        elseif keydown(VK_UP)
            if player.dir = UP and player.ty > 0 and iso_Blocks[player.tx][player.ty - 1] < 0
                player.movep# = 0.0
            else
                player.dir = UP
            endif
        elseif keydown(VK_DOWN)
            if player.dir = DOWN and player.ty < iso_MapH - 1 and iso_Blocks[player.tx][player.ty + 1] < 0
                player.movep# = 0.0
            else
                player.dir = DOWN
            endif
        endif
    else
        player.movep# = min#(player.movep# + 0.05, 1.0)
        dir = player.dir
        if dir = LEFT
            player.x# = float(player.tx) - player.movep# + 0.5
            player.y# = float(player.ty) + 0.5
        elseif dir = RIGHT
            player.x# = float(player.tx) + player.movep# + 0.5
            player.y# = float(player.ty) + 0.5
        elseif dir = UP
            player.x# = float(player.tx) + 0.5
            player.y# = float(player.ty) - player.movep# + 0.5
        else
            player.x# = float(player.tx) + 0.5
            player.y# = float(player.ty) + player.movep# + 0.5
        endif

        if player.movep# = 1.0
            player.movep# = -1.0
            if player.dir = LEFT
                player.tx = player.tx - 1
            elseif player.dir = RIGHT
                player.tx = player.tx + 1
            elseif player.dir = UP
                player.ty = player.ty - 1
            else
                player.ty = player.ty + 1
            endif
        endif
    endif

    if player.movep# >= 0.0
        proc ISO_SetSprite 0, 1, player.dir + frame, player.x#, player.y#, 0, 5
    else
        proc ISO_SetSprite 0, 1, player.dir, player.x#, player.y#, 0, 5
    endif


    set color 0, 0, 0
    cls
    set color 255, 255, 255
    proc ISO_Render

    frameTimer = (frameTimer + 1)%8
    if frameTimer = 0 then frame = (frame + 1)%4
    rem draw image 1, 32, 180, 4 + frame

    set color 255, 255, 255
    set caret width(primary)/2, height(primary) - 24
    write "User arrow keys to walk."

    redraw
    wait 10
until keydown(27, true)


rem ========================================================
rem
rem ========================================================
procedure ISO_ClearSprites()
    for i = 0 to ISO_MAX_SPRITES - 1
        iso_Sprites[i].used = false
    next
endproc

rem ========================================================
rem Load map
rem ========================================================
function ISO_LoadMap(filename$)
    open file 0, filename$
    if not file(0) then return false
    
    rem Get path.
    for i = len(filename) - 1 downto 0
        if mid$(filename, i) = "/" then break
    next
    if i < 0
        path$ = ""
    else
        path$ = left$(filename, i + 1)
    endif

    rem Read image filename.
    imgFilename$ = path + read$(0)

    rem Load image.
    load image ISO_TILES_IMAGE, imgFilename
    if not image(ISO_TILES_IMAGE)
        free file 0
        return false
    endif    
    iso_TileW = read(0)
    iso_TileH = iso_TileW/2
    set image colorkey ISO_TILES_IMAGE, true
    set image grid ISO_TILES_IMAGE, width(ISO_TILES_IMAGE)/iso_TileW, height(ISO_TILES_IMAGE)/iso_TileH

    rem Load blocks.
    iso_BlockImages = read(0)
    iso_BlockHeights[iso_BlockImages]
    for i = 0 to iso_BlockImages - 1
        load image ISO_BLOCK_IMAGE_BASE + i, path + read$(0)
        set image colorkey ISO_BLOCK_IMAGE_BASE + i, true
        iso_BlockHeights[i] = read(0)
    next

    rem Init map with width and height from file.
    iso_MapW = read(0)
    iso_MapH = read(0)
    iso_Floor[iso_MapW][iso_MapH]
    iso_Blocks[iso_MapW][iso_MapH]
    iso_Steps[iso_MapW][iso_MapH]
    rem Load data.
    for y = 0 to iso_MapH - 1
        for x = 0 to iso_MapW - 1
            iso_Floor[x][y] = read(0)
        next
    next
    for y = 0 to iso_MapH - 1
        for x = 0 to iso_MapW - 1
            iso_Blocks[x][y] = read(0)
        next
    next

    free file 0

    rem Sprites.
    proc ISO_ClearSprites
    iso_Buckets[iso_MapW][iso_MapH][ISO_BUCKET_SIZE]
    for y = 0 to iso_MapH - 1
        for x = 0 to iso_MapW - 1
            for i = 0 to ISO_BUCKET_SIZE - 1
                iso_Buckets[x][y][i] = -1
            next
        next
    next

    rem Center.
    iso_BaseX = (width(primary) - (iso_MapW*iso_TileW - iso_MapH*iso_TileW))/2
    iso_BaseY = (height(primary) - iso_MapH*iso_TileH)/2

    iso_Factor = 2.0/(sqr(2.0*float(iso_TileW*iso_TileW)))


    return true
endfunc

rem ========================================================
rem Render.
rem ========================================================
procedure ISO_Render()
    rem Du kan lägga alla koordinater i lookup, ev skapa en
    rem bild för golvet.
    halfW = iso_TileW/2
    halfH = iso_TileH/2
    bs = ISO_BUCKET_SIZE - 1
    for y = 0 to iso_MapH - 1
        for x = 0 to iso_MapW - 1
            rem Coordinates.
            drawX = iso_BaseX + x*halfW - y*halfW
            drawY = iso_BaseY + y*halfH + x*halfH
            rem Draw floor?
            if iso_Floor[x][y] >= 0
                draw image ISO_TILES_IMAGE, drawX, drawY, iso_Floor[x][y]
            endif
        next
    next
    for y = 0 to iso_MapH - 1
        for x = 0 to iso_MapW - 1
            rem Coordinates.
            drawX = iso_BaseX + x*halfW - y*halfW
            drawY = iso_BaseY + y*halfH + x*halfH
            rem Draw block?
            block = iso_Blocks[x][y]
            if block >= 0
                draw image ISO_BLOCK_IMAGE_BASE + block, drawX, drawY - iso_BlockHeights[block]
            endif

            rem Draw sprites.
            for i = 0 to bs
                sprite = iso_Buckets[x][y][i]
                if sprite >= 0
                    img = iso_Sprites[sprite].img
                    drawX = iso_BaseX + int(iso_Sprites[sprite].x#*float(halfW) - iso_Sprites[sprite].y#*float(halfW)) + halfW -  width(img)/2
                    drawY = iso_BaseY + int(iso_Sprites[sprite].y#*float(halfH) + iso_Sprites[sprite].x#*float(halfH)) - height(img) + iso_Sprites[sprite].by - iso_Sprites[sprite].z
                    draw image iso_Sprites[sprite].img, drawX, drawY, iso_Sprites[sprite].cel
                endif
            next
        next
    next
endproc

rem ========================================================
rem Conversion from screen to tile..
rem ========================================================
function ISO_ScreenToTileX(x, y)
    
    v#[] = [float(x - iso_BaseX - iso_TileW/2)*iso_Factor, float(y - iso_BaseY)*2.0*iso_Factor]
    proc V_Rotate v, -45.0
    return int(v[0])
endfunc

rem ========================================================
rem Conversion from screen to tile..
rem ========================================================
function ISO_ScreenToTileY(x, y)
    v#[] = [float(x - iso_BaseX - iso_TileW/2)*iso_Factor, float(y - iso_BaseY)*2.0*iso_Factor]
    proc V_Rotate v, -45.0
    return int(v[1])
endfunc

rem ========================================================
rem Conversion from tile to screen.
rem ========================================================
function ISO_TileToScreenX(x, y)
    return iso_BaseX + x*iso_TileW/2 - y*iso_TileW/2
endfunc

rem ========================================================
rem Conversion from tile to screen.
rem ========================================================
function ISO_TileToScreenY(x, y)
    return iso_BaseY + y*iso_TileH/2 + x*iso_TileH/2
endfunc

function ISO_TileHeight(x, y)
    if x >= 0 and x < iso_MapW and y >= 0 and y < iso_MapH
        block = iso_Blocks[x][y]
        if block >= 0
            return iso_BlockHeights[block]
        endif
    endif
    return 0
endfunc

rem ========================================================
rem
rem ========================================================
procedure ISO_SetSprite(index, img, cel, x#, y#, z, baseY)
    if iso_Sprites[index].used
        iso_Sprites[index].img = img
        iso_Sprites[index].cel = cel
        iso_Sprites[index].x# = x
        iso_Sprites[index].y# = y
        iso_Sprites[index].z = z
        iso_Sprites[index].by = baseY
        tx = int(x)
        ty = int(y)
        if tx <> iso_Sprites[index].tx or ty <> iso_Sprites[index].ty
            proc ISO_UnbucketSprite index
            iso_Sprites[index].tx = tx
            iso_Sprites[index].ty = ty
            proc ISO_BucketSprite index
        else
            iso_Sprites[index].tx = tx
            iso_Sprites[index].ty = ty
        endif
    else
        iso_Sprites[index].used = true
        iso_Sprites[index].img = img
        iso_Sprites[index].cel = cel
        iso_Sprites[index].x# = x
        iso_Sprites[index].y# = y
        iso_Sprites[index].z = z
        iso_Sprites[index].by = baseY
        iso_Sprites[index].tx = int(x)
        iso_Sprites[index].ty = int(y)
        proc ISO_BucketSprite index
    endif
endproc

rem ========================================================
rem
rem ========================================================
procedure ISO_BucketSprite(index)
    tx = iso_Sprites[index].tx
    ty = iso_Sprites[index].ty
    if tx >= 0 and tx < iso_MapW and ty >= 0 and ty < iso_MapH
        for i = 0 to ISO_BUCKET_SIZE - 1
            if iso_Buckets[tx][ty][i] < 0 then break
        next
        if i < ISO_BUCKET_SIZE
            iso_Buckets[tx][ty][i] = index
        endif
    endif
endproc

rem ========================================================
rem
rem ========================================================
procedure ISO_UnbucketSprite(index)
    tx = iso_Sprites[index].tx
    ty = iso_Sprites[index].ty
    if tx >= 0 and tx < iso_MapW and ty >= 0 and ty < iso_MapH
        for i = 0 to ISO_BUCKET_SIZE - 1
            if iso_Buckets[tx][ty][i] = i
                iso_Buckets[tx][ty][i] = -1
                break
            endif
        next
    endif
endproc

rem ==================================================================
rem
rem ==================================================================
procedure ISO_ClearPathSteps()
    for y = 0 to iso_MapH - 1
        for x = 0 to iso_MapW - 1
            iso_Steps[x][y] = 10000
        next
    next
endproc

rem ==================================================================
rem
rem ==================================================================
function ISO_GetPath(&path[][], fromX, fromY, toX, toY)
    proc ISO_ClearPathSteps
    return ISO_FindPath(path, fromX, fromY, toX, toY, 0)
endproc

rem ==================================================================
rem
rem ==================================================================
function ISO_FindPath(&path[][], x, y, toX, toY, step)
    if step >= sizeof(path, 0) then return 0
    if x < 0 or x >= iso_MapW or y < 0 or y >= iso_MapH then return 0
    if step >= iso_Steps[x][y] then return 0
    iso_Steps[x][y] = step
    if iso_Floor[x][y] = -1 or iso_Blocks[x][y] >= 0 then return 0
    
    step = step + 1
    found = false

    steps = 0
    if x = toX and y = toY
        steps = step
    else
        dx = toX - x
        dy = toY - y
        if dx > 0 and dy > 0
            if iso_Floor[x][y + 1] >= 0 and iso_Floor[x + 1][y] >= 0 and iso_Blocks[x][y + 1] < 0 and iso_Blocks[x + 1][y] < 0
                s = ISO_FindPath(path, x + 1, y + 1, toX, toY, step)
                if s > 0 then steps = s
            endif
        elseif dx < 0 and dy < 0
            if iso_Floor[x][y - 1] >= 0 and iso_Floor[x - 1][y] >= 0 and iso_Blocks[x][y - 1] < 0 and iso_Blocks[x - 1][y] < 0
                s = ISO_FindPath(path, x - 1, y - 1, toX, toY, step)
                if s > 0 then steps = s
            endif
        elseif dx < 0 and dy > 0
            if iso_Floor[x][y + 1] >= 0 and iso_Floor[x - 1][y] >= 0 and iso_Blocks[x][y + 1] < 0 and iso_Blocks[x - 1][y] < 0
                s = ISO_FindPath(path, x - 1, y + 1, toX, toY, step)
                if s > 0 then steps = s
            endif
        elseif dx > 0 and dy < 0
            if iso_Floor[x][y - 1] >= 0 and iso_Floor[x + 1][y] >= 0 and iso_Blocks[x][y - 1] < 0 and iso_Blocks[x + 1][y] < 0
                s = ISO_FindPath(path, x + 1, y - 1, toX, toY, step)
                if s > 0 then steps = s
            endif
        endif
        if abs(toX - x) > abs(toY - y)
            if toX > x
                s = ISO_FindPath(path, x + 1, y, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x - 1, y, toX, toY, step)
                if s > 0 then steps = s
            else
                s = ISO_FindPath(path, x - 1, y, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x + 1, y, toX, toY, step)
                if s > 0 then steps = s
            endif
            if toY > y
                s = ISO_FindPath(path, x, y + 1, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x, y - 1, toX, toY, step)
                if s > 0 then steps = s
            else
                s = ISO_FindPath(path, x, y - 1, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x, y + 1, toX, toY, step)
                if s > 0 then steps = s
            endif
        else
            if toY > y
                s = ISO_FindPath(path, x, y + 1, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x, y - 1, toX, toY, step)
                if s > 0 then steps = s
            else
                s = ISO_FindPath(path, x, y - 1, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x, y + 1, toX, toY, step)
                if s > 0 then steps = s
            endif
            if toX > x
                s = ISO_FindPath(path, x + 1, y, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x - 1, y, toX, toY, step)
                if s > 0 then steps = s
            else
                s = ISO_FindPath(path, x - 1, y, toX, toY, step)
                if s > 0 then steps = s
                s = ISO_FindPath(path, x + 1, y, toX, toY, step)
                if s > 0 then steps = s
            endif
        endif
    endif

    if steps
        path[step - 1][0] = x
        path[step - 1][1] = y
    endif

    return steps
endfunc


Attached Files
.zip   Isometric_assets.zip (Size: 7.83 KB / Downloads: 5)
Reply
#6
Excellent - that's the one I was thinking of, it works really well - I remember being so impressed with this when I first saw it. I had forgotten that it was written in N6, but that's no problem.

Thank you so much for taking the time to find this.......

All the best - Kevin.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)