Twinkling star routine

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Twinkling star routine

Post by Lachie Dazdarian »

This routine is an extension of my earlier routine that allowed you to draw stars and polygons with a desired number of corners, change their size, and rotate them.

Code: Select all

#include "fbgfx.bi"
Using FB

const ScreenWidth = 640
const ScreenHeight = 480
const FALSE = 0
const TRUE = 1
const PI = 3.141593

DECLARE SUB DrawPolygon (centerx as integer, centery as integer, num_of_corners as integer, pradius as integer, pcolor as uinteger, start_angle as SINGLE)
DECLARE SUB DrawStar (centerx as integer, centery as integer, num_of_spikes as integer, inner_radius as integer, outer_radius AS INTEGER, pcolor as uinteger, start_angle as SINGLE)
DECLARE SUB DrawSparklingStar (starx AS INTEGER, stary AS INTEGER, star_radius AS INTEGER, star_outer_radius AS INTEGER, star_angle AS INTEGER, star_corners AS INTEGER, r AS INTEGER, g AS INTEGER, b AS INTEGER, luminance AS INTEGER, lstep AS INTEGER, jumpiness AS INTEGER)
  
DIM SHARED AS INTEGER buffer_width, buffer_height, rnd_number, current_corners, current_angle, current_centerx, current_centery, current_radius, current_outer_radius
DIM SHARED AS INTEGER current_luminance, current_step
DIM SHARED some_buffer AS ANY PTR
DIM SHARED read_col AS UINTEGER

SCREENRES ScreenWidth, ScreenHeight, 32, 1, 0

current_corners = 4
current_angle = 38
current_centerx = ScreenWidth/2   ' Starting position of the star.
current_centery = ScreenHeight/2
current_radius = 1
current_outer_radius = 30
buffer_width = ScreenWidth      ' We set the star image buffer to full
buffer_height = ScreenHeight    ' screen, but should be modified to a smaller
                                ' one, depending on the size of
                                ' stars you'll use.
current_luminance = 30
current_step = 2

some_buffer = IMAGECREATE(buffer_width,buffer_height,0)

DO
    
screenlock

LINE (0,0)-(ScreenWidth, ScreenHeight), RGB(0,0,0), BF

rnd_number = INT(RND * 5) + 1

Draw String (10,10), "PGUP/PGDOWN - change the number of corners", RGB(255,0,0)
Draw String (10,20), "ARROW UP/DOWN/LEFT/RIGHT - move the polygon", RGB(255,0,0)
Draw String (10,30), "A,S - change the starting angle", RGB(255,0,0)
Draw String (10,40), "1,2 - change the inner angle", RGB(255,0,0)
Draw String (10,50), "3,4 - change the outer angle (with stars)", RGB(255,0,0)
Draw String (10,60), "5,6 - change luminance", RGB(255,0,0)
Draw String (10,70), "7,8 - change luminance step", RGB(255,0,0)

IF MULTIKEY(SC_UP) THEN current_centery = current_centery - 3
IF MULTIKEY(SC_DOWN) THEN current_centery = current_centery + 3
IF MULTIKEY(SC_LEFT) THEN current_centerx = current_centerx - 3
IF MULTIKEY(SC_RIGHT) THEN current_centerx = current_centerx + 3
IF MULTIKEY(SC_S) THEN current_angle = current_angle + 4
IF MULTIKEY(SC_A) THEN current_angle = current_angle - 4
IF MULTIKEY(SC_1) THEN current_radius = current_radius - 2
IF MULTIKEY(SC_2) THEN current_radius = current_radius + 2
IF MULTIKEY(SC_3) THEN current_outer_radius = current_outer_radius - 2
IF MULTIKEY(SC_4) THEN current_outer_radius = current_outer_radius + 2
IF MULTIKEY(SC_5) THEN current_luminance = current_luminance - 2
IF MULTIKEY(SC_6) THEN current_luminance = current_luminance + 2
IF MULTIKEY(SC_7) THEN current_step = current_step - 2
IF MULTIKEY(SC_8) THEN current_step = current_step + 2

IF current_corners < 2 THEN current_corners = 2

DrawSparklingStar current_centerx, current_centery, current_radius, current_outer_radius, current_angle, current_corners, 0, 200, 205, current_luminance, current_step, 3

DrawSparklingStar 100, 300, 51, 38, 45, 6, 0, 73, 245, 40, 4, 1
DrawSparklingStar 170, 370, 3, 98, 35, 7, 200, 10, 45, 54, 4, 3
DrawSparklingStar 500, 300, 11, 12, 35, 10, 20, 200, 15, 30, 2, 3
DrawSparklingStar 530, 330, 11, 12, 35, 10, 200, 10, 135, 30, 2, 3
DrawSparklingStar 450, 330, 11, 12, 35, 10, 200, 200, 35, 30, 2, 8

screenunlock

