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: 203
» Forum posts: 1,543

Full Statistics

Online Users
There are currently 142 online users.
» 0 Member(s) | 141 Guest(s)
Bing

Latest Threads
Backspace Key
Forum: NaaLaa 7 Questions
Last Post: 1micha.elok
2 hours ago
» Replies: 9
» Views: 457
Raylib and SmallBASIC....
Forum: Programming
Last Post: aurel
9 hours ago
» Replies: 1
» Views: 27
A diligent BASIC dialect(...
Forum: Programming
Last Post: luwal
Yesterday, 11:05 PM
» Replies: 2
» Views: 70
RW3
Forum: NaaLaa 7 Code
Last Post: 1micha.elok
Yesterday, 05:21 AM
» Replies: 6
» Views: 606
It's that time of year ag...
Forum: Everything else
Last Post: 1micha.elok
Yesterday, 05:09 AM
» Replies: 1
» Views: 49
Why all 80's Computers ha...
Forum: Everything else
Last Post: johnno56
05-03-2025, 02:08 PM
» Replies: 3
» Views: 107
The most used BASIC diale...
Forum: Programming
Last Post: johnno56
05-02-2025, 01:01 AM
» Replies: 13
» Views: 510
Most used game engines on...
Forum: Everything else
Last Post: johnno56
05-01-2025, 04:55 AM
» Replies: 1
» Views: 69
Suggestion: other classic...
Forum: Suggestions
Last Post: luwal
04-29-2025, 02:05 AM
» Replies: 2
» Views: 169
Suggestion: an example fo...
Forum: Suggestions
Last Post: luwal
04-27-2025, 06:16 PM
» Replies: 3
» Views: 188

 
  Convex hull, quick algorithm
Posted by: Marcus - 05-02-2024, 04:24 PM - Forum: NaaLaa 7 Code - Replies (7)

I need to calculate and display the convex hull of 2D polygons in the editor for that 3d thing, so I implemented a quick (as in "divide and conquer") algorithm for it. I remember writing a quick algorithm for the convex hull of a set of random points in 3D at the university, which is a bit trickier.

If you ever need to calculate the convex hull for a polygon or a bunch of points, you can use this Smile

Code:
' Convex hull test
' ----------------

set window "test", 640, 480
set redraw off

do
    set color 0, 0, 0
    cls
    ' Create 100 random points.
    points = []
    for i = 1 to 100
        a = rnd()*2*PI
        r = rnd(200)
        points[sizeof(points)] = 320 + cos(a)*r
        points[sizeof(points)] = 240 + sin(a)*r
    next
    ' Draw points.
    set color 255, 255, 255
    pcount = sizeof(points)/2
    for i = 0 to pcount - 1
        draw pixel points[i*2], points[i*2 + 1]
    next
    ' Display and wait one second.
    redraw
    wait 1000
    ' Calculate convex hull and display it.
    hull = ConvexHull(points)
    draw poly hull
   
    set caret width(primary)/2, 4
    center "Press space bar to continue ..."
   
    redraw
    while not keydown(KEY_SPACE, true)  fwait 60
loop

' ConvexHull
' ----------
' Calculate the convex hull for a set of points in an array [x0, y0, x1, y1 ..], return as a polygon
' in the same format.
function ConvexHull(points)
    pcount = sizeof(points)/2
    xminIndex = 0; xmaxIndex = 0
    for i = 1 to pcount - 1
        x = points[i*2]
        if x < points[xminIndex*2] xminIndex = i
        if x > points[xmaxIndex*2] xmaxIndex = i
    next
    lpoints = []; rpoints = []
    for i = 0 to pcount - 1
        if i <> xminIndex and i <> xmaxIndex
            cp = CrossProd(points[xminIndex*2], points[xminIndex*2 + 1],
                    points[xmaxIndex*2], points[xmaxIndex*2 + 1],
                    points[i*2], points[i*2 + 1])
            if cp < 0
                lpoints[sizeof(lpoints)] = points[i*2]
                lpoints[sizeof(lpoints)] = points[i*2 + 1]
            elseif cp > 0
                rpoints[sizeof(rpoints)] = points[i*2]
                rpoints[sizeof(rpoints)] = points[i*2 + 1]
            endif
        endif
    next
    hull = []
    hull[sizeof(hull)] = points[xminIndex*2]
    hull[sizeof(hull)] = points[xminIndex*2 + 1]
    HullRec(hull, lpoints, points[xminIndex*2], points[xminIndex*2 + 1], points[xmaxIndex*2], points[xmaxIndex*2 + 1])
    hull[sizeof(hull)] = points[xmaxIndex*2]
    hull[sizeof(hull)] = points[xmaxIndex*2 + 1]
    HullRec(hull, rpoints, points[xmaxIndex*2], points[xmaxIndex*2 + 1], points[xminIndex*2], points[xminIndex*2 + 1])
   
    return hull
   
    function HullRec(hull, points, x0, y0, x1, y1)
        if not sizeof(points)  return
        pcount = sizeof(points)/2
        maxd = 0; maxdIndex = -1
        for i = 0 to pcount - 1
            x = points[i*2]; y = points[i*2 + 1]
            d = LinePointDist(x0, y0, x1, y1, x, y)
            if d > maxd
                maxd = d
                maxdIndex = i
            endif
        next
           
        npoints = []
        for i = 0 to pcount - 1
            if i <> maxdIndex
                x = points[i*2]; y = points[i*2 + 1]
                cp = CrossProd(x0, y0, points[maxdIndex*2], points[maxdIndex*2 + 1], x, y)
                if cp < 0
                    npoints[sizeof(npoints)] = x
                    npoints[sizeof(npoints)] = y
                endif
            endif
        next
        if sizeof(npoints)
            HullRec(hull, npoints, x0, y0, points[maxdIndex*2], points[maxdIndex*2 + 1])
        endif
        hull[sizeof(hull)] = points[maxdIndex*2]
        hull[sizeof(hull)] = points[maxdIndex*2 + 1]
       
        npoints = []
        for i = 0 to pcount - 1
            if i <> maxdIndex
                x = points[i*2]; y = points[i*2 + 1]
                cp = CrossProd(points[maxdIndex*2], points[maxdIndex*2 + 1], x1, y1, x, y)
                if cp < 0
                    npoints[sizeof(npoints)] = x
                    npoints[sizeof(npoints)] = y
                endif
            endif
        next
        if sizeof(npoints)
            HullRec(hull, npoints, points[maxdIndex*2], points[maxdIndex*2 + 1], x1, y1)
        endif
    endfunc
   
    function CrossProd(ax, ay, bx, by, cx, cy)
        return (bx - ax)*(cy - ay) - (by - ay)*(cx - ax)
    endfunc
   
    function LinePointDist(x0, y0, x1, y1, px, py)
        dx = x1 - x0; dy = y1 - y0; d = dx*dx + dy*dy
        if d <= 0  return 0
        return |(x1 - x0)*(py - y0) - (px - x0)*(y1 - y0)|/sqr(d)
    endfunc   
endfunc

Print this item

  Small pinball game using circle-line collision routines from Marcus
Posted by: kevin - 05-01-2024, 02:30 PM - Forum: NaaLaa 7 Code - Replies (2)

This is not meant to be a proper simulation (as you will see if you run it Smile), but just an experiment with the terrific circle-line functions that Marcus provided a while back. I've used the functions as they were originally written by Marcus, with one small alteration to the polygon function, where I have added a fifth argument to allow me to specify a point around which the polygon is rotated, rather than the center point of the polygon (I needed this for the 2 flippers).

There a few values that can be altered in the code to change the way that the ball reacts to certain lines - I've marked some of these as "arbitrary values", and I'm sure changing these will make for a smoother game, but I've decided to move on to a new project.

Control the flippers with the A and D keys, and launch the ball using the UP arrow.

   

Code:
' Experiment.

set window "PINBALL", 480, 640
set redraw off

#win32
visible score = 0
' List of lines that objects can collide with.

left_flipper = []
right_flipper = []

l_flipper = Polygon([0,0,10,-10,60,30,60,40], 140,580,  true,[0,0])
r_flipper = Polygon([0,0,-10,-10,-60,30,-60,40], 300,580,  true,[0,0])
'=============================================================================
'Note  -added fifth argument to Polygon - 0 rotates around center point, or
'use a 2 part table to rotate around any point in the polygon - i.e. [32,34]
' to rotate around the fourth point in the polygon array here : -
'l_flipper = Polygon([0,0,10,0,32,24,32,34,22,34,0,10], 320, 240, true,[32,34])
'==============================================================================
l_flipper.AddTo(left_flipper)
left_flipper_timer = 0
left_ang = 0

r_flipper.AddTo(right_flipper)
right_flipper_timer = 0
right_ang = 0



bouncers = []
lines = []
circles = []
table1 = Polygon([180,0,300,0,360,20,420,60,460,120,480,180,480,640,
                    0,640,0,180,20,120,60,60,120,20,180,0],0,0,false,0)
table1.AddTo(lines)


visible circle_hit = unset
circle1 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],100,230,true,0)
circle1.AddTo(circles)

