Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - PeeJay

#196
Thanks Gernot - works a treat - down to 5ms now :)

D²O - your video card is obviously a tad better than mine! :D
#197
Sure. In this code:

Code (glbasic) Select
// --------------------------------- //
// USEASBMP bug
// --------------------------------- //

SETSCREEN 640,480,1

WHILE KEY(01)=FALSE

FOR loop=1 TO 100
SETPIXEL RND(640),RND(480),RGB(200,0,0)
NEXT

time1=GETTIMERALL()
USEASBMP
time=GETTIMERALL()-time1

PRINT "TIME TAKEN : "+time,0,460

SHOWSCREEN

WEND
I'm averaging around 1700ms for the USEASBMP command to work. Windowed makes no difference. Changing to 320x240 speeds it up to around 1680ms
#198
I manage to get around 2 frames per second here if I include USEASBMP in my code. I know my video card is hardly earth shattering (a NVidia FX5500) but that can't be right, surely?
#199
Okay, as the starfield coding seems to have been evolving :)  (and because I fancied porting some Blitz code over), I've done a 3D starfield myself. Movement is currently randomized, but it will move in the x and y planes, and will rotate on the z axis, plus there is motion blur on the stars and variable brightness depending on their distance.

I wonder what the next offering will bring? :D

Code (glbasic) Select
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
//                                                                      //
// Project: GLStarfield                                                 //
//                                                                      //
// (C)opyright PeeJay 2008                    www.peejays-remakes.co.uk //
//                                                                      //
// A 3D Starfield with movement and motion blur - the full monty! :o)   //
//                                                                      //
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//

SETSCREEN 640,480,0
LIMITFPS 60

GLOBAL ax,ay,az,axvel,ayvel,azvel,axacc,ayacc,azacc,cx,sx,cy,sy,cz,sz

TYPE star
    x
    y
    z
    zvel
    prevx
    prevy
ENDTYPE
GLOBAL stars[] AS star

SetupStars()

WHILE TRUE

axacc=axacc+((RND(12)-6)/10000)
ayacc=ayacc+((RND(12)-6)/10000)
azacc=azacc+((RND(12)-6)/10000)

axvel=axvel+axacc ; ayvel=ayvel+ayacc ; azvel=azvel+azacc

axacc=axacc*0.99 ; ayacc=ayacc*0.99 ; azacc=azacc*0.99
axvel=axvel*0.99 ; ayvel=ayvel*0.99 ; azvel=azvel*0.99

ax=(ax+axvel)*0.99 ; ay=(ay+ayvel)*0.99 ; az=(az+azvel)*0.99

cx=COS(ax) ; sx=SIN(ax) ; cy=COS(ay) ; sy=SIN(ay) ; cz=COS(az) ; sz=SIN(az)

    DoStars()
   
WEND

END

FUNCTION SetupStars:

    LOCAL loop
   
    FOR loop=1 TO 300
    LOCAL st AS star
    st.x=RND(800)-400
    st.y=RND(800)-400
    st.z=100+RND(900)
    st.zvel=RND(5)+0.5
    st.prevx=-1000
    st.prevy=0
    DIMPUSH stars[],st
    NEXT

ENDFUNCTION

FUNCTION DoStars:

LOCAL tx,tz,ty,tx2,x,y,xd,yd,bl,br

BLACKSCREEN

FOREACH st IN stars[]
IF st.prevx<0 OR st.prevx>640 OR st.prevy<0 OR st.prevy>480 OR st.z<1
    st.x=RND(800)-400
    st.y=RND(800)-400
    st.z=100+RND(900)
    st.zvel=RND(5)+0.5
    st.prevx=-1000
    st.prevy=0
ENDIF

st.z=st.z-st.zvel

tx=(st.x*cy)+(st.z*sy) ; tz=(st.z*cy)-(st.x*sy) ; ty=(st.y*cx)+(tz*sx)
tz=(tz*cx)-(st.y*sx) ; tx2=(tx*cz)+(ty*sz) ; ty=(ty*cz)-(tx*sz) ; tx=tx2

x=((tx/tz)*100)*3+320 ; y=((ty/tz)*100)*3+240

IF st.prevx=-1000
xd=0 ; yd=0 ; bl=1
ELSE
xd=x-st.prevx ; yd=y-st.prevy ; bl=SQR((xd*xd)+(yd*yd))
ENDIF

br=255-((st.z*255)/1000) ; br=(br*st.zvel)/6

IF bl>1 AND bl<50
DRAWLINE x,y,st.prevx,st.prevy,RGB(br,br,br)
ELSE
SETPIXEL x,y,RGB(br,br,br)
ENDIF

st.prevx=x ; st.prevy=y

NEXT

SHOWSCREEN

