func InitSimulation() bool { // Load texture texObjects = LoadTexture("objects.png") if texObjects == nil { return false } rand = New(0) // Create sprites sky = sprite.New(nil, 0, 0, SCREEN_WIDTH, SKY_HEIGHT) sea = dist.New(SEA_SUBDIVISION, SEA_SUBDIVISION) sea.SetTextureRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-SKY_HEIGHT) sun = sprite.New(texObjects, 81, 0, 114, 114) sun.SetHotSpot(57, 57) moon = sprite.New(texObjects, 0, 0, 81, 81) moon.SetHotSpot(40, 40) star = sprite.New(texObjects, 72, 81, 9, 9) star.SetHotSpot(5, 5) glow = sprite.New(texObjects, 128, 128, 128, 128) glow.SetHotSpot(64, 64) glow.SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE) seaglow = sprite.New(texObjects, 128, 224, 128, 32) seaglow.SetHotSpot(64, 0) seaglow.SetBlendMode(BLEND_COLORADD | BLEND_ALPHAADD | BLEND_NOZWRITE) // Initialize simulation state colWhite.SetHWColor(0xFFFFFFFF) timet = GetTime() speed = 0.0 for i := 0; i < NUM_STARS; i++ { // star positions starX[i] = rand.Float64(0, SCREEN_WIDTH) starY[i] = rand.Float64(0, STARS_HEIGHT) starS[i] = rand.Float64(0.1, 0.7) } for i := 0; i < SEA_SUBDIVISION; i++ { // sea waves phase shifts seaP[i] = float64(i) + rand.Float64(-15.0, 15.0) } // Systems are ready now! return true }
func UpdateSimulation() { cellw := SCREEN_WIDTH / (SEA_SUBDIVISION - 1) var col1, col2 color.ColorRGB // Update time of day if speed == 0.0 { timet = GetTime() } else { timet += Delta() * speed if timet >= 24.0 { timet -= 24.0 } } seq_id = int(timet / 3) seq_residue = timet/3 - float64(seq_id) zenith := -(timet/12.0*hge.Pi - hge.Pi_2) // Interpolate sea and sky colors col1.SetHWColor(skyTopColors[seq[seq_id]]) col2.SetHWColor(skyTopColors[seq[seq_id+1]]) colSkyTop = col2.MulScalar(seq_residue).Add(col1.MulScalar(1.0 - seq_residue)) col1.SetHWColor(skyBtmColors[seq[seq_id]]) col2.SetHWColor(skyBtmColors[seq[seq_id+1]]) colSkyBtm = col2.MulScalar(seq_residue).Add(col1.MulScalar(1.0 - seq_residue)) col1.SetHWColor(seaTopColors[seq[seq_id]]) col2.SetHWColor(seaTopColors[seq[seq_id+1]]) colSeaTop = col2.MulScalar(seq_residue).Add(col1.MulScalar(1.0 - seq_residue)) col1.SetHWColor(seaBtmColors[seq[seq_id]]) col2.SetHWColor(seaBtmColors[seq[seq_id+1]]) colSeaBtm = col2.MulScalar(seq_residue).Add(col1.MulScalar(1.0 - seq_residue)) var a float64 // Update stars if seq_id >= 6 || seq_id < 2 { for i := 0; i < NUM_STARS; i++ { a = 1.0 - starY[i]/STARS_HEIGHT a *= rand.Float64(0.6, 1.0) if seq_id >= 6 { a *= math.Sin((timet - 18.0) / 6.0 * hge.Pi_2) } else { a *= math.Sin((1.0 - timet/6.0) * hge.Pi_2) } starA[i] = a } } // Calculate sun position, scale and colors if seq_id == 2 { a = math.Sin(seq_residue * hge.Pi_2) } else if seq_id == 5 { a = math.Cos(seq_residue * hge.Pi_2) } else if seq_id > 2 && seq_id < 5 { a = 1.0 } else { a = 0.0 } colSun.SetHWColor(0xFFEAE1BE) colSun = colSun.MulScalar(1 - a).Add(colWhite.MulScalar(a)) a = (math.Cos(timet/6.0*hge.Pi) + 1.0) / 2.0 if seq_id >= 2 && seq_id <= 6 { colSunGlow = colWhite.MulScalar(a) colSunGlow.A = 1.0 } else { colSunGlow.SetHWColor(0xFF000000) } sunX = SCREEN_WIDTH*0.5 + math.Cos(zenith)*ORBITS_RADIUS sunY = SKY_HEIGHT*1.2 + math.Sin(zenith)*ORBITS_RADIUS sunS = 1.0 - 0.3*math.Sin((timet-6.0)/12.0*hge.Pi) sunGlowS = 3.0*(1.0-a) + 3.0 // Calculate moon position, scale and colors if seq_id >= 6 { a = math.Sin((timet - 18.0) / 6.0 * hge.Pi_2) } else { a = math.Sin((1.0 - timet/6.0) * hge.Pi_2) } colMoon.SetHWColor(0x20FFFFFF) colMoon = colMoon.MulScalar(1 - a).Add(colWhite.MulScalar(a)) colMoonGlow = colWhite colMoonGlow.A = 0.5 * a moonX = SCREEN_WIDTH*0.5 + math.Cos(zenith-hge.Pi)*ORBITS_RADIUS moonY = SKY_HEIGHT*1.2 + math.Sin(zenith-hge.Pi)*ORBITS_RADIUS moonS = 1.0 - 0.3*math.Sin((timet+6.0)/12.0*hge.Pi) moonGlowS = a*0.4 + 0.5 // Calculate sea glow if timet > 19.0 || timet < 4.5 { // moon a = 0.2 // intensity if timet > 19.0 && timet < 20.0 { a *= (timet - 19.0) } else if timet > 3.5 && timet < 4.5 { a *= 1.0 - (timet - 3.5) } colSeaGlow = colMoonGlow colSeaGlow.A = a seaGlowX = moonX seaGlowSX = moonGlowS * 3.0 seaGlowSY = moonGlowS * 2.0 } else if timet > 6.5 && timet < 19.0 { // sun a = 0.3 // intensity if timet < 7.5 { a *= (timet - 6.5) } else if timet > 18.0 { a *= 1.0 - (timet - 18.0) } colSeaGlow = colSunGlow colSeaGlow.A = a seaGlowX = sunX seaGlowSX = sunGlowS seaGlowSY = sunGlowS * 0.6 } else { colSeaGlow.A = 0.0 } var dwCol1 hge.Dword // Move waves and update sea color for i := 1; i < SEA_SUBDIVISION-1; i++ { a = float64(i) / (SEA_SUBDIVISION - 1) col1 = colSeaTop.MulScalar(1 - a).Add(colSeaBtm.MulScalar(a)) dwCol1 = col1.HWColor() fTime := 2.0 * Time() a *= 20 for j := 0; j < SEA_SUBDIVISION; j++ { sea.SetColor(j, i, dwCol1) dy := a * math.Sin(seaP[i]+(float64(j)/(SEA_SUBDIVISION-1)-0.5)*hge.Pi*16.0-fTime) sea.SetDisplacement(j, i, 0.0, dy, dist.DISP_NODE) } } dwCol1 = colSeaTop.HWColor() dwCol2 := colSeaBtm.HWColor() for j := 0; j < SEA_SUBDIVISION; j++ { sea.SetColor(j, 0, dwCol1) sea.SetColor(j, SEA_SUBDIVISION-1, dwCol2) } var posX float64 // Calculate light path if timet > 19.0 || timet < 5.0 { // moon a = 0.12 // intensity if timet > 19.0 && timet < 20.0 { a *= (timet - 19.0) } else if timet > 4.0 && timet < 5.0 { a *= 1.0 - (timet - 4.0) } posX = moonX } else if timet > 7.0 && timet < 17.0 { // sun a = 0.14 // intensity if timet < 8.0 { a *= (timet - 7.0) } else if timet > 16.0 { a *= 1.0 - (timet - 16.0) } posX = sunX } else { a = 0.0 } if a != 0.0 { k := int(math.Floor(posX / float64(cellw))) s1 := (1.0 - (posX-float64(k*cellw))/float64(cellw)) s2 := (1.0 - (float64((k+1)*cellw)-posX)/float64(cellw)) if s1 > 0.7 { s1 = 0.7 } if s2 > 0.7 { s2 = 0.7 } s1 *= a s2 *= a for i := 0; i < SEA_SUBDIVISION; i += 2 { a = math.Sin(float64(i) / (SEA_SUBDIVISION - 1) * hge.Pi_2) col1.SetHWColor(sea.Color(k, i)) col1.AddEqual(colSun.MulScalar(s1 * (1 - a))) col1.Clamp() sea.SetColor(k, i, col1.HWColor()) col1.SetHWColor(sea.Color(k+1, i)) col1.AddEqual(colSun.MulScalar(s2 * (1 - a))) col1.Clamp() sea.SetColor(k+1, i, col1.HWColor()) } } }