Simple goofy game...

Game development specific discussions.
Post Reply
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Simple goofy game...

Post by Dr_D »

I've been a bit bored today, so I made a casual game to play around with. It even uses some sub-pixel line/circle rendering code from Eclipzer, way back in 2008. :p
Anyway, when it starts, it says ready, set, go...
The circle will start tracing the lines around the screen.
The objective is to hit Space when you are right on top of each perpendicular midpoint(the yellow lines)...
It will leave a circle there as a marker, to show you how close you were.
It gives you a score based on average distance, at the end of each level.
A lower score is better.
I hope somebody enjoys it... It helped cure my boredom. lol

Code: Select all

#include "fbgfx.bi"
randomize 1234567
screenres 640,480,32,,FB.GFX_ALPHA_PRIMITIVES

const as single PI = 3.1415926, PI2 = PI*2, PIh = PI/2, PID180 = PI/180


'******sub-line/circle code from Eclipzer from 2008 :D******
union colorClass
as uinteger colour 'color value
type
	as ubyte  b 'color blue  component
	as ubyte  g 'color green component
	as ubyte  r 'color red   component
	as ubyte  a 'color alpha component
end type
declare operator let(value as uinteger) 'define object assignment ....... ex: object=var
declare operator cast() as string       'define object string output .... ex: print object
declare operator cast() as uinteger     'define object numerical output . ex: var=object
declare constructor(byval value as uinteger=&hFF000000)
end union


declare sub sub_line(x1 as integer,y1 as integer,x2 as integer,y2 as integer,thickness as integer,byval colour as colorClass)
declare sub sub_circle(x0 as integer,y0 as integer,radius as integer,thickness as integer,colour as colorClass)
'**********************************************

type vec2f

	declare constructor()

	declare constructor ( byref as vec2f )

	declare constructor ( byref x as single, byref y as single )

	declare function dist( byref vb as vec2f ) as single

	declare function perp( byref b as vec2f ) as vec2f


	as single x,y

end type


type linestruct

	as vec2f p1, p2, mp, norm

end type


type ball_struct

	as vec2f p

	as byte active

end type


declare operator + ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
declare operator + ( byval lhs as vec2f, byval rhs as single ) as vec2f
declare operator - ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
declare operator - ( byval lhs as vec2f, byval rhs as single ) as vec2f
declare operator * ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
declare operator * ( byval lhs as vec2f, byval rhs as single ) as vec2f
declare operator / ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
declare operator / ( byval lhs as vec2f, byval rhs as single ) as vec2f
declare operator / ( byval lhs as vec2f, byval rhs as integer ) as vec2f
declare sub generate_level( levLine() as lineStruct, bPos() as ball_struct )
declare function lines_intersect( byref ipoint as vec2f, byref va as vec2f, byref vb as vec2f, byref vc as vec2f, byref vd as vec2f ) as integer





dim as lineStruct Line1, levLine(0 to 20), tLine
dim as ball_struct bPos(0 to ubound(levLine)+1)
dim as integer bId = 0
dim as byte waitDraw = true
dim as double rad, fTime
dim as integer linecol


generate_level( levLine(), bPos() )


fTime = timer