circle2 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],225,230,true,0)
circle2.AddTo(circles)

circle3 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],350,230,true,0)
circle3.AddTo(circles)

circle4 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],162,180,true,0)
circle4.AddTo(circles)

circle5 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],287,180,true,0)
circle5.AddTo(circles)

circle6 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],130,440,true,0)
circle6.AddTo(circles)

circle7 = Polygon([0,0,9,3,13,8,15,15,13,23,9,27,0,30,-9,27,-13,23,-15,15,-13,8,-9,3],310,440,true,0)
circle7.AddTo(circles)


'additional parts of table
'lines - no bouncing
lines[sizeof(lines)] = Line(440,640,440,180)
lines[sizeof(lines)] = Line(360,640,440,590)
lines[sizeof(lines)] = Line(0,590,80,640)
'left upper curve (inner) - no bouncing
lines[sizeof(lines)] = Line(65,330,40,290)
lines[sizeof(lines)] = Line(40,290,40,200)
lines[sizeof(lines)] = Line(40,200,55,150)
lines[sizeof(lines)] = Line(55,150,95,95)
lines[sizeof(lines)] = Line(95,95,150,60)
lines[sizeof(lines)] = Line(150,60,200,45)


'right upper curve (inner) - no bouncing
lines[sizeof(lines)] = Line(300,85,315,90)
lines[sizeof(lines)] = Line(315,90,360,120)
lines[sizeof(lines)] = Line(360,120,385,160)
lines[sizeof(lines)] = Line(385,160,400,200)