ENDFUNCTION
#200
Beta Tests / Maze tiler test
2008-Jan-21
The bug fix is out - it meant that there was the possibility of having a block of 3x3 gap near the maze edges - this was due to me compacting everything into one function (and making a hash of it!), but has now been fixed.

Entry and exit points can be anywhere around the edges of the maze with the variable value being an odd number (eg
  • [7] or
  • [21] or [13][0] - you get the idea!). When I get some time, I will look at adding A* path finding (which is what I used in my Maziacs game)

As for variable thicknesses for walls and paths, this is not practical. Given your example of 3 tiles for the path and one for the wall, if a column has 5 path cells and 5 wall cells, that would make (5.3+5 cells = 20 cells) - but if the next row had 6 path calls and 4 wall cells, that would mean (6.3+4 cells = 22 cells), thus meaning the whole maze shape would become totally distorted and unmanageable
#201
Apologies to those that have already used this function - unfortunately there was a small bug that crept in (during porting and compacting into one function) that meant when generating an exact maze, it was possible to have empty gaps of 3x3 near the maze edges.

Here is the bugfixed version:

Code (glbasic) Select
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
//                                                                      //
// Project: Random Maze Generator Function for GLBasic                  //
//                                                                      //
// (C)opyright PeeJay December 13th 2007      www.peejays-remakes.co.uk //
//              bugfix January 21st 2008                                //
//                                                                      //
// Code is free to use for FREEWARE projects only, though credit would  //
// still be welcomed if you decide to use it                            //
//                                                                      //
// Please contact me through my website for conditions on using this    //
// code in shareware, commercial, or other revenue generating projects  //
//                                                                      //
// This function will randomly generate a 2D map of practically any     //
// size very quickly, storing the result in an array for ease of use    //
//                                                                      //
// I have used this code in DarkBasic, BlitzBasic, and now I offer it   //
// to the GLBasic community. For the first time, I have reduced the     //
// code to fit in one function for maximum simplicity                   //
//                                                                      //
// Not surprisingly, the code is fairly complex - even more so by the   //
// fact I've not added comments! However, it is a self contained,       //
// robust, standalone function, so anyone should be able to use it      //
// without needing to understand the methodology behind it              //
//                                                                      //
// The code will produce either an exact maze, or one that is more      //
// open. An exact maze is defined as one where there is only one route  //
// from any point in the maze to any other point in the maze            //
//                                                                      //
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//

DIM maze[0][0]
DIM pjcos[4]
DIM pjsin[4]

LOCAL loop,loop1,time1,time2

WHILE TRUE

REDIM maze[0][0];REDIM maze[79][59] // Reset maze

time1=GETTIMERALL()
MakeMaze(maze[],1) // Maze (maze[] must be DIMed), exact=1, not exact=0
time2=GETTIMERALL()

FOR loop=0 TO 78
FOR loop1=0 TO 58
IF maze[loop][loop1]=1
DRAWRECT 4+(loop*8),4+(loop1*8),8,8,RGB(64,64,0)
DRAWRECT 5+(loop*8),5+(loop1*8),6,6,RGB(96,48,0)
ENDIF
NEXT
NEXT

PRINT "Maze Generated in "+INTEGER(time2-time1)+" milliseconds",180,220

SHOWSCREEN

MOUSEWAIT
WEND

END

// -------------------------------------------------------------------- //

FUNCTION MakeMaze: pjmaze[], pjexact

LOCAL pjmx = BOUNDS(pjmaze[],0)-1
LOCAL pjmy = BOUNDS(pjmaze[],1)-1
LOCAL pjfx,pjfy,pjloop,pjypos,pjxpos,pjfarx,pjfary,pjallx,pjally,pjalldir
LOCAL pjgo,pjtemp,pjx,pjy,pjdir,pjresult,pjlop,pjx2,pjy2,pjtemp2

pjcos[0]=1
pjcos[2]=-1
pjsin[1]=1
pjsin[3]=-1

FOR pjfx=0 TO pjmx
pjmaze[pjfx][0]=1
pjmaze[pjfx][pjmy]=1
NEXT

FOR pjfy=0 TO pjmy
pjmaze[0][pjfy]=1
pjmaze[pjmx][pjfy]=1
NEXT

FOR pjloop=1 TO pjmy/6
pjypos=RND((pjmy-6)/2)*2
pjxpos=RND(2)*2
FOR pjfx=1 TO pjxpos
pjmaze[pjfx][pjypos]=1
NEXT
pjypos=RND((pjmy-6)/2)*2
pjxpos=pjmx-(RND(2)*2)
FOR pjfx=pjmx TO pjxpos STEP -1
pjmaze[pjfx][pjypos]=1
NEXT
NEXT
FOR pjloop=1 TO pjmx/6
pjxpos=4+RND((pjmx-8)/2)*2
pjmaze[pjxpos][pjmy-1]=1
pjmaze[pjxpos][pjmy-2]=1
NEXT

