### Author Topic: DotBall  (Read 3925 times)

#### fuzzy70

• Community Developer
• Prof. Inline
• Posts: 828
• Look left, Look right, LOOK OUT!!
##### DotBall
« on: 2012-Feb-29 »
Here is my attempt at making an oldschool dot ball, the rotation code I found laying around in an old word document of mine (along with other snippets) so I cannot say with total honesty if I wrote that part or not

I mainly wrote this as an exercise of using functions in types which is slowly beginning to sink in at last & is probably far from the best example. Any suggestions of improvements or if/where I have failed would be welcomed

Code: (glbasic) [Select]
`// --------------------------------- //// Project: dotball// Start: Tuesday, February 28, 2012// IDE Version: 10.244// FREE-VERSION:// Need Premium for Features:// 3D Graphics// Network Commands// INLINE C/C+++ code// SETCURRENTDIR("Media") // go to media filesGLOBAL DB AS dotball, scx, scyGETSCREENSIZE scx, scyTYPE point x y zENDTYPETYPE dotball xrot yrot zrot ballpoints[] AS point FUNCTION createball: pointcount LOCAL theta, phi, loop DIM self.ballpoints[pointcount] FOREACH loop IN self.ballpoints[] theta = RND (180)-90 phi = RND (359) loop.x = (COS(theta) * 10) * (COS(phi) * 10) loop.y = (COS(theta) * 10) * (SIN(phi) * 10) loop.z = SIN(theta) * 100 NEXT ENDFUNCTION FUNCTION drawball: sx,sy,sz LOCAL tmpx, tmpy, tmpz, px, loop, persp, x%, y%, colour% persp = 400 FOREACH loop IN self.ballpoints[] tmpy = ((loop.y * COS(self.xrot)) - (loop.z * SIN(self.xrot))) tmpz = ((loop.y * SIN(self.xrot)) + (loop.z * COS(self.xrot))) tmpx = ((loop.x * COS(self.yrot)) - (tmpz * SIN(self.yrot))) tmpz = ((loop.x * SIN(self.yrot)) + (tmpz * COS(self.yrot))) px = tmpx tmpx = ((tmpx * COS(self.zrot)) - (tmpy * SIN(self.zrot))) tmpy = ((px * SIN(self.zrot)) + (tmpy * COS(self.zrot))) x  = (512 * (tmpx) / (persp - (tmpz))) + (scx/2) y  = (scy/2) - (512 * tmpy) / (persp - (tmpz)) colour = tmpz + 155 DRAWRECT x,y,2,2,RGB(colour,colour,colour) NEXT INC self.xrot , sx INC self.yrot , sy INC self.zrot , sz ENDFUNCTIONENDTYPEDB.createball(500)WHILE TRUE DB.drawball(1,0.75,0.5) SHOWSCREENWEND`
Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

#### Ian Price

• Prof. Inline
• Posts: 4159
• On the shoulders of giants.
##### Re: DotBall
« Reply #1 on: 2012-Feb-29 »
That's really rather nice
I came. I saw. I played.

#### matchy

• Prof. Inline
• Posts: 1545
##### Re: DotBall
« Reply #2 on: 2012-Feb-29 »
Wow simply great.

With various code like this also, I feel an old school sinusoidal intro demo coming on:
http://www.glbasic.com/forum/index.php?topic=7669.0

#### fuzzy70

• Community Developer
• Prof. Inline
• Posts: 828
• Look left, Look right, LOOK OUT!!
##### Re: DotBall
« Reply #3 on: 2012-Feb-29 »
A simple change I just noticed from looking at the code ( & why I did not do it in the 1st place I have no idea ) is to add an x & y to the function call drawball so you can draw it where you like rather than centred. Have changed the code to do that now but you can leave the last 2 parameters off & it will centre it like before.

Lee