lines[sizeof(lines)] = Line(40,490,40,430)
lines[sizeof(lines)] = Line(400,430,400,490)

'triangles sticking out of side - not bouncing
lines[sizeof(lines)] = Line(0,380,40,380)
lines[sizeof(lines)] = Line(0,310,40,380)
lines[sizeof(lines)] = Line(440,380,400,380)
lines[sizeof(lines)] = Line(400,380,440,310)

'bouncers

bouncers[sizeof(bouncers)] = Line(40,490,130,550)
bouncers[sizeof(bouncers)] = Line(400,490,310,550)

bouncers[sizeof(bouncers)] = Line(40,430,70,435)
bouncers[sizeof(bouncers)] = Line(400,430,370,435)


' Player.
visible obj = Object(472, 632, 16)
obj.dx = 0
obj.dy = 0


############  to calculate FPS  ##########################
visible framecount,lasttime = 999,fps,frametime = 0,starttime = 0,endtime = 0,min_fps = 99999,max_fps = 0
##########################################################

while not keydown(KEY_ESCAPE)
###  for FPS calc #########
framecount = framecount + 1
starttime = clock()
###########################
    ' Rotate obstacles.
    circle1.SetAngle(circle1.Angle() + rad(3))
    circle2.SetAngle(circle2.Angle() + rad(3))
    circle3.SetAngle(circle3.Angle() + rad(3))
    circle4.SetAngle(circle4.Angle() + rad(3))
    circle5.SetAngle(circle5.Angle() + rad(3))
    circle6.SetAngle(circle5.Angle() + rad(3))
    circle7.SetAngle(circle5.Angle() + rad(3))
   
