NaaLaa
The Maze - Printable Version

+- NaaLaa (https://www.naalaa.com/forum)
+-- Forum: NaaLaa (https://www.naalaa.com/forum/forum-1.html)
+--- Forum: NaaLaa 7 Code (https://www.naalaa.com/forum/forum-4.html)
+--- Thread: The Maze (/thread-114.html)

Pages: 1 2


The Maze - 1micha.elok - 04-09-2024

THE MAZE
I'm still working on the game, and soon it will be released
Herewith some preview snapshots :

           
click the image to zoom in

Big Grin Big Grin Big Grin


RE: The Maze - johnno56 - 04-09-2024

Intriguing... I do like a mystery thriller... Code on, sir. Code on.


RE: The Maze - 1micha.elok - 04-09-2024

(04-09-2024, 11:15 AM)johnno56 Wrote: Intriguing... I do like a mystery thriller... Code on, sir. Code on.

Code:
'maze generated from json file
map = JSON_FromFile("myassets/maze.json")
w3d.InitMap(sizeof(map), sizeof(map[0]))

To be continued....adding more mystery codes to the MAZE....lol....
oh no....my dateline clock to finish this game is ticking now.....
I can't stop it now....

Big Grin Big Grin Big Grin


RE: The Maze - 1micha.elok - 04-12-2024

THE MAZE
Made with N7_20240407

           
click each image to zoom in

Controls :
- Movement             LEFT, RIGHT, UP, DOWN
- Strafe Left/Right    CTRL+LEFT, CTRL+RIGHT
- Exit/continue         ESC
- Shoot/open door    SPACE BAR

 Hints :
 - Turn ON your speaker to experience the thriller background music
 - flash blue = a zombie is killed
   a zombie is killed when you shoot it closed enough but not too closed
 - flash red = you are killed when you are too closed to a zombie
 - flash yellow = you collect a coin
 - flash purple ... it's very rare, it is reserved for the winner only

 Weakness of this game that I haven't known yet how to do it... sorry Smile
 - A zombie should run after you if it see you
   A zombie stop chasing you when you hide inside a room and close the door
 - Animated walking zombies, spinning coins
 - Limited amount of bullets, but you may reload them
 - Some puzzles to solve :
  1. You have to find a key to open a door
  2. You have to find an amunition box to reload your bullets
  3. You have to find a paper map so that a little guided map is displayed on the screen
  4. Some parts of the maze is totally dark, and you have to find a torch to light up the path
 - Utilize the right side panel as a dynamic information box :
  1. Display collectible items (key,amunition box, paper map, torch etc.)
  2. Display infos and clues for you in each different situation
 - Generate different mazes (maze generator in n7) every time you start a new game
 - It's still buggy (you may find some bugs in the codes)

 Acknowledgements :
 - Libraries by Marcus
  1. json.n7
  2. wolf3d.n7 , examples folder

Code:
'=================================================
' MAZE
' Made with N7_20240407
'
' Controls :
' - Movement            LEFT, RIGHT, UP, DOWN
' - Strafe Left/Right   CTRL+LEFT, CTRL+RIGHT
' - Exit/continue       ESC
' - Shoot/open door     SPACE BAR
'
' Hints :
' - Turn ON your speaker to experience the thriller background music
' - flash blue = a zombie is killed
'   a zombie is killed when you shoot it closed enough but not too closed
' - flash red = you are killed when you are too closed to a zombie
' - flash yellow = you collect a coin
' - flash purple ... it's very rare, it is reserved for the winner only
'
' Weakness of this game that I haven't known yet how to do it... sorry :)
' - A zombie should run after you if it see you
'   A zombie stop chasing you when you hide inside a room and close the door
' - Animated walking zombies, spinning coins
' - Limited amount of bullets, but you may reload them
' - Some puzzles to solve :
'   1. You have to find a key to open a door
'   2. You have to find an amunition box to reload your bullets
'   3. You have to find a paper map so that a little guided map is displayed on the screen
'   4. Some parts of the maze is totally dark, and you have to find a torch to light up the path
' - Utilize the right side panel as a dynamic information box :
'   1. Display collectible items (key,amunition box, paper map, torch etc.)
'   2. Display infos and clues for you in each different situation
' - Generate different mazes (maze generator in n7) every time you start a new game
' - It's still buggy (you may find some bugs in the codes)
'
' Acknowledgements :
' - Libraries by Marcus
'   1. json.n7
'   2. wolf3d.n7 , examples folder
' - Maze Generator https://wgsantos97.github.io/content/1-projects/1-Maze-Generator-I.html
' - Title Images and Animations
'   Shadow https://images.app.goo.gl/RHRduqftTpoeqHpB8
'   Gate https://images.app.goo.gl/SNMKgtxpvcuzBYoq9
'   Maze logo https://images.app.goo.gl/uikJN2iKj2c27VA5A
' - Sound Effects
'   Thunder https://pixabay.com/sound-effects/search/thunder/
'   Evil Cue by SamuelFrancisJohnson https://pixabay.com/id/sound-effects/evil-cue-111895/
'   Monster growl https://tuna.voicemod.net/sound/a05aabc9-4234-4f7e-a311-51c0b1e79a66
' - Tiles
'   Stone wall https://u7.uidownload.com/vector/896/839/vector-stone-wall-texture-eps-thumbnail.jpg
'   Ceiling https://www.deviantart.com/bcmartini77/art/Seamless-Stone-Tile-Texture-524353179
'   Door https://images.app.goo.gl/aUv6hdWhpw3fhU1P7
' - Sprite
'   Zombie https://images.app.goo.gl/AN8RbAvfA8bqAki69   
'   Holy Grail https://images.app.goo.gl/pGd2nh4ZieNwfxWz6
'==================================================


'----------------
' INITIALIZATION
'----------------
'#win32
include "json.n7"
include "wolf3d.n7"; w3d = Wolf3D()

set window "maze", 400, 200, false, 3
set redraw off

'color definition
white               = [255,255,255]
white_              = [255,255,255,100]         
black               = [0,0,0]
lightgray           = [100,100,100]
gray                = [50,50,50]
red                 = [255,0,0]
red_                = [255,0,0,100]
pink                = [255,0,255]
green               = [0,200,0]
darkgreen           = [0,64,0]
yellow              = [255,255,0]
yellow_             = [255,255,0,100]
brown               = [110,96,87]
blue_               = [0,0,255,100]
purple_             = [128,0,128,100]

' player
player = []
player.x            = 0
player.z            = 0
player.angle        = 90 '90=south
player.lifes        = 3
player.coins        = 0 'count the number of collected coins
player.shootTimer   = 0 'limit how often to shoot a new bullet.
player.killzombies  = 0 'count the number of killed zombies
player.shoot        = false

' tileset
tile            = []
tile.door       = loadimage("myassets/door.png")
tile.wall       = loadimage("myassets/stone_wall.png")
tile.floor_     = loadimage("myassets/stone_floor.png")
tile.ceiling    = loadimage("myassets/wood_ceiling.png")

' accessories
acc             = []
acc.coin        = loadimage("myassets/coin.png")
acc.bullet      = loadimage("myassets/fire_ball.png")
acc.zombie      = loadimage("myassets/zombie.png")
acc.logo        = loadimage("myassets/title_mini.png")
acc.holy_grail  = loadimage("myassets/holy_grail.png")

' store each object
coins           = []
bullets         = []
zombies         = []
holy_grail      = []

'maze generated from json file, 0=floor, 1=wall, 8=coin, 9=player
map = JSON_FromFile("myassets/maze.json")
w3d.InitMap(sizeof(map), sizeof(map[0]))

'set floor,ceiling,wall,door, coins on the maze
w3d.SetFloorTexture(tile.floor_)
w3d.SetCeilingTexture(tile.ceiling)
for z = 0 to sizeof(map)-1
    for x = 0 to sizeof(map[0])-1
        select map[z][x]
            case 1
                w3d.SetWall(x, z, tile.wall)
            case 2
                w3d.SetDoor(x, z, tile.door, W3D_X_AXIS)
            case 5
                holy_grail[0] = w3d.AddFloorSprite(x+0.5, z+0.5, acc.holy_grail, 0.5)
            case 6
                zombies[sizeof(zombies)] = w3d.AddFloorSprite(x+0.5, z+0.5, acc.zombie, 1)
            case 8
                coins[sizeof(coins)] = w3d.AddFloorSprite(x + 0.5, z + 0.5,acc.coin, 0.5)                     
            case 9
                player.x = x + 0.5
                player.z = z + 0.5
        endsel
    next
next

' SetView(x, y, w, h, field of view)
w3d.SetView(3,3, width(primary)-100, height(primary)-6, rad(90))

' SetFog(min_d, max_d, r, g, b), a fog effect
w3d.SetFog(4, 8, black[0],black[1],black[2])

' Generate little guide map.
map = []
map.img = 0
map.scale = 2
create image map.img, w3d.mw*map.scale, w3d.mh*map.scale
set image map.img
set color pink; cls; set image colorkey map.img, pink[0],pink[1],pink[2]
for z = 0 to w3d.mh - 1
    for x = 0 to w3d.mw - 1
        if w3d.Wall(x, z) > 0 then
            set color green
            draw rect x*map.scale, z*map.scale, map.scale, map.scale, true
        endif
    next
next
set image primary

'info box
info        = []
info.x      = width(primary)-94
info.y      = 3
info.w      = 90
info.h      = height(primary)-6
info.music_ = loadmusic("myassets/evil_cue.wav")

'--------------
' INTRODUCTION
'--------------
' Caution
set color white
set caret width(primary)/2,5
center "CAUTION"
center
center "Please beware if you have suffered"
center "any side effects when playing this game"
center "or are concerned that"
center "you might be in danger in doing so."
center "Please stop playing and take a rest"
center
center
center
center
center "Press ESC to continue.."
redraw
do;wait 1;until keydown(KEY_ESCAPE,true)

' Title Screen
gate    = loadimage("myassets/title_gate.png")
thunder = loadsound("myassets/title_thunder.wav")
title   = loadimage("myassets/title.png")
for i = 1 to 5
    set color white_
    draw rect 0,0,width(primary),height(primary),1
    redraw; wait 100
    set color black; cls; set color white
    play sound thunder
    draw image gate,0,0; redraw; wait 500
next
set color white_
draw image title, (width(primary)-width(title))/2,5
set color white; set caret width(primary)/2,185; center "Press ESC to continue"
redraw
do; wait 1;until keydown(KEY_ESCAPE,true)
free image gate
free sound thunder
free image title

' Introduction
play music info.music_,true
darkness = loadimage("myassets/title_darkness.png",10,3)
for e = 5 to 1
    for i = 0 to 20
        set color black;cls;set color white
        draw image darkness,5,0,i
        set caret 30+width(darkness),10
        wln "Choose your best paths."
        wln "Reach the exit door."
        wln "Even though ..."
        wln "you walk through the maze"
        wln "of the shadow of death"
        wln "you won't be afraid"
        wln "You'll find strength"
        wln "in every step..."
        wln
        wln "Are you ready ?"
        set color red; write e
        redraw
        wait 60
    next
    wait 10
next
free image darkness

'timer
timer        = []
timer.Start  = clock()
timer.sound_ = loadsound("myassets/monster_growl.wav")

'-----------
' MAIN LOOP
'-----------
while not keydown(KEY_ESCAPE)
    'monster growl sound effect
    timer.Duration = (clock() - timer.Start)/1000
    if round(timer.Duration)%8 = 0 then
        play sound timer.sound_,0.2
    endif

    set color black;cls;set color white

    ' info box layout
    set color lightgray
    draw rect info.x,info.y,info.w,info.h 'outer box
    set color brown
    draw image acc.logo,-10+info.x+25,info.y+15
    draw rect -15+info.x+25,info.y+25*4,70,85
    set caret -13+info.x+25,10+info.y+25*4
    wln "Goto"
    wln "Red Exit"
    wln "and be"
    wln "careful"
                                                                                                                       
    ' Player's Movement
    dx = 0; dz = 0
    if keydown(KEY_CONTROL)
        ' Strafe with the arrow left and right keys.
        if keydown(KEY_LEFT)
            dx = dx + cos(rad(player.angle - 90))
            dz = dz + sin(rad(player.angle - 90))
        endif
        if keydown(KEY_RIGHT)
            dx = dx + cos(rad(player.angle + 90))
            dz = dz + sin(rad(player.angle + 90))
        endif
    else
        ' Rotate view, use %360 to keep player.angle in the range [0..360]
        if keydown(KEY_LEFT)  player.angle = (player.angle - 2)%360
        if keydown(KEY_RIGHT) player.angle = (player.angle + 2)%360
    endif
       
    ' Move forward with the arrow up key.
    if keydown(KEY_UP)
        dx = dx + cos(rad(player.angle))
        dz = dz + sin(rad(player.angle))
    endif
    if keydown(KEY_DOWN)
        dx = dx - cos(rad(player.angle))
        dz = dz - sin(rad(player.angle))
    endif

    'Player's movement
    d = sqr(pow(dx,2) + pow(dz,2))
    if d > 0
        dx = dx/d ; dx = dx*0.05
        dz = dz/d ; dz = dz*0.05
        result = w3d.Move(player.x, player.z, dx, dz, 0.25)
        player.x = result.x
        player.z = result.z
    endif
    w3d.Render(player.x, player.z, rad(player.angle))

    ' collision player vs coins.
    i = 0
    while i < sizeof(coins)
        c = coins[i]
        ' d = the square distance between the player and the coin
        ' if less than 0.25, the coin is picked up
        d = (c.x - player.x)^2 + (c.z - player.z)^2
        if d < 0.25
            w3d.RemoveSprite(c)
            free val coins, c
            player.coins = player.coins + 1           
           
            'flash yellow
            for i = 1 to 3
                set color yellow_
                draw rect 0,0,width(primary),height(primary),1
                redraw; wait 100
            next
           
        else
            i = i + 1
        endif
    wend

    ' collision player vs holy_grail
        hg = holy_grail[0]
        dhg = (hg.x - player.x)^2 + (hg.z - player.z)^2
        if dhg < 0.25
            w3d.RemoveSprite(hg)
            free val holy_grail, hg
           
            'flash purple
            for q = 1 to 3
                set color purple_
                draw rect 0,0,width(primary),height(primary),1
                redraw; wait 100
            next
   
            'The End   
            set color white
            set caret 10,20
            wln "You have not only reached"
            wln "the exit door of the maze,"
            wln "but also you have seen"
            wln "The Holy Grail."
            wln "You have embraced it"
            wln "forever and ever."
            wln
            wln "Congratulations"
            wln "You finished it in "+int(clock()/1000)+" seconds"
            wln "You collected "+player.coins+" coins"
            wln "You killed "+player.killzombies+" zombies"

            redraw
            do;wait 1; until keydown(KEY_ESCAPE,true)
            end
        endif
                   
    ' collision player vs zombies
    i = 0
    while i < sizeof(zombies)
        c = zombies[i]
        ' the square distance between the player and the zombies
        ' if less than 0.25, the coin is picked up
        d = (c.x - player.x)^2 + (c.z - player.z)^2
        if d < 0.25
            w3d.RemoveSprite(c)
            free val zombies, c
            player.lifes = player.lifes-1
                       
            'flash red
            for i = 1 to 3
                set color red_
                draw rect 0,0,width(primary),height(primary),1
                redraw; wait 100
            next

            'The End   
            if player.lifes < 0 then
                set color white
                set caret 10,40
                wln "Now,you are one of them"
                wln "As a zombie"
                wln "You are trapped in the maze"
                wln "Forever..."
                wln
                wln "The End"
                redraw
                do;wait 1; until keydown(KEY_ESCAPE,true)
                end
            endif           
                             
        else
            i = i + 1
        endif
    wend

    ' Shoot a bullet or open a door
    player.shootTimer = max(player.shootTimer - 1, 0)
    if keydown(KEY_SPACE)
        ' Facing(x, z, angle) returns true if the closest thing is a door.
        res = w3d.Facing(player.x, player.z, rad(player.angle))
        if res.door and res.distance < 1.0 and w3d.OpenDoor(res.mapx, res.mapz)
            ' so that the player doesn't shoot every time it opens a door
             dummy = keydown(KEY_SPACE, true)
        elseif player.shootTimer = 0
            ' AddSprite(center_x, center_y, center_z, texture, width, height)
            bullet = w3d.AddSprite(player.x, 0.2, player.z, acc.bullet, 0.29, 0.29)
            bullet.dx = 0.2*cos(rad(player.angle))
            bullet.dz = 0.2*sin(rad(player.angle))
            bullets[sizeof(bullets)] = bullet
            player.shootTimer = 5
        endif
    endif
   
    ' Update bullets
    i = 0
    while i < sizeof(bullets)
        b = bullets[i]
        if w3d.MoveSprite(b, b.dx, b.dz, 0.1)
            w3d.RemoveSprite(b)
            free val bullets, b
        else
            i = i + 1
        endif
       
        'zombie is killed when the player is closed enough but not too closed
        k = 0
        while k < sizeof(zombies)
            c = zombies[k]
            db = (c.x - player.x)^2 + (c.z - player.z)^2
            if db < 5
                w3d.RemoveSprite(c)
                free val zombies, c
                player.killzombies = player.killzombies + 1
                player.shoot = true                               
            else
                k = k + 1
            endif
           
            if player.shoot then
                'flash blue
                for m = 1 to 3
                    set color blue_
                    draw rect 0,0,width(primary),height(primary),1
                    redraw; wait 100
                next
                player.shoot = false
            endif
        wend       
    wend               
                                               
    'Display green map, white player and red destination
    x = 220
    y = height(primary) - height(map.img) -5
    set color white
    draw image map.img, x, y
    draw rect x + int(player.x*map.scale) - 1, y + int(player.z*map.scale) - 1, map.scale, map.scale, true
    set color red
    draw ellipse x + width(map.img)-2, y+height(map.img)-4, map.scale*1.5, map.scale*1.5, true   

    'Display Lifes, Timer, Coins, Zombies
    set color white
    set caret 10,5
    wln "Lifes  :"+player.lifes
    wln "Coins  :"+player.coins
    wln "Zombies:"+player.killzombies
    set caret 210,5
    wln "Timer :"+int(clock()/1000)
                                                                                                                                                       
    ' Update the window.
    redraw
    fwait 60
wend

'---------------
' Gone Too Soon
'---------------

'flash red
for i = 1 to 3
    set color red_
    draw rect 0,0,width(primary),height(primary),1
    redraw; wait 100
next

set color white
set caret 10,40
wln "Gone too soon"
wln "Why now ?"
wln "You are still trapped in the maze"
wln "Forever..."
wln
wln "The End"
redraw
do;wait 1; until keydown(KEY_ESCAPE,true)
end



RE: The Maze - johnno56 - 04-12-2024

When I saw your first screen shot I thought, "Oh no! It's timed!". Thankfully it was not a "count down"... Phew!

Navigation was smooth. Having the mini-map is a huge help... The sound track is well chosen! Knowing that the wolf3d library was used, for me anyway, made it better experience. Huge fan of Wolf3D type games...

Great game! Well done!

Are you planning on a sequel or perhaps modifications to the current game?  Whichever you choose, I will eagerly wait for it...!!

   


RE: The Maze - 1micha.elok - 04-12-2024

(04-12-2024, 11:23 AM)johnno56 Wrote: ... Huge fan of Wolf3D type games...
Are you planning on a sequel or perhaps modifications to the current game?  Whichever you choose, I will eagerly wait for it...!!

Thank you for being a huge fan of Wolf3D type games !

There are some points that I have not found yet on how to code them, such as :

  1. You play hide-and-seek with a zombie when you don't have bullets anymore ... lol ....
      A zombie should run after you if it see you like in Pac-Man
      A zombie stop chasing you when you hide inside a room and close the door
 
 2. Animated walking zombies, spinning coins

 3.  Limited amount of bullets, but you may reload them

 4.  Some puzzles to solve :
     a. You have to find a key to open a door
     b. You have to find an amunition box to reload your bullets
     c. You have to find a paper map so that a little guided map is displayed on the screen
     d. Some parts of the maze is totally dark, and you have to find a torch to light up the path
 
 5. Utilize the right side panel as a dynamic information box :
    a. Display collectible items (key,amunition box, paper map, torch etc.)
    b. Display infos and clues for you in each different situation
 
 6. Generate different mazes (maze generator in n7) every time you start a new game

I wish, someone has the answers to the points above, so that THE MAZE - II will be on production 

Big Grin Big Grin Big Grin


RE: The Maze - Marcus - 04-12-2024

Raycasting games are just like top down 2d games. Maybe you can look at how I coded the enemies in farmer man (in7/examples/other)? I believe they chase the player when they see him. There should also be a function in wolf3d to check if a point (x, z) is visible from another point.


RE: The Maze - 1micha.elok - 04-12-2024

(04-12-2024, 06:08 PM)Marcus Wrote: Raycasting games are just like top down 2d games. Maybe you can look at how I coded the enemies in farmer man (in7/examples/other)? I believe they chase the player when they see him. There should also be a function in wolf3d to check if a point (x, z) is visible from another point.

   
The Farmer Man
click to zoom in

Thanks, Marcus... I'll take a look at the Farmer Man....I saw your Avatar in that game, too  Big Grin

   
Wolf3D function to check point visibility

...and also learn how to use wolf3d to check point visibility


RE: The Maze - johnno56 - 04-13-2024

I found a MazeGen program, written in QB64, and figured that you could probably adapt if for your purposes.

It produces a 40x40 maze (walls only - sorry...) and outputs to the screen for a few seconds then ends.

It should not be too difficult to modify the output to a file...

I know... It's rough... but, until an Editor magically pops up, it's all I could throw together. I hope it helps...

ps: I made a very-crude Editor, in another language that shall remain nameless, and could possibly be converted to N7... but do not get your hopes up... At the moment it has more bugs than a carcass...

Code:
' Open a window and enable double buffering.
set window "MazeGen", 680, 680, false
set redraw off

randomize clock()

mWidth = 41
mHeight = 41

'   Create array and fill
maze = dim(mWidth, mHeight)
for x = 0 to mWidth - 1
    for y = 0 to mHeight - 1
        maze[x][y] = "#"
    next
next

'   Initial start locations
currentX = rnd(0, mWidth - 1)
currentY = rnd(0, mHeight - 1)

'   Values must be odd
if currentX % 2 = 0     currentX = currentX + 1
if currentY % 2 = 0     currentY = currentY + 1
maze[currentX][currentY] = " "

'   Generate Maze
done = false
do
    for i = 0 to 99
        oldX = currentX
        oldY = currentY
       
        '   Move in random directions
        select case rnd(0, 3)
            case 0
                if currentX + 2 < mWidth    currentX = currentX + 2
            case 1
                if currentY + 2 < mHeight   currentY = currentY + 2
            case 2
                if currentX - 2 > 0         currentX = currentX - 2
            case 3
                if currentY - 2 > 0         currentY = currentY - 2
        endsel
       
        '   If cell is unvisited then connect it
        if maze[currentX][currentY] = "#"
            maze[currentX][currentY] = " "
            maze[int((currentX + oldX) / 2)][(currentY + oldY) / 2] = " "
        endif
    next
   
    '   Check if all cells are visited
    done = true
    for x = 1 to mWidth - 1 step 2
        for y = 1 to mHeight - 1 step 2
            if maze[x][y] = "#"     done = false
        next
    next
until done = true

'   Draw Maze
set color 255, 255, 255
for y = 0 to mHeight - 1
    for x = 0 to mWidth - 1
        set caret x * 16, y * 16
        wln maze[x][y]
    next
    wln
next
redraw
wait 3000; end

I know... It is not very efficient, but it gets the job done... lol

J


RE: The Maze - 1micha.elok - 04-14-2024

(04-13-2024, 07:53 AM)johnno56 Wrote: I found a MazeGen program, written in QB64, and figured that you could probably adapt if for your purposes.
...

Thank you, Johnno
This is one of the game element that I am looking for.
The maze generator in N7. GREAT.

I'll learn your code and see how far I can adapt it to THE MAZE - II ( Yes, it is in production now ... Cool .... at least the Maze location will be inside an ancient Egyptian Pyramid, no more zombies, but some guardian mummies will happily meet you there... lol ....)

Happy Autumn Sunday in the southern hemisphere !