Code: (glbasic) [Select]
`// --------------------------------- //// Project: dotball// Start: Tuesday, February 28, 2012// IDE Version: 10.244// FREE-VERSION:// Need Premium for Features:// 3D Graphics// Network Commands// INLINE C/C+++ code// SETCURRENTDIR("Media") // go to media filesGLOBAL DB AS dotball, scx, scyGETSCREENSIZE scx, scyTYPE point x y zENDTYPETYPE dotball xrot yrot zrot ballpoints[] AS point FUNCTION createball: pointcount LOCAL theta, phi, loop DIM self.ballpoints[pointcount] FOREACH loop IN self.ballpoints[] theta = RND (180)-90 phi = RND (359) loop.x = (COS(theta) * 10) * (COS(phi) * 10) loop.y = (COS(theta) * 10) * (SIN(phi) * 10) loop.z = SIN(theta) * 100 NEXT ENDFUNCTION FUNCTION drawball: sx,sy,sz,posx=scx/2,posy=scy/2 LOCAL tmpx, tmpy, tmpz, px, loop, persp, x%, y%, colour% persp = 400 FOREACH loop IN self.ballpoints[] tmpy = ((loop.y * COS(self.xrot)) - (loop.z * SIN(self.xrot))) tmpz = ((loop.y * SIN(self.xrot)) + (loop.z * COS(self.xrot))) tmpx = ((loop.x * COS(self.yrot)) - (tmpz * SIN(self.yrot))) tmpz = ((loop.x * SIN(self.yrot)) + (tmpz * COS(self.yrot))) px = tmpx tmpx = ((tmpx * COS(self.zrot)) - (tmpy * SIN(self.zrot))) tmpy = ((px * SIN(self.zrot)) + (tmpy * COS(self.zrot))) x  = (512 * (tmpx) / (persp - (tmpz))) + (posx) y  = (posy) - (512 * tmpy) / (persp - (tmpz)) colour = tmpz + 155 DRAWRECT x,y,2,2,RGB(colour,colour,colour) NEXT INC self.xrot , sx INC self.yrot , sy INC self.zrot , sz ENDFUNCTIONENDTYPEDB.createball(500)WHILE TRUE DB.drawball(1,0.75,0.5,200,200) SHOWSCREENWEND`
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

#### Slydog

• Prof. Inline
• Posts: 932
• KodeSource
##### Re: DotBall
« Reply #4 on: 2012-Feb-29 »
Ha, I had no idea what this would do until I ran it!   Very cool!

Here's a game idea that came to mind while running this:
- In this room is an invisible object.
- You have a 'gun' that shoots paint dots (like your sphere) towards the invisible object.
- You can rotate the room in all directions to control where you fire your paint dot.
- Eventually the shape of the invisible object will start revealing itself with more paint dots.
- Try to figure out what the invisible object is!  (from a list of common object shapes)
- Scored based on how few paint dots you needed to make accurate guess.
- Or you are trying to get out of an invisible maze, shoot strategic paint dots to see where the walls are.
- Or a form of 'Battleship'.  Shoot dots to reveal / guess where the ships are. (ships could be simple cubes, rectangles)

But still a very cool demo!

 Or instead of ONE invisible object, have multiple very simple shaped objects randomly placed in room, and you have to determine which objects are located where (kinda like the Battleship concept).
« Last Edit: 2012-Feb-29 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

#### fuzzy70

• Community Developer
• Prof. Inline
• Posts: 828
• Look left, Look right, LOOK OUT!!
##### Re: DotBall
« Reply #5 on: 2012-Feb-29 »
Updated now so you can specify scale as well as position (both are optional parameters), hopefully fixed the colour scaling code to return ranges from 0-255, also added a dotcube for the fun of it

Todo :
• Add more objects like a torus, cylinder etc
• Fix the cube code so that Z falls in the -100 to 100 range same as sphere (only for the colour code mainly)
• Add a destroy function to clear the array
• Breakout the common rotation code into it's own function
• Numerous other little tweaks & fixes