set mouse off   
if obj.y >= 624 and obj.x < 440 then game_over()   


    obj.x = obj.x + obj.dx
    obj.y = obj.y + obj.dy


    '-------   left flipper  ------------
    if keydown(KEY_A,true) and left_flipper_timer <= 0
        left_flipper_timer = 16
    endif
    if left_flipper_timer > 0
        left_flipper_timer = left_flipper_timer - 1
        l_flipper.SetAngle(max(l_flipper.Angle() - rad(4),-1.2))
    elseif left_flipper_timer <= 0
        l_flipper.SetAngle(0)
    endif
 
    PushOut(obj, left_flipper)
    if obj.pdy < 0
    if l_flipper.Angle() <> 0
        obj.dy = - 10
        left_ang = angle_rad(l_flipper.trans[1][0],l_flipper.trans[1][1],l_flipper.trans[2][0],l_flipper.trans[2][1])
        left_vecs = get_vecs(left_ang)
        obj.dx = obj.dx + left_vecs[0] * 16'arbitrary figure
    endif
    endif
    '==================================
    '-------   right flipper  ------------
    if keydown(KEY_D,true) and right_flipper_timer <= 0
        right_flipper_timer = 16
    endif
    if right_flipper_timer > 0
        right_flipper_timer = right_flipper_timer - 1
        r_flipper.SetAngle(max(r_flipper.Angle() + rad(4),-1.2))
    elseif right_flipper_timer <= 0
        r_flipper.SetAngle(0)
    endif

    PushOut(obj, right_flipper)
    if obj.pdy < 0
    if r_flipper.Angle() <> 0
        obj.dy = - 10
       right_ang = angle_rad(r_flipper.trans[2][0],r_flipper.trans[2][1],r_flipper.trans[1][0],r_flipper.trans[1][1])
        right_vecs = get_vecs(right_ang)
        obj.dx = obj.dx + right_vecs[0] * 32'arbitrary figure
    endif
    endif
    '==================================
    PushOut(obj, bouncers)' make them bounce a little
    if obj.pdx <> 0 or obj.pdy <> 0
       obj.dx = obj.dx + obj.pdx*12'arbitrary figure
       obj.dy = obj.dy + obj.pdy*12 'arbitrary figure
    endif

 
   
    PushOut(obj, lines)
  ' 
   if obj.y < 180 and obj.x > 240  and obj.dx < 0' help with initial lauch of ball
        if obj.pdx <> 0 or obj.pdy <> 0
            obj.dx = obj.dx + obj.pdx*4'arbitrary figure
         
        endif
   endif
   if obj.y < 180 and obj.x < 240 ' help with initial lauch of ball
        if obj.pdx <> 0 or obj.pdy <> 0
            obj.dx = obj.dx + obj.pdx*0.3'arbitrary figure
            obj.dy = obj.dy + obj.pdy*1
        endif
   endif
    ' obj.pdx and obj.pdy has now been set to the average "push direction" caused by all lines
    ' pushing the object around.
  
    ' Push direction y < 0 means the object is being pushed UP. In that case, set dy to 0.
    if obj.pdy < 0
        ' If push direction y < -0.25, let the player jump.
        if obj.pdy < -0.25 and keydown(KEY_UP, true) and obj.x >= 455
            obj.dy = -14
       endif
    endif
    ' Apply gravity.
    obj.dy = min(obj.dy + 0.1, 6)
    ' So ... stuff to dx.
    obj.dx = obj.dx + obj.pdx*0.25 ' I have no idea
    obj.dx = obj.dx*0.95
   
    PushOut(obj, circles)
        if obj.pdx <> 0 or obj.pdy <> 0
        score = score + 10
        obj.dx = obj.pdx * 8'arbitrary
        obj.dy = obj.pdy * 8'arbitrary
    endif
    
    set color 0, 0, 0
    cls
    set color 255, 255, 255
    DrawLines(lines)
    DrawLines(circles)
    DrawLines(bouncers)
    DrawLines(left_flipper)
    DrawLines(right_flipper)
    obj.Draw()
   
    set caret 20,10
    set justification left
    write "SCORE : " + score;wln
  

'    set caret 460,10
'    set justification right
'    write "FPS = " + str(fps);wln

'    write "MIN_FPS = " + str(min_fps);wln
'    write "MAX_FPS = " + str(max_fps);wln

    redraw
    fwait 60
   
    #######  FPS calc  ############################
endtime = clock()
frametime = frametime + endtime - starttime
if frametime > 1000 # 1 second
    fps = framecount
    framecount = 0
    frametime = 0
    if fps < min_fps then min_fps = fps
    if fps > max_fps then max_fps = fps
endif
################################################
wend

function DrawLines(lines)
    foreach ln in lines  draw line ln[0], ln[1], ln[2], ln[3]
endfunc


function Object(x, y, r)
    return [x: x, y: y, r: r, rsqr: r*r, pdx: 0, pdy: 0,
            Draw: function(); draw ellipse .x, .y, .r, .r, false; endfunc]
endfunc

' Pushout
' -------
function PushOut(obj, lines)
    tests = 4
    obj.pdx = 0
    obj.pdy = 0
    for i = 1 to tests
        col = false
        foreach ln in lines
            dp = max(0, min(ln[6], (obj.x - ln[0])*ln[4] + (obj.y - ln[1])*ln[5]))
            px = ln[0] + dp*ln[4]; py = ln[1] + dp*ln[5]
            dx = obj.x - px; dy = obj.y - py
            d = dx*dx + dy*dy
            if d < obj.rsqr
                k = 1/sqr(d)
                obj.x = px + dx*k*obj.r
                obj.y = py + dy*k*obj.r
                obj.pdx = obj.pdx + dx*k
                obj.pdy = obj.pdy + dy*k
                col = true
         
            endif
        next
        if not col break
    next
    if obj.pdx or obj.pdy
        k = 1/sqr(obj.pdx*obj.pdx + obj.pdy*obj.pdy)
        obj.pdx = obj.pdx*k
        obj.pdy = obj.pdy*k
    endif
endfunc