pjfarx=pjmx
pjfary=pjmy
pjallx=0
pjally=0
pjexact=pjexact+1

WHILE TRUE
WHILE TRUE

pjallx=pjallx+pjcos[pjalldir]*pjexact
pjally=pjally+pjsin[pjalldir]*pjexact
pjgo=pjgo+pjexact

IF pjgo>=pjfarx-pjexact AND (pjalldir=0 OR pjalldir=2)
pjgo=0
pjfarx=pjfarx-pjexact
pjtemp=pjalldir+1
pjalldir=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)
ENDIF
IF pjgo>=pjfary-pjexact AND (pjalldir=1 OR pjalldir=3)
pjgo=0
pjfary=pjfary-pjexact
pjtemp=pjalldir+1
pjalldir=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)
ENDIF

IF pjfarx<=0 OR pjfary<=0 THEN BREAK
IF pjmaze[pjallx][pjally]=1 AND (pjallx
WEND

IF pjfarx<=0 OR pjfary<=0 THEN BREAK
IF pjallx>=pjmx OR pjally>=pjmy THEN BREAK

pjx=pjallx
pjy=pjally
pjdir=RND(3)

WHILE TRUE

FOR pjloop=0 TO 3
pjresult=1
FOR pjlop=1 TO pjexact+1
pjx2=pjx+pjcos[pjloop]*pjlop
pjy2=pjy+pjsin[pjloop]*pjlop
IF pjx2<=0 OR pjy2<=0 OR pjx2>pjmx OR pjy2>pjmy THEN pjresult=0
IF pjresult=1
IF pjmaze[pjx2][pjy2]=1 THEN pjresult=0
ENDIF
IF pjresult=1
pjtemp=pjloop+1
pjtemp2=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)
IF pjmaze[pjx2+pjcos[pjtemp2]][pjy2+pjsin[pjtemp2]]=1 THEN pjresult=0
ENDIF
IF pjresult=1
pjtemp=pjloop-1
pjtemp2=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)
IF pjmaze[pjx2+pjcos[pjtemp2]][pjy2+pjsin[pjtemp2]]=1 THEN pjresult=0
ENDIF
NEXT
IF pjresult=1 THEN BREAK
NEXT

IF pjloop=4 THEN BREAK

pjtemp=pjdir+1-RND(2)
pjdir=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)

pjresult=1
FOR pjlop=1 TO pjexact+1
pjx2=pjx+pjcos[pjdir]*pjlop
pjy2=pjy+pjsin[pjdir]*pjlop
IF pjx2<=0 OR pjy2<=0 OR pjx2>pjmx OR pjy2>pjmy THEN pjresult=0
IF pjresult=1
IF pjmaze[pjx2][pjy2]=1 THEN pjresult=0
ENDIF
IF pjresult=1
pjtemp=pjdir+1
pjtemp2=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)
IF pjmaze[pjx2+pjcos[pjtemp2]][pjy2+pjsin[pjtemp2]]=1 THEN pjresult=0
ENDIF
IF pjresult=1
pjtemp=pjdir-1
pjtemp2=pjtemp-4*(pjtemp>3)+4*(pjtemp<0)
IF pjmaze[pjx2+pjcos[pjtemp2]][pjy2+pjsin[pjtemp2]]=1 THEN pjresult=0
ENDIF
NEXT

IF pjresult=1
FOR pjloop=1 TO pjexact
pjx=pjx+pjcos[pjdir]
pjy=pjy+pjsin[pjdir]
pjmaze[pjx][pjy]=1
NEXT
ENDIF
WEND
WEND

IF pjexact=2
FOR pjfx=2 TO pjmx-2 STEP 2
IF pjmaze[pjfx][2]=0
pjmaze[pjfx][2]=1 ; pjmaze[pjfx][1]=1
ENDIF
IF pjmaze[pjfx][pjmy-2]=0
pjmaze[pjfx][pjmy-2]=1 ; pjmaze[pjfx][pjmy-1]=1
ENDIF
NEXT
FOR pjfy=2 TO pjmy-2 STEP 2
IF pjmaze[2][pjfy]=0
pjmaze[2][pjfy]=1 ; pjmaze[1][pjfy]=1
ENDIF
IF pjmaze[pjmx-2][pjfy]=0
pjmaze[pjmx-2][pjfy]=1 ; pjmaze[pjmx-1][pjfy]=1
ENDIF
NEXT
ENDIF