do

	rad += (timer-fTime)*.4

	fTime = timer

	dim as byte goOn = rad>PI2 and bId>0

	if goOn or multikey(FB.SC_R) then
		
		screenlock
		
		dim as single fDist
		
		for i as integer = 0 to ubound(levLine)
			
			fDist+=levLine(i).mp.Dist(bPos(i).p)*10
			
		next
		
		fDist\=ubound(levLine)
		
		dim as string text = "SCORE = " & fDist
		
		draw string (320-len(text)*4, 240), text
		
		screenunlock
		
		sleep 3000,1

		fTime = timer

		rad = 0

		bId = 0

		waitDraw = true

		generate_level( levLine(), bPos() )

	end if


	Line1.p1 = type(320, 240)
	Line1.p2 = type( 320 + 125 *  cos(rad), 240 + 125 * -sin(rad) )
	tLine.p1 = Line1.p1
	tLine.p2 = type( 320 + 300 *  cos(rad), 240 + 300 * -sin(rad) )


	if multikey(FB.SC_SPACE) then

		if not bPos(bId).active then
			bPos(bId).active = true
			bPos(bId).p = bPos(ubound(bPos)).p
		end if

	end if

	screenlock
	cls

	dim as vec2f intersection_point = Line1.p2

	for i as integer = 0 to ubound(levLine)

		'if lines_intersect( intersection_point, levLine(i).p1, levLine(i).p2, Line1.p1, Line1.p2 ) then
		'linecol = &h0000ff
		'end if

		if lines_intersect( bPos(ubound(bPos)).p, levLine(i).p1, levLine(i).p2, tLine.p1, tLine.p2 ) then
			'clickPos = bPos(ubound(bPos)).p
			bId = i
		end if

		if (i and 1) then

			linecol = rgba(0,0,255,128)

		else

			linecol = rgba(255,0,0,128)

		end if

		sub_line(levLine(i).p1.x, levLine(i).p1.y, levLine(i).p2.x, levLine(i).p2.y,3,linecol)
		sub_line(levLine(i).mp.x, levLine(i).mp.y, levLine(i).mp.x+levLine(i).norm.x*10, levLine(i).mp.y+levLine(i).norm.y*10, 3, rgba(255,255,0,128))
		
		'line(levLine(i).p1.x, levLine(i).p1.y)-(levLine(i).p2.x, levLine(i).p2.y),linecol
		'line(levLine(i).mp.x, levLine(i).mp.y)-(levLine(i).mp.x+levLine(i).norm.x*10, levLine(i).mp.y+levLine(i).norm.y*10), &hffffffff

	next

	'line(tLine.p1.x, tLine.p1.y)-(intersection_point.x, intersection_point.y),&hffff00


	for i as integer = 0 to ubound(bPos)

		if bPos(i).active then
			'circle(bPos(i).p.x,bPos(i).p.y),10,rgb(200,200,0)
			sub_circle(bPos(i).p.x,bPos(i).p.y,10,3,rgba(255,255,0,128))
		end if

	next

	screensync
	screenunlock

	sleep 3,1

	if waitDraw then
		
		dim as string text
		
		screenlock
		text = "READY?"
		draw string (320-len(text)*4, 200), text
		screenunlock		
		sleep 500, 1
		
		screenlock
		text = "SET..."
		draw string (320-len(text)*4, 240), text
		screenunlock		
		sleep 500, 1
		
		screenlock
		text = "GO!!!!!"
		draw string (320-len(text)*4, 280), text
		screenunlock		
		sleep 500, 1
		
		waitDraw = false
		fTime = timer
	end if

loop until multikey(FB.SC_ESCAPE)


constructor colorClass(byval value as uinteger)
	colour=value
end constructor

operator colorClass.let(value as uinteger)
	colour=value
end operator

operator colorClass.cast() as string
	return str(colour)
end operator

operator colorClass.cast() as uinteger
	return colour
end operator


