DotBall

Previous topic - Next topic

fuzzy70

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  :O

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 files
GLOBAL DB AS dotball, scx, scy

GETSCREENSIZE scx, scy

TYPE point
x
y
z
ENDTYPE

TYPE 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

ENDFUNCTION


ENDTYPE


DB.createball(500)


WHILE TRUE

DB.drawball(1,0.75,0.5)

SHOWSCREEN

WEND




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

That's really rather nice :)
I came. I saw. I played.

matchy

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

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 files
GLOBAL DB AS dotball, scx, scy

GETSCREENSIZE scx, scy

TYPE point
x
y
z
ENDTYPE

TYPE 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

ENDFUNCTION


ENDTYPE


DB.createball(500)


WHILE TRUE

DB.drawball(1,0.75,0.5,200,200)

SHOWSCREEN

WEND


"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

#4
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:
- You start with an empty 'room'.
- 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!

[Edit] 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).
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

fuzzy70

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  :D

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  =D

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 files
GLOBAL DB AS dotball, DC AS dotcube, scx, scy

GETSCREENSIZE scx, scy

TYPE point
x
y
z
ENDTYPE

TYPE 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

ENDFUNCTION


ENDTYPE

TYPE 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

ENDFUNCTION


ENDTYPE
DC.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)

SHOWSCREEN

WEND


"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

Thats fun. I flippin love it.  =D

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.

Quote from: matchy 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

Do it!

fuzzy70

#7
Quote from: Wampus on 2012-Feb-29
Thats fun. I flippin love it.  =D

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.

Glad you like it  =D

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).

Your comments for improvements/ideas are appreciated & welcomed, if anyone else has any please post them  =D

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 files

GLOBAL dobj[] AS dotobject, scx, scy, alphaloop, alphastep, ikey$

GETSCREENSIZE scx, scy

TYPE point
x
y
z
ENDTYPE

TYPE 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

ENDTYPE


REDIM dobj[2]
dobj[0].createball(1000)
dobj[1].createcube(500)

alphaloop = -1
alphastep = 0.01
WHILE 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, alphastep

WEND
"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)