ENDFUNCTION
#202
Beta Tests / Maze tiler test
2008-Jan-21
Cool. If you're interested (which I doubt!) the maze generation function is using a modified randomised Prim's algorithm - and I think I may have found a bug in the code :( I'll post a bugfix once I have had a bit of a play .....
#203
No probs - just a couple of tips for you. My coll routine works with circles too (so would save you a function), and you can scrap the
Code (glbasic) Select
   IF x1        dx = x2 - x1
    ELSE
        dx = x1 - x2
    ENDIF
    IF y1        dy = y2 - y1
    ELSE
        dy = y1 - y2
    ENDIF
bit anyway - it doesn't matter if it produces a negative value, since you are going to square it, so it will always give a positive result.

In your example, it will be pretty accurate, purely because of the smaller size of your ellipses - in my code, I made them pretty huge, thus magnifying the error so you could see it clearly.

I also used a very crap method of drawing the ellipse deliberately so you could see how the maths was done - purely because it is the same maths that is use to calculate the radius at any locus around the ellipse.

Anyhoo, happy to help :)

Edit: Oh, I should point out that this code only allows for collisions where the major axis and minor axis are perpendicular to each other (so not a skewed ellipse), and that they correspond to the x and y axis of the screen (so not on a slant.) I could code for these eventualities at a push, but then the maths starts to get really messy! Also, it does not cover ovoid shapes (eggs!) - this is where the minor axis is perpendicular to the major axis, but is offset from the central position. Again, I could code it, but then the maths goes from the sublime to the ridiculous! :D
#204
You may find this useful - http://en.wikipedia.org/wiki/Flood_fill
#205
Okay, here you go, Be aware that while the maths is perfect, the limitations of accuracy within GL do not allow for pixel perfect calculations (sometimes it is several pixels out!) - this is only true of the elliptical calculations (where the trigonometrical functions require the greater accuracy.)  I'll leave it to someone else to code in C (not my forte, I'm afraid!)

Code (glbasic) Select
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
//                                                                      //
// Project: Oval Collisions in GL Basic                                 //
//                                                                      //
// (C)opyright PeeJay 2008                    www.peejays-remakes.co.uk //
//                                                                      //
// Rough and ready code for drawing ovals, but, more signifanctly,      //
// code to check for collisions between circles and ovals (ellipses)    //
//                                                                      //
// Important Note: This is NOT accurate - in order to achieve pixel     //
// perfect accuracy, it would be necessary to use a C inline call to    //
// take advantage of the 64 bit precision. This has only been coded to  //
// demonstrate the maths behind it.                                     //
//                                                                      //
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//

SETSCREEN 640,480,1
LIMITFPS 60

LOCAL mx,my,b1,b2

WHILE KEY(01)=0

MOUSESTATE mx,my,b1,b2

DrawOval(320,240,180,100,200,0,0)
DrawOval(mx,my,50,80,200,200,0)

IF CollideOval(320,240,180,100,mx,my,50,80)
PRINT "COLLISION!",280,234
ENDIF

SHOWSCREEN

WEND

END

FUNCTION DrawOval: x,y,rx,ry,cr,cg,cb // x,y are centre, rx,ry are radii

LOCAL ang

FOR ang=0 TO 360 STEP 0.5
SETPIXEL x+rx*COS(ang),y+ry*SIN(ang),RGB(cr,cg,cb)
NEXT

ENDFUNCTION

FUNCTION CollideOval: x1,y1,rx1,ry1,x2,y2,rx2,ry2

LOCAL rad1,rad2,dx,dy,distx,disty,a

IF rx1=ry1 // circle - fairly accurate
rad1=rx1
ELSE
a=ATAN(y2-y1,x2-x1) // ellipse - needs 64 bit accuracy
IF a<0 THEN a=360+a
dx=rx1*COS(a)
dy=ry1*SIN(a)
rad1=SQR((dx*dx)+(dy*dy))
ENDIF

IF rx2=ry2 // circle - fairly accurate
rad2=rx2
ELSE
a=ATAN(y1-y2,x1-x2) // ellipse - needs 64 bit accuracy
IF a<0 THEN a=360+a
dx=rx2*COS(a)
dy=ry2*SIN(a)
rad2=SQR((dx*dx)+(dy*dy))
ENDIF

distx=x2-x1
disty=y2-y1

IF rad1+rad2>=SQR((distx*distx)+(disty*disty))
RETURN TRUE
ELSE
RETURN FALSE
ENDIF

ENDFUNCTION
#206
It's on my list of things to code :)
#207
Code (glbasic) Select
IF DOESFILEEXIST("/dev/touchscreen/wm97xx")
MOUSEWAIT
ELSE
KEYWAIT
ENDIF
#208
Yes, You need to calculate the angle between the centre of the ellipses (using arctan) - from this, you can calculate the radii at that point, then do the same pythagorean calculation as your circle collision system.
#209
saboteur - why not have a look at my scrolling tilemap code posted here - http://www.glbasic.com/forum/viewtopic.php?id=1336 - and hopefully you'll get a better of idea to use tiles in games to free up resources.
#210
Thanks Neurox - that is great for this, but I still think they are very useful commands for string splicing, for word wrap and the like