' Polygon
' -------
' Return polygon at position x, y.
' Polygon
' -------
' Return polygon at position x, y.
'function Polygon(points, x, y, closed,rotation_point_x,rotation_point_y)
function Polygon(points, x, y, closed,rotation_point)
'========================================================================
'Note -  added fifth argument to Polygon - 0 rotates around center point, or
'use a 2 part table to rotate around any point in the polygon - i.e. [32,34]
' to rotate around the fourth point in the polygon array here :-
'l_flipper = Polygon([0,0,10,0,32,24,32,34,22,34,0,10], 320, 240, true,[32,34])
'========================================================================

    p = [trans: unset, org: [], x: x, y: y, a: 0, cx:0, cy: 0]
    pcount = sizeof(points)/2
    centerX = 0
    centerY = 0
    if closed  n = pcount - 1
    else    n = pcount - 2
    for i = 0 to n
        j = (i + 1)%pcount
        p.org[sizeof(p.org)] = Line(
                points[i*2], points[i*2 + 1],
                points[j*2], points[j*2 + 1])
    next
    for i = 0 to pcount - 1
        if rotation_point = 0
            p.cx = p.cx + points[i*2]; p.cy = p.cy + points[i*2 + 1]
        else
            p.cx = rotation_point[0] * pcount 'rotation_point_x
            p.cy = rotation_point[1] * pcount ' rotation_point_y
        endif
    next

    p.cx = p.cx/pcount; p.cy = p.cy/pcount
    p.trans = copy(p.org)
  
    ' AddTo
    ' -----
    ' Add to list of lines.
    p.AddTo = function(lines)
        foreach ln in .trans  lines[sizeof(lines)] = ln
    endfunc

    ' X
    ' -
    ' Return x coordinate.
    p.X = function()
        return .x
    endfunc
  
    ' Y
    ' -
    ' Return y coordinate.
    p.Y = function()
        return .y
    endfunc
  
    ' Angle
    ' -----
    ' Return angle.
    p.Angle = function()
        return .a
    endfunc
  
    ' SetTransform
    ' ------------
    ' Set position and angle and apply.      
    p.SetTransform = function(x, y, angle)
        .x = x
        .y = y
        .a = angle
        .Transform()
    endfunc
  
    ' SetPosition
    ' -----------
    ' Set position and apply.
    p.SetPosition = function(x, y)
        .x = x
        .y = y
        .Transform()
    endfunc
  
    ' SetAngle
    ' --------
    ' Set angle and apply.
    p.SetAngle = function(angle)
        .a = angle
        .Transform()
    endfunc
  
    ' Transform
    ' ---------
    ' Update transformed polygon.
    p.Transform = function()
        RotateLines(.org, .trans, .cx, .cy, .a)
        foreach ln in .trans
            ln[0] = ln[0] + .x; ln[1] = ln[1] + .y
            ln[2] = ln[2] + .x; ln[3] = ln[3] + .y
            ln[4] = (ln[2] - ln[0])/ln[6]; ln[5] = (ln[3] - ln[1])/ln[6]
        next
    endfunc
  
    p.Transform()
  
    return p
  
    ' RotateLines
    ' -----------
    ' Helper.
    function RotateLines(srcLines, dstLines, aroundX, aroundY, angle)
        c = cos(angle); s = sin(angle)
        for i = 0 to sizeof(srcLines) - 1
            srcLn = srcLines[i]; dstLn = dstLines[i]
            x = srcLn[0] - aroundX; y = srcLn[1] - aroundY
            dstLn[0] = aroundX + x*c - y*s; dstLn[1] = aroundY + y*c + x*s
            x = srcLn[2] - aroundX; y = srcLn[3] - aroundY
            dstLn[2] = aroundX + x*c - y*s; dstLn[3] = aroundY + y*c + x*s
        next
    endfunc  
endfunc


' Rectangle
' ---------
function Rectangle(x, y, w, h)
    w = w - 1
    h = h - 1
    return Polygon([0, 0, w, 0, w, h, 0, h], x, y, true,0)
endfunc

' Line
' ----
' Return a new line.
function Line(x0, y0, x1, y1)
    ln = [x0, y0, x1, y1]
    dx = ln[2] - ln[0]; dy = ln[3] - ln[1]
    ln[6] = sqr(dx*dx + dy*dy)
    ln[4] = dx/ln[6]
    ln[5] = dy/ln[6]
    return ln
endfunc

'-------------------------
function angle_rad(x0,y0,x1,y1)
dx = x1 - x0
dy = y1 - y0
   
angle_r = atan2(dx,dy)
return angle_r
endfunc
'-----------------------
function get_vecs(angle_r)
vector_x =  -cos(angle_r - PI)
vector_y = sin(angle_r - PI)

return [vector_x,vector_y]
endfunc
'-----------------------
function game_over()
set caret 240,320
set justification center
write "GAME OVER"
'pln "GAME OVER"
redraw
wait 4000
obj.x = 472
obj.y = 632
score = 0
endfunc