Lee
Code: (glbasic) [Select]
`// --------------------------------- //// Project: dotball// Start: Tuesday, February 28, 2012// IDE Version: 10.244// FREE-VERSION:// Need Premium for Features:// 3D Graphics// Network Commands// INLINE C/C+++ code// SETCURRENTDIR("Media") // go to media filesGLOBAL DB AS dotball, DC AS dotcube, scx, scyGETSCREENSIZE scx, scyTYPE point x y zENDTYPETYPE dotball xrot yrot zrot ballpoints[] AS point FUNCTION createball: pointcount LOCAL theta, phi, loop DIM self.ballpoints[pointcount] FOREACH loop IN self.ballpoints[] theta = RND (180)-90 phi = RND (359) loop.x = (COS(theta) * 10) * (COS(phi) * 10) loop.y = (COS(theta) * 10) * (SIN(phi) * 10) loop.z = SIN(theta) * 100 NEXT ENDFUNCTION FUNCTION drawball: sx,sy,sz,posx=scx/2,posy=scy/2,scale=1 LOCAL tmpx, tmpy, tmpz, px, loop, persp, x%, y%, colour% persp = 400 FOREACH loop IN self.ballpoints[] tmpy = ((loop.y * COS(self.xrot)) - (loop.z * SIN(self.xrot))) tmpz = ((loop.y * SIN(self.xrot)) + (loop.z * COS(self.xrot))) tmpx = ((loop.x * COS(self.yrot)) - (tmpz * SIN(self.yrot))) tmpz = ((loop.x * SIN(self.yrot)) + (tmpz * COS(self.yrot))) px = tmpx tmpx = ((tmpx * COS(self.zrot)) - (tmpy * SIN(self.zrot))) tmpy = ((px * SIN(self.zrot)) + (tmpy * COS(self.zrot))) x  = ((scale*512) * (tmpx) / (persp - (tmpz))) + (posx) y  = (posy) - ((scale*512) * tmpy) / (persp - (tmpz)) colour = (tmpz+100) * 1.2 DRAWRECT x,y,2,2,RGB(colour,colour,colour) NEXT INC self.xrot , sx INC self.yrot , sy INC self.zrot , sz ENDFUNCTIONENDTYPETYPE dotcube xrot yrot zrot cubepoints[] AS point FUNCTION createcube: pointcount LOCAL loop, across, down, side DIM self.cubepoints[pointcount] FOREACH loop IN self.cubepoints[] side = RND (5) across = RND (120) down = RND (120) SELECT side CASE 0  // Front face loop.x = across-60 loop.y = down-60 loop.z = 60 CASE 1  // Back face loop.x = across-60 loop.y = down-60 loop.z = -60 CASE 2  // Left face loop.x = -60 loop.y = down-60 loop.z = across-60 CASE 3  // Right face loop.x = 60 loop.y = down-60 loop.z = across-60 CASE 4  // Top face loop.x = across-60 loop.y = 60 loop.z = down-60 CASE 5  // Bottom Face loop.x = across-60 loop.y = -60 loop.z = down-60 ENDSELECT NEXT ENDFUNCTION FUNCTION drawcube: sx,sy,sz,posx=scx/2,posy=scy/2,scale=1 LOCAL tmpx, tmpy, tmpz, px, loop, persp, x%, y%, colour% persp = 400 FOREACH loop IN self.cubepoints[] tmpy = ((loop.y * COS(self.xrot)) - (loop.z * SIN(self.xrot))) tmpz = ((loop.y * SIN(self.xrot)) + (loop.z * COS(self.xrot))) tmpx = ((loop.x * COS(self.yrot)) - (tmpz * SIN(self.yrot))) tmpz = ((loop.x * SIN(self.yrot)) + (tmpz * COS(self.yrot))) px = tmpx tmpx = ((tmpx * COS(self.zrot)) - (tmpy * SIN(self.zrot))) tmpy = ((px * SIN(self.zrot)) + (tmpy * COS(self.zrot))) x  = ((scale*512) * (tmpx) / (persp - (tmpz))) + (posx) y  = (posy) - ((scale*512) * tmpy) / (persp - (tmpz)) colour = (tmpz+100) * 1.2 DRAWRECT x,y,2,2,RGB(colour,colour,colour) NEXT INC self.xrot , sx INC self.yrot , sy INC self.zrot , sz ENDFUNCTIONENDTYPEDC.createcube(1000)DB.createball(1000)WHILE TRUE DC.drawcube(0.5,0.75,1,250,150,1) DB.drawball(1,0.75,0.5,400,400,0.5) SHOWSCREENWEND`
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

#### Wampus

• Prof. Inline
• Posts: 1004
##### Re: DotBall
« Reply #6 on: 2012-Feb-29 »
Thats fun. I flippin love it.

Couple of things I thought of. Try drawing the screen with ALPHAMODE 1.0 to see if you like the effect better than the default mode.  I wonder if you might also get a performance boost by replacing the DRAWRECT command with a series of POLYVECTOR sprites.

Wow simply great.

With various code like this also, I feel an old school sinusoidal intro demo coming on:
http://www.glbasic.com/forum/index.php?topic=7669.0

Do it!

#### fuzzy70

• Community Developer
• Prof. Inline
• Posts: 828
• Look left, Look right, LOOK OUT!!
##### Re: DotBall
« Reply #7 on: 2012-Feb-29 »
Thats fun. I flippin love it.

Couple of things I thought of. Try drawing the screen with ALPHAMODE 1.0 to see if you like the effect better than the default mode.  I wonder if you might also get a performance boost by replacing the DRAWRECT command with a series of POLYVECTOR sprites.