sub sub_line(x1 as integer,y1 as integer,x2 as integer,y2 as integer,thickness as integer,byval colour as colorClass)

	dim as integer alpha=colour.a

	dim as integer t2=thickness/2

	dim as integer bx(1)={x1,x2}
	dim as integer by(1)={y1,y2}

	dim as integer LI=0,RI=1
	dim as integer TI=0,BI=1

	if bx(LI)>bx(RI) then swap LI,RI
	if by(TI)>by(BI) then swap TI,BI

	dim as single dx=(bx(RI)-bx(LI))
	dim as single dy=(by(RI)-by(LI))

	dim as single dydx=dy/dx
	dim as single dydx2=dydx*dydx

	dim as single b=y1-dydx*x1,d

	dim as single ndx=-dy
	dim as single ndy= dx

	dim as single length=sqr(dx*dx+dy*dy)

	dim as single nx=ndx/length
	dim as single ny=ndy/length

	dim as single px,py

	for y as integer=by(TI)-t2 to by(BI)+t2
		for x as integer=bx(LI)-t2 to bx(RI)+t2

			if dx then 'non-vertical line

				d=(dydx*x-y+b)/sqr(dydx2+1) 'point-to-line distance equation

				px=x+d*nx 'projected x
				py=y+d*ny 'projected y

				select case px
					case is < bx(LI)
						dim as single xx=x-bx(LI)
						dim as single yy=y-by(LI)
						d=sqr(xx*xx+yy*yy)

					case is > bx(RI)
						dim as single xx=x-bx(RI)
						dim as single yy=y-by(RI)
						d=sqr(xx*xx+yy*yy)

					case else: d=abs(d)
				end select

			else 'vertical line

				select case y
					case is < by(TI)
						dim as single xx=x-bx(TI)
						dim as single yy=y-by(TI)
						d=sqr(xx*xx+yy*yy)

					case is > by(BI)
						dim as single xx=x-bx(BI)
						dim as single yy=y-by(BI)
						d=sqr(xx*xx+yy*yy)

					case else: d=x-x1
				end select

			end if

			if d<t2 then
				colour.a=alpha
				pset(x,y),colour
			elseif (d-t2)<=1 then
				colour.a=alpha*(1-(d-t2))
				pset (x,y),colour
			end if
		next
	next

end sub


sub sub_circle(x0 as integer,y0 as integer,radius as integer,thickness as integer,colour as colorClass)
  
    dim as single router,rinner,r2
  
    router=radius+thickness/2
    rinner=radius-thickness/2
  
    dim as integer r=router+1,rr
    
    dim as integer alpha=colour.a
  
    if thickness then
      
      for y as integer=-r to r
        for x as integer=-r to r
        
          rr=x*x+y*y
          r2=sqr(rr)
        
          if (r2<router) and (r2>rinner) then 'point between outer and inner radii
            colour.a=alpha
            pset (x0+x,y0+y),colour
          elseif abs(r2-router)<=1 then       'point near outter radius
            colour.a=alpha*(1-(r2-router))
            pset (x0+x,y0+y),colour
          elseif abs(rinner-r2)<=1 then       'point near inner radius
            colour.a=alpha*(1-(rinner-r2))
            pset (x0+x,y0+y),colour
          end if
        
        next
      next
      
    else 'special case: thickness=0
    
      for y as integer=-r to r
        for x as integer=-r to r        
          rr=x*x+y*y
          r2=sqr(rr)        
          if abs(r2-radius)<=1 then
            colour.a=alpha*(1-abs(r2-radius))
            pset (x0+x,y0+y),colour
          end if        
        next
      next
      
    end if
  
end sub


sub generate_level( levLine() as lineStruct, bPos() as ball_struct )

	for ti as integer = 0 to ubound(levLine)

		dim as integer i = ti mod ubound(levLine)
		dim as integer iand1 = (i+1) mod ubound(levLine)

		dim as single rad = i * ( PI2 / ( ubound(levLine) + 1 ) )
		dim as integer rSize = 100 + int( rnd * 150)
		levLine(i).p2 = vec2f(  320 + rSize * cos(rad), 240 + rSize * -sin(rad) )

		levLine(iand1).p1 = levLine(i).p2

	next

	'levLine( ubound(levLine) ).p2 = levLine(0).p1
	'levLine( 1 ).p2 = levLine(2).p1


	for i as integer = 0 to ubound(levLine)

		with levLine(i)

			.mp = (.p1+.p2) / 2
			.norm = .p1.perp(.mp)

		end with

	next


	for i as integer = 0 to ubound(bPos)-1
		bPos(i).active = false
	next
	bPos(ubound(bPos)).active = true

end sub


function lines_intersect( byref ipoint as vec2f, byref va as vec2f, byref vb as vec2f, byref vc as vec2f, byref vd as vec2f ) as integer

	dim as vec2f v1 = vb - va
	dim as vec2f v2 = vd - vc
	dim as vec2f v3 = vc - va
	dim as single perp = (v1.x * v2.y) - (v1.y * v2.x)

	if perp<>0 then
		dim as single d1 = ((v3.x * v2.y) - (v3.y * v2.x)) / perp
		if  d1<=1 and d1>=0 then
			dim as single d2 = ((v3.x * v1.y) - (v3.y * v1.x)) / perp
			if d2<=1 and d2>=0 then
				dim as single m1, m2, c1, c2, recip

				if v1.x <> 0 then
					m1 = v1.y / v1.x
				else
					m1 = 1
				end if

				if v2.x <> 0 then
					m2 = v2.y / v2.x
				else
					m2 = 1
				end if

				c1 = va.y - (m1*va.x)
				c2 = vc.y - (m2*vc.x)

				recip = 1 / -(m1 - m2)

				ipoint.x = -(c2-c1) * recip
				ipoint.y = ((m2*c1) - (m1*c2)) * recip

				return true
			end if
		end if
	end if

	return false
end function



constructor vec2f()
end constructor


constructor vec2f(byref lhs as vec2f)

this.x = lhs.x
this.y = lhs.y

end constructor


constructor vec2f(byref x as single, byref y as single)

this.x = x
this.y = y

end constructor


function vec2f.dist( byref vb as vec2f ) as single

	dim as single d

	dim as single dx
	dim as single dy

	dx = this.x - vb.X
	dy = this.y - vb.Y

	d = sqr(dx^2+dy^2)

	if d = 0 then d = 1

	return  d

end function


function vec2f.perp( byref b as vec2f ) as vec2f

	dim as single vLen
	dim as vec2f d

	d.x = b.x - this.x
	d.y = b.y - this.y

	vLen = b.dist(this)

	return type( d.y  / vLen, -d.x / vLen )

end function


operator + ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
	return type<vec2f>( lhs.x + rhs.x, lhs.y + rhs.y )
end operator

operator + ( byval lhs as vec2f, byval rhs as single ) as vec2f
	return type<vec2f>( lhs.x + rhs, lhs.y + rhs )
end operator

operator - ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
	return type<vec2f>( lhs.x - rhs.x, lhs.y - rhs.y )
end operator

operator - ( byval lhs as vec2f, byval rhs as single ) as vec2f
	return type<vec2f>( lhs.x - rhs, lhs.y - rhs )
end operator

operator * ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
	return type<vec2f>( lhs.x * rhs.x, lhs.y * rhs.y )
end operator

operator * ( byval lhs as vec2f, byval rhs as single ) as vec2f
	return type<vec2f>( lhs.x * rhs, lhs.y * rhs )
end operator

operator / ( byval lhs as vec2f, byval rhs as vec2f ) as vec2f
	return type<vec2f>( lhs.x / rhs.x, lhs.y / rhs.y )
end operator

operator / ( byval lhs as vec2f, byval rhs as single ) as vec2f
	return type<vec2f>( lhs.x / rhs, lhs.y / rhs )
end operator

operator / ( byval lhs as vec2f, byval rhs as integer ) as vec2f
	return type<vec2f>( lhs.x / rhs, lhs.y / rhs )
end operator
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Simple goofy game...

Post by badidea »

I was bored enough to try it. Its nice, but it quickly gets boring to play :-)
I did not see that line and circle code before. Goes into my collection miscellaneous graphics routines.
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Re: Simple goofy game...

Post by Dr_D »

Cool. :)
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple goofy game...

Post by BasicCoder2 »

Dr_D wrote:I've been a bit bored today, so I made a casual game to play around with.
What happened with Bloosh?
viewtopic.php?f=17&t=25424
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Re: Simple goofy game...

Post by Dr_D »

It's still around. There were a couple things to iron out, but we didn't really generate enough excitement to justify spending a much more time on it. Sir_mud works with computers every day now, so he doesn't want to sit there and program all night as well... I can't say I blame him. Anyway, there is a desktop version *here* that you can fiddle around with, if you're interested. ;)
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Re: Simple goofy game...

Post by Dr_D »

What happened to the game? I saw it, but I didn't have FB near me... I wanted to try it.
Post Reply