Print this item

  Raycaster
Posted by: johnno56 - 04-28-2024, 10:08 PM - Forum: NaaLaa 6 Questions - Replies (5)

Building a level, walls; floors and ceilings, I can do... but I get a little confused with placing items... I can place item on the ceiling and floors ok. But the "indexes" for the items I am not all that familiar. Do the "item" indexes have to be the same as the image "indexes"?

   

Would there be a RC PDF squirreled away on some drive per chance?

Print this item

  Wolf3D test
Posted by: johnno56 - 04-27-2024, 02:27 AM - Forum: NaaLaa 7 Code - Replies (3)

This is just a walls, floor and ceiling layout of the first level modeled after the actual Wolf3D game... This is just a navigable concept level of 64x64 tiles... just to see how N7 copes performance wise...

I will probably use a different tileset for the complete game (assuming I can get that far... lol)... It would be a good idea not to step on Apogee's toes... lol

Of course, the usual constructive criticisms and suggestions, are always welcome....

J


.zip   level1a.zip (Size: 470.2 KB / Downloads: 11)

ps: I modified the display to "double" for "my" screen. Edit as you see fit...

Print this item

  The Maze II
Posted by: 1micha.elok - 04-26-2024, 06:23 AM - Forum: NaaLaa 7 Code - Replies (4)

THE MAZE II
       
click each image to zoom in

Disclaimer                                                        
No person or entity associated with this game received payment or anything of value, or entered into any agreement,              
in connection with the depiction of the ancient egyptian culture  and with any game assets used in this game.                                          \
No mummies were harmed in the making of this game. Any similarity to any person living or dead is coincidental      

Stage
 Stage 1. Sand Desert in s3d
             First thing first, find a hieroglyph magic spell. Without the spell, you can't eliminate a mummy.
             Cast the spell in a relative close distance. But, don't too close to the mummy.
             control key : SPACE BAR, Mouse, S

 Stage 2. Maze inside the Pyramid in wolf3d
              The maze grid size is small, so you don't need a map. 
              The maze is auto-generated using random maze algorithm.
             control key : LEFT, RIGHT, UP, DOWN, SPACE BAR

          -. Find a key to hidden knowledge
          -. Enjoy your egyptian treasures
          -. Taste the magical amulet
          -. Wear a super diamond
          -. Search for the Pharaoh's Sceptre

 Hints :
 1. Turn on your best sound system. Experience the creepy atmosphere. Don't play this game after midnight.
 2. Don't skip or press ESC too soon, just enjoy every scene.

Note :
This game uses new library of s3d.  It's really injected new fresh energy into the classic horror theme  with its contemporary and somewhat experimental approach to the 3D world. Thanks to Marcus for providing feedback especially on how to put a mummy and example on how to use heightmap using s3d library and thanks to Johnno for MazeGen



Attached Files
.zip   maze2_v2.zip (Size: 2.01 MB / Downloads: 7)
Print this item

  Wolf3D
Posted by: johnno56 - 04-23-2024, 10:04 PM - Forum: NaaLaa 7 Questions - Replies (24)

@Marcus,

If memory serves correctly, at one time, you stated that Wolf3D did not have an editor...  I have noticed that the command structure for Wolf3D is quite similar to that of N6's Raycaster. Is it at all possible that the RC editor may be modified for Wolf3D use? But, then again, what about using the Tilemap Editor? Even if it is to just create the a "map[]" file to be read by Wolf3D... Just a thought or two... (Ok... You can stop chuckling now... *sighh*)

I made a very crude "platformer" 'map' editor, using a language that shall not be named, but it is quite limited in what it can do... but, what it does do, is create a text file of the level map. I suppose, assuming I have the ability to do so, I could try to modify the output file to reflect the same structure "map = []" uses... Warning: This will be a "stretch" for me... I am not certain that I can properly convert the base program to N7... If I can, then I shall discuss the limitations in more detail... Please do not hold your breath whilst you wait.... lol

J

Print this item

  That 3d thing
Posted by: Marcus - 04-20-2024, 11:34 PM - Forum: NaaLaa 7 Code - Replies (75)

I just thought I'd post an example of the current state of that 3d thing I'm working on. It's just an executable where you walk around in a level created with the editor. No source code or editor included this first time. There are still no "sub sectors", so a single sector always have the same floor and wall height. Next time I promise you more advanced rooms and some decoration meshes.

Walk with WASD and look around with the mouse. There is a settings menu where you can change some graphical things and mouse sensitivity (the menu pops up as soon as you start, and you can bring it up again with the escape key).

[Image: that_thing_editor.jpg]

[Image: that_thing.jpg]