Not to sure about ALPHAMODE mainly because I have not played around with that command yet but will have a go. The DRAWRECT was used as I didn't like the way 1x1 pixels looked & just needed something quick to view the output, also POLYVECTORS are another area I need to play around with as no experience with them as such yet.

Lookup tables for SIN/COS might give a boost, not so much on PC's I think but some of the lower spec targets like WinCE, Cannoo etc might benefit from them.

It was more or less coded in 1 sitting so there are bound to be some further optimisations that can be made as I focused on the effect rather than the performance (as well as learning types a bit more).

Lee

update:

• Rolled the creation of the objects into the same type & made the type an array so you can create multiple objects easy if you need.
• Doing the above has removed duplicate code somewhat
• Added a "killobject" function to freeup memory
Code: (glbasic) [Select]
`// --------------------------------- //// Project: dotobject// Start: Wednesday, February 29, 2012// IDE Version: 10.244// FREE-VERSION:// Need Premium for Features:// 3D Graphics// Network Commands// INLINE C/C+++ code// SETCURRENTDIR("Media") // go to media filesGLOBAL dobj[] AS dotobject, scx, scy, alphaloop, alphastep, ikey\$GETSCREENSIZE scx, scyTYPE point x y zENDTYPETYPE dotobject xrot yrot zrot objectpoints[] AS point FUNCTION createball: pointcount LOCAL theta, phi, loop DIM self.objectpoints[pointcount] FOREACH loop IN self.objectpoints[] theta = RND (180)-90 phi = RND (359) loop.x = (COS(theta) * 10) * (COS(phi) * 10) loop.y = (COS(theta) * 10) * (SIN(phi) * 10) loop.z = SIN(theta) * 100 NEXT ENDFUNCTION FUNCTION createcube: pointcount LOCAL loop, across, down, side DIM self.objectpoints[pointcount] FOREACH loop IN self.objectpoints[] side = RND (5) across = RND (120) down = RND (120) SELECT side CASE 0  // Front face loop.x = across-60 loop.y = down-60 loop.z = 60 CASE 1  // Back face loop.x = across-60 loop.y = down-60 loop.z = -60 CASE 2  // Left face loop.x = -60 loop.y = down-60 loop.z = across-60 CASE 3  // Right face loop.x = 60 loop.y = down-60 loop.z = across-60 CASE 4  // Top face loop.x = across-60 loop.y = 60 loop.z = down-60 CASE 5  // Bottom Face loop.x = across-60 loop.y = -60 loop.z = down-60 ENDSELECT NEXT ENDFUNCTION FUNCTION drawobject: sx,sy,sz,posx=scx/2,posy=scy/2,scale=1 LOCAL tmpx, tmpy, tmpz, px, loop, persp, x%, y%, colour% persp = 400 FOREACH loop IN self.objectpoints[] tmpy = ((loop.y * COS(self.xrot)) - (loop.z * SIN(self.xrot))) tmpz = ((loop.y * SIN(self.xrot)) + (loop.z * COS(self.xrot))) tmpx = ((loop.x * COS(self.yrot)) - (tmpz * SIN(self.yrot))) tmpz = ((loop.x * SIN(self.yrot)) + (tmpz * COS(self.yrot))) px = tmpx tmpx = ((tmpx * COS(self.zrot)) - (tmpy * SIN(self.zrot))) tmpy = ((px * SIN(self.zrot)) + (tmpy * COS(self.zrot))) x  = ((scale*512) * (tmpx) / (persp - (tmpz))) + (posx) y  = (posy) - ((scale*512) * tmpy) / (persp - (tmpz)) colour = (tmpz+100) * 1.2 DRAWRECT x,y,2,2,RGB(colour,colour,colour) NEXT INC self.xrot , sx INC self.yrot , sy INC self.zrot , sz ENDFUNCTION FUNCTION killobject: DIM self.objectpoints[0] ENDFUNCTION ENDTYPEREDIM dobj[2]dobj[0].createball(1000)dobj[1].createcube(500)alphaloop = -1alphastep = 0.01WHILE TRUE ALPHAMODE alphaloop dobj[0].drawobject(1,0.75,0.5,400,400,.25) dobj[1].drawobject(0.5,0.75,1,250,150,1) SHOWSCREEN ikey\$=INKEY\$() IF ikey\$ = "0" THEN dobj[0].killobject() IF ikey\$ = "1" THEN dobj[1].killobject() IF alphaloop > 1.0 THEN alphastep = -0.01 IF alphaloop < -1.0 THEN alphastep = 0.01 INC alphaloop, alphastepWEND`
« Last Edit: 2012-Feb-29 by fuzzy70 »
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)