Author Topic: DotBall  (Read 3432 times)

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
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  :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)

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4158
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: DotBall
« Reply #1 on: 2012-Feb-29 »
That's really rather nice :)
I came. I saw. I played.

Offline matchy

  • Prof. Inline
  • *****
  • Posts: 1544
    • View Profile
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

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
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 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)

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 930
  • KodeSource
    • View Profile
    • 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:
- 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).
« Last Edit: 2012-Feb-29 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
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  :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)

Offline Wampus

  • Prof. Inline
  • *****
  • Posts: 1004
    • View Profile
Re: DotBall
« Reply #6 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.

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!

Offline fuzzy70

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 828
  • Look left, Look right, LOOK OUT!!
    • View Profile
Re: DotBall
« Reply #7 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
« 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)