Edit You will see that the walls "wiggle" when you walk along them at close range. That's an effect caused by lerping instead of doing fully perspective correct texture mapping. I may improve that the next time I update the S3D library. But that will have to wait until this engine is ready and I've made a game with it.



Attached Files
.zip   that_thing.zip (Size: 777.82 KB / Downloads: 6)
Print this item

  N7 Lander 2
Posted by: johnno56 - 04-19-2024, 11:12 PM - Forum: NaaLaa 7 Code - Replies (3)

Do not ask about version one. Let's not go there... lol

Anyway... Here is version 2 using the new pixeli() command for collision detection.

You know how it works. Left and right arrow keys to move left and right. Up arrow to apply vertical thrust. Land on the green Pad. (Not too fast) Watch your fuel... there is no more until the very last level. Spoiler alert: Hold your breath for level nine.

ToDo:

Collision detection still flaky for level 10.
No background noise or music track.... open to suggestions.
Add "your" recommendations... (assuming "I" can do it. lol)


.zip   lander2.zip (Size: 952.26 KB / Downloads: 15)

Print this item

  HELP. The Mummy in s3d
Posted by: 1micha.elok - 04-18-2024, 12:52 PM - Forum: NaaLaa 7 Questions - Replies (3)

New S3d Library

           
click each image to zoom - in

The mummy is everywhere when I am facing North, South, West etc ... lol .....
Is there a way to put the mummy somewhere in certain coordinate (x,y,z) ?

Code:
'==================================================
' THE MAZE II
' Part 1. Sand Desert
' Part 2. to be
' Part 3. to be
'
' Control :
' SPACE     = move forward
' Mouse     = see around
'
' Reference :
' - s3d.n7 library, ex6_heightmap.n7 by Marcus
'
' Sand texture https://images.app.goo.gl/QwsHZq7hZVdyNXB76
' Mummy1 https://images.app.goo.gl/uiosCKdMHraZPfoC7
' Title https://images.app.goo.gl/AGLmRC8g9vQDg21Q6
'==================================================


'----------------
' INITIALIZATION
'----------------
include "data_maze2/heightmap_library.n7"
include "s3d.n7"; S3D_SetView(primary, rad(90), 0.1, 5)
set window "Maze 2 - Part 1.Sand Desert",400,200,false,3
set mouse off
set redraw off

'color definition
gray         = [128,128,128]
black        = [0,0,0]
white        = [255,255,255]
red          = [255,0,0]
green        = [0,255,0]
darkgreen    = [0,128,0,120]

' Heightmap and Ground
heightmapImg = loadimage("data_maze2/heightmap.png");hm = CreateHeightmap(heightmapImg, 8)
groundImg    = loadimage("data_maze2/ground.png")

' Camera
camX         = 32   ; camY          = 0 ; camZ      = 32 'position
camYaw       = 0    ; camPitch      = 0                  'rotation
camBobAngle  = 0    ; camBobEffect  = 0                  'when the user moves

' Mummy
mummy = []
mummy[1] = []
mummy[1].img = loadimage("data_maze2/mummy1.png")

' misc initial value
dt = 0.003
map = [] 'little map
map.x = width(primary)-100
map.z = height(primary)-80
map.w = width(heightmapImg)
map.h = height(heightmapImg)
map.r = map.w/2        'radius
map.cx = map.x+map.w/2 'center
map.cz = map.z+map.h/2 'center
map.a  = 0             'angle
pos = [] 'player's position
pos.x = 0
pos.y = 0
pos.z = 0

'-----------
' GAME LOOP
'-----------
while not keydown(KEY_ESCAPE, true)
    '----------
    ' control
    '----------
    ' Rotation
    mdx = mouserelx(); mdy = mouserely()
    camYaw = (camYaw + mdx*45*dt)%360 ; camPitch = min(max(camPitch - mdy*45*dt, -60), 60)
    set mouse width(primary)/2, height(primary)/2
   
    ' Movement
    dx = 0; dz = 0
    if keydown(KEY_SPACE)
        dx = dx + sin(rad(camYaw))
        dz = dz + cos(rad(camYaw))
    endif
    if dx or dz
        camBobAngle = camBobAngle + 500*dt          'when the user moves
        k = dt/sqr(dx*dx + dz*dz)
        camX = camX + k*dx                          'position X                 
        camZ = camZ + k*dz                          'position Z
        camBobEffect = min(camBobEffect + 4*dt, 1)  'when the user moves
    endif
    camY = hm.GetY(camX, camZ) - 0.5                'position Y
    pos.x = str(camX,0,1)
    pos.y = str(camY,0,1)
    pos.z = str(camZ,0,1)   
    map.a = 90-camYaw

    '------------
    ' rendering
    '------------
    ' Fill screen with the fog color.
    set color gray; cls

    ' Rendering Process
    S3D_Clear()
    S3D_SetSorting(S3D_BACK_TO_FRONT)
    S3D_SetDepthBuffer(S3D_Z_BUFFER_WRITE)
    S3D_RotateX(rad(-camPitch))
    S3D_RotateY(rad(-camYaw))
    S3D_Translate(-camX, -camY + 0.04*camBobEffect*sin(rad(camBobAngle)), -camZ)
    S3D_Texture(groundImg)
    S3D_Mesh(hm.mesh, 0)
    S3D_Render()
    S3D_RenderFog(gray[0],gray[1],gray[2],false)
       
    ' Just simple draw image
    set color white
    draw image mummy[1].img, 20,20               
       
    '------------
    ' navigation
    '------------
    set color black
        set caret 0,0; wln "Angle "+camYaw 'camYaw = 0 south, 90 east, 180 north, 270 west
        wln "Position "+pos.x+","+pos.y+","+pos.z
    set color darkgreen ; draw ellipse map.cx,map.cz,map.r,map.r,true
    set color green     
        draw ellipse map.cx,map.cz,map.r,map.r
        draw line    map.cx,map.cz,map.cx+map.r*cos(rad(map.a)),map.cz+map.r*sin(rad(map.a))
    set color red       ; draw ellipse (map.x+int(pos.x)),(map.z+int(pos.z)),2,2,true
    set color white     ; draw ellipse (map.x+int(pos.x)),(map.z+int(pos.z)),2,2
        set caret map.cx-18, map.z-13; wln "North" 
        set caret map.cx-18, map.z+map.h; wln "South"
        set caret map.x-35, map.cz-5; wln "West"
        set caret map.x+map.w+5, map.cz-5; wln "East"
   
    redraw
    wait 1
wend



Attached Files
.zip   maze2.zip (Size: 93.07 KB / Downloads: 5)
Print this item

  Circle-line collision
Posted by: Marcus - 04-16-2024, 03:59 PM - Forum: NaaLaa 7 Code - Replies (9)

I wrote a quick test for how collisions between moving objects (player and enemies) and the static walls should work in that 3d thing I'm working on. In the game/engine I will just check for collisions with walls close to the moving objects (a uniform grid will contain information about which walls passes through each cell). But maybe someone may still find this test useful for their own purposes:

Code:
set window "Collision", 640, 480
set redraw off

lines = []
randomize 11
for i = 1 to 8
    ln = [rnd(640), rnd(480), rnd(640), rnd(480)]
    dx = ln[2] - ln[0]; dy = ln[3] - ln[1]
    ln[6] = sqr(dx*dx + dy*dy)
    ln[4] = dx/ln[6]
    ln[5] = dy/ln[6]
    lines[sizeof(lines)] = ln
next

obj = Object(320, 240, 16)

while not keydown(KEY_ESCAPE, true)
    'obj.x = mousex(); obj.y = mousey()
    if keydown(KEY_LEFT)  obj.x = obj.x - 4
    if keydown(KEY_RIGHT)  obj.x = obj.x + 4
    if keydown(KEY_UP)  obj.y = obj.y - 4
    if keydown(KEY_DOWN)  obj.y = obj.y + 4   
    PushOut(obj, lines)
   
    set color 0, 0, 0
    cls
    set color 255, 255, 255
    DrawLines(lines)
    obj.Draw()
   
    set caret width(primary)/2, 0
    center "Use the arrow keys to move the circle around"
   
    redraw
    fwait 60
wend

function DrawLines(lines)
    foreach ln in lines  draw line ln[0], ln[1], ln[2], ln[3]
endfunc

function Object(x, y, r)
    return [x: x, y: y, r: r, rsqr: r*r,
            Draw: function(); draw ellipse .x, .y, .r, .r, false; endfunc]
endfunc

function PushOut(obj, lines)
    ' Let all lines push the object around a maximum of 10 times. This is not a recommended
    ' approach, just for testing.
    tests = 10
    for i = 1 to tests
        col = false
        foreach ln in lines
            dp = max(0, min(ln[6], (obj.x - ln[0])*ln[4] + (obj.y - ln[1])*ln[5]))
            px = ln[0] + dp*ln[4]; py = ln[1] + dp*ln[5]
            dx = obj.x - px; dy = obj.y - py
            d = dx*dx + dy*dy
            if d < obj.rsqr
                k = 1/sqr(d)
                obj.x = px + dx*k*obj.r
                obj.y = py + dy*k*obj.r
                col = true
            endif
        next
        if not col break
    next
endfunc

This is pretty much how I did it in the GLOOM library for n6 too, if my memory is correct (source code since long gone).

Print this item