Added a color palette for randomly selecting colors for each star.
-- StarField V3 -- Inspired by Codea's example project "Bit Invaders"
--[[ GOAL: Display stars radiating from screen center. Think Star Trek. Rather than lines falling from the top of the screen I wanted lines (stars) radiating from screen center. What seemed like an eazy project at first proved a bit more difficult. I have a knack for pounding square pegs into round holes, but I learned stuff along the way, so that's all that matters.
Stars appear tapered to give a bit of perspective. Speed and size vary as well based on their appearent "closeness" to the viewer.
I have simplified the code taken from Bit Invaders just to make it easier to follow.
See StarField:draw() for handling of table at program exit.
NOTE: Tap screen 4 times to close and return to source code.
--]]
displayMode(FULLSCREEN_NO_BUTTONS)
function setup()
projName = "StarField"
version = "V3"
vercolor = color(255, 0, 0, 50)
print("Hello, StarField! (version "..version..")")
-- Screen center
X = WIDTH/2
Y = HEIGHT/2
SF = StarField()
testing = 1 -- (0=no, 1=yes) This display the line table volume bargraph.
blueColor = color(0, 0, 255, 255)
redColor = color(255, 0, 0, 255)
whiteColor = color(255, 255, 255, 255)
bgColor = color(25, 25, 25, 255)
colorR = color(255, 0, 0, 255)
colorO = color(255, 100, 50, 255)
colorY = color(255, 200, 0, 255)
colorG = color(0, 255, 0, 255)
colorB = color(0, 0, 255, 255)
colorI = color(40, 0, 100, 255) -- too dark for this project
colorV = color(50, 0, 60, 255) -- too dark for this project
colorPalette = {colorR,colorO,colorY, colorG, colorB,colorI,colorV}
end
-- This function gets called once every frame
function draw()
background(bgColor)
--VersionStamper(projName,version,vercolor)
SF:update()
SF:draw()
end
function touched(touch)
if touch.state == BEGAN then
tapCT = touch.tapCount
end
end
----------------------------------------------
-- A Single Star (Produce a single star)
----------------------------------------------
Star = class()
function Star:init(vel, angle, inc, starColor)
self.velocity = vel
self.angle = angle
self.inc = inc
self.starColor = starColor
self.position = vec2(0, math.random(0,100)) -- a positive X-value is interesting
end
function Star:update()
self.position.y = self.position.y + self.velocity*.2
self.inc = self.inc + ((self.velocity*self.velocity)*.005)
end
function Star:draw()
p = self.position -- this is a vec2() type
taper = self.inc * .005 -- gives a slight taper to the star's "trail"
coma = self.inc * .04 -- the size of the star
pushStyle()
fontSize(12)
fill(blueColor)
stroke(blueColor)
fill(self.starColor)
stroke(self.starColor)
strokeWidth(self.inc*.015) -- Stars "closer" to viewer are thicker...
lineCapMode(ROUND)
pushMatrix()
rotate(self.angle)
-- The extra line gives a tapered appearance to the star's trail.
line(p.x-taper, p.y+self.inc, p.x, p.y)
line(p.x+taper, p.y+self.inc, p.x, p.y)
ellipse(p.x, p.y+self.inc, coma) -- ...and their "coma" appears larger.
popMatrix()
popStyle()
end
function Star:shouldCull()
-- Check if beyond the screen by a certain amount. Mark for deletion if so.
if self.position.y > WIDTH*.65 then
return true
end
return false
end
----------------------------------------------
-- StarField (Displays all stars in StarField)
----------------------------------------------
StarField = class()
function StarField:init()
self.minSpeed = 10
self.maxSpeed = 25
self.angle = 0
self.lineTab = {}
end
function StarField:updateAndCull()
for i,v in ipairs(self.lineTab) do
if v:shouldCull() then
table.remove(self.lineTab, i)
else
v:update()
end
end
end
function StarField:update()
-- Just do this once so no need for a for statement.
vel = math.random(self.minSpeed, self.maxSpeed) -- velocity
angle = math.random(-180,180)
inc = 0
-- Star colors
for i=1, 5 do -- Use this for selecting from setup()-defined color palette.
starColor = colorPalette[math.random(1,5)]
end
--[[ -- Use this for stars of random color.
starColor = color(
math.random(100,250),
math.random(100,250),
math.random(100,250),
255)
--]]
--starColor = blueColor -- Use this if monochrome stars are desired.
maxVolume = 125 -- Put a limit on the number of stars created.
--[[
A single star is written to a table with a call to Star() within the table.insert call. However, putting a reasonable limit on the number of stars created will reduce some of the "herky-jerkyness" when managing a large volumes.
--]]
if #self.lineTab < maxVolume then
-- Every star created gets a unique value
table.insert(self.lineTab, Star(vel, angle, inc, starColor))
end
self:updateAndCull()
end
function StarField:draw()
pushStyle()
pushMatrix()
translate(WIDTH/2,HEIGHT/2)
for i,v in ipairs(self.lineTab) do
v:draw()
end
popMatrix()
popStyle()
-- Show line-table volume as a bar-graph.
if testing == 1 then self:lineTableVolume() end
-- Blast table using "nil" then return to code.
if tapCT == 4 then self.lineTab = nil close() end
end
function StarField:lineTableVolume() -- by Scotty
-- Just a bar graph that shows the number of lines in the line table.
pushStyle()
just = 15 -- justification
pushMatrix()
translate(100,75)
fill(colorY)
textMode(CENTER)
text("Line-Table Volume",0,-20)
lineCapMode(SQUARE)
strokeWidth(10)
stroke(colorY)
line(0,0,0,#self.lineTab)
textMode(CORNER)
text(#self.lineTab, -just*3,#self.lineTab)
stroke(bgColor)
strokeWidth(2)
for i=0,650,50 do
if #self.lineTab > i then text(i, just, i-10) line(-5, i, 5, i) end
end
popMatrix()
popStyle()
end