IF MULTIKEY(SC_PAGEUP) THEN 
    current_corners = current_corners + 1
    DO
    SLEEP 1
    LOOP UNTIL NOT MULTIKEY(SC_PAGEUP)
END IF

IF MULTIKEY(SC_PAGEDOWN) THEN 
    current_corners = current_corners - 1
    DO
    SLEEP 1
    LOOP UNTIL NOT MULTIKEY(SC_PAGEDOWN)
END IF

sleep 10, 1

LOOP UNTIL MULTIKEY(SC_ESCAPE)

IMAGEDESTROY some_buffer

SUB DrawPolygon (centerx as integer, centery as integer, num_of_corners as integer, pradius as integer, pcolor as uinteger, start_angle as SINGLE)

DIM unit_angle AS DOUBLE

IF num_of_corners < 2 THEN EXIT SUB

unit_angle = 2*PI/num_of_corners

FOR countcorner AS INTEGER = 1 TO num_of_corners

LINE (centerx + sin(start_angle+unit_angle*(countcorner-1))*pradius, centery - cos(start_angle+unit_angle*(countcorner-1))*pradius) - (centerx + sin(start_angle+unit_angle*countcorner)*pradius, centery - cos(start_angle+unit_angle*countcorner)*pradius), pcolor
    
NEXT countcorner
  
END SUB

SUB DrawStar (centerx as integer, centery as integer, num_of_spikes as integer, inner_radius as integer, outer_radius AS INTEGER, pcolor as uinteger, start_angle as SINGLE)

IF num_of_spikes < 2 THEN EXIT SUB

centerx = buffer_height/2
centery = buffer_height/2

DIM unit_angle AS DOUBLE

unit_angle = 2*PI/(num_of_spikes*2)

FOR countcorner AS INTEGER = 1 TO num_of_spikes*2

IF countcorner = 1 OR countcorner MOD 2 <> 0 THEN LINE some_buffer,(centerx + sin(start_angle+unit_angle*(countcorner-1))*outer_radius, centery - cos(start_angle+unit_angle*(countcorner-1))*outer_radius) - (centerx + sin(start_angle+unit_angle*countcorner)*inner_radius, centery - cos(start_angle+unit_angle*countcorner)*inner_radius), pcolor
IF countcorner > 1 AND countcorner MOD 2 = 0 THEN LINE some_buffer,(centerx + sin(start_angle+unit_angle*(countcorner-1))*inner_radius, centery - cos(start_angle+unit_angle*(countcorner-1))*inner_radius) - (centerx + sin(start_angle+unit_angle*countcorner)*outer_radius, centery - cos(start_angle+unit_angle*countcorner)*outer_radius), pcolor

NEXT countcorner

PAINT some_buffer, (centerx, centery), pcolor

  
END SUB

SUB DrawSparklingStar (starx AS INTEGER, stary AS INTEGER, star_radius AS INTEGER, star_outer_radius AS INTEGER, star_angle AS INTEGER, star_corners AS INTEGER, r AS INTEGER, g AS INTEGER, b AS INTEGER, luminance AS INTEGER, lstep AS INTEGER, jumpiness AS INTEGER)
  
DIM temp_alpha AS INTEGER

Line some_buffer, (0, 0)-(ScreenWidth-1, ScreenHeight-1), 0, BF

rnd_number = INT(RND * jumpiness) + 1

FOR count_edge AS INTEGER = luminance TO 0 STEP -lstep
temp_alpha = 255-count_edge*250/luminance+rnd_number
IF temp_alpha < 1 THEN temp_alpha = 1
IF temp_alpha > 255 THEN temp_alpha = 255
DrawStar starx, stary, star_corners, star_radius+count_edge+rnd_number, star_outer_radius+count_edge+rnd_number, RGBA(r,g,b,temp_alpha), star_angle*PI/180
NEXT count_edge

PUT(starx-buffer_height/2,stary-buffer_height/2), some_buffer, ALPHA

END SUB
Use the routine like this:

Code: Select all

DrawSparklingStar starx, stary, star_radius, star_outer_radius, star_angle, star_corners, red, green, blue, luminance, luminance_step, jumpiness (spark effect)
Screenshot:

Image

Anyway, this code allows you to do the same, but stars are filled and shaded toward the edge. They can also twinkle (a cheap trick, but still), you can set their color, luminance, and luminance step.

The code is somewhat processor demanding in real-time, but nobody is stopping you to grab objects generated with this routine when your program starts, and then use them appropriately. Of course, your objects will be less flexibly then (no real-time rotation, etc.).

You can use these objects to emulate street lamp lights, or light spells in RPGs, or whatever you can think of.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

Nice! :-)
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Post by JohnB »

Interesting effects !
duke4e
Posts: 717
Joined: Dec 04, 2005 0:16
Location: Varazdin, Croatia, Europe
Contact:

Post by duke4e »

As usual, Croatians kick ass!
Nice work Lachie!
Post Reply