HGE-7 模拟太阳和月亮的运转


  1 /*
  2 ** Haaf's Game Engine 1.8
  3 ** Copyright (C) 2003-2007, Relish Games
  4 ** hge.relishgames.com
  5 **
  6 ** hge_tut08 - The Big Calm
  7 */
  8 
  9 
 10 // 复制"font2.fnt","font2.png","objects.png"
 11 
 12 
 13 // 本教程模拟了太阳和月亮的运转,以及天空和海面的情况
 14 
 15 
 16 #include <math.h>
 17 
 18 #include <hge.h>
 19 #include <hgecolor.h>
 20 #include <hgesprite.h>
 21 #include <hgedistort.h>
 22 #include <hgefont.h>
 23 #pragma comment(lib,"hge.lib")
 24 #pragma comment(lib,"hgehelp.lib")
 25 
 26 
 27 HGE            *hge=0;
 28 hgeFont        *fnt=0;
 29 
 30 // 一些常量和变量
 31 
 32 #define SCREEN_WIDTH    800
 33 #define SCREEN_HEIGHT    600
 34 #define NUM_STARS        100
 35 #define SEA_SUBDIVISION 16
 36 
 37 #define SKY_HEIGHT        (SCREEN_HEIGHT*0.6f)
 38 #define STARS_HEIGHT    (SKY_HEIGHT*0.9f)
 39 #define ORBITS_RADIUS    (SCREEN_WIDTH*0.43f)
 40 
 41 DWORD skyTopColors[] = {0xFF15092A, 0xFF6C6480, 0xFF89B9D0};
 42 DWORD skyBtmColors[] = {0xFF303E57, 0xFFAC7963, 0xFFCAD7DB};
 43 DWORD seaTopColors[] = {0xFF3D546B, 0xFF927E76, 0xFF86A2AD};
 44 DWORD seaBtmColors[] = {0xFF1E394C, 0xFF2F4E64, 0xFF2F4E64};
 45 
 46 int seq[]={0, 0, 1, 2, 2, 2, 1, 0, 0};
 47 
 48 // 资源句柄
 49 HTEXTURE    texObjects;
 50 
 51 hgeSprite    *sky;
 52 hgeSprite    *sun;
 53 hgeSprite    *moon;
 54 hgeSprite    *glow;
 55 hgeSprite    *seaglow;
 56 hgeSprite    *star;
 57 
 58 hgeDistortionMesh *sea;
 59 
 60 hgeColor    colWhite;
 61 
 62 // 保存状态的变量
 63 float time;        // 0-24 小时
 64 float speed;    // 指定一小时有多少秒
 65 
 66 int      seq_id;
 67 float seq_residue;
 68 
 69 //天上星星的的信息
 70 float starX[NUM_STARS];  // x
 71 float starY[NUM_STARS];  // y
 72 float starS[NUM_STARS];  // 缩放
 73 float starA[NUM_STARS];  // 透明度
 74 
 75 float seaP[SEA_SUBDIVISION]; // 相移数组
 76 
 77 hgeColor colSkyTop;
 78 hgeColor colSkyBtm;
 79 hgeColor colSeaTop;
 80 hgeColor colSeaBtm;
 81 
 82 hgeColor colSun;
 83 hgeColor colSunGlow;
 84 hgeColor colMoon;
 85 hgeColor colMoonGlow;
 86 hgeColor colSeaGlow;
 87 
 88 float sunX, sunY, sunS, sunGlowS;
 89 float moonX, moonY, moonS, moonGlowS;
 90 float seaGlowX, seaGlowSX, seaGlowSY;
 91 
 92 // 函数声明
 93 bool InitSimulation();// 初始化数据
 94 void DoneSimulation();// 删除数据
 95 void UpdateSimulation();// 更新数据
 96 void RenderSimulation();// 绘制数据
 97 
 98 
 99 ///////////////////////// 函数实现 ///////////////////////////
100 
101 
102 bool FrameFunc()
103 {
104     // 检查按键
105     switch(hge->Input_GetKey())
106     {
107         case HGEK_0:        speed=0.0f; break;
108         case HGEK_1:        speed=0.1f; break;
109         case HGEK_2:        speed=0.2f; break;
110         case HGEK_3:        speed=0.4f; break;
111         case HGEK_4:        speed=0.8f; break;
112         case HGEK_5:        speed=1.6f; break;
113         case HGEK_6:        speed=3.2f; break;
114         case HGEK_7:        speed=6.4f; break;
115         case HGEK_8:        speed=12.8f; break;
116         case HGEK_9:        speed=25.6f; break;
117         case HGEK_ESCAPE:    return true;
118     }
119 
120     // 更新场景
121     UpdateSimulation();
122     return false;
123 }
124 
125 
126 bool RenderFunc()
127 {
128     int hrs, mins, secs;
129     float tmp;
130     
131     // 计算用于显示的时间
132     hrs=(int)floorf(time);
133     tmp=(time-hrs)*60.0f;
134     mins=(int)floorf(tmp);
135     secs=(int)floorf((tmp-mins)*60.0f);
136 
137     // 绘制场景
138     hge->Gfx_BeginScene();
139     RenderSimulation();    
140     fnt->printf(7, 7, HGETEXT_LEFT, "Keys 1-9 to adjust simulation speed, 0 - real time\nFPS: %d", hge->Timer_GetFPS());
141     fnt->printf(SCREEN_WIDTH-50, 7, HGETEXT_LEFT, "%02d:%02d:%02d", hrs, mins, secs);
142     hge->Gfx_EndScene();
143 
144     return false;
145 }
146 
147 
148 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
149 {
150     hge = hgeCreate(HGE_VERSION);
151 
152     hge->System_SetState(HGE_LOGFILE, "hge_tut08.log");
153     hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
154     hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
155     hge->System_SetState(HGE_TITLE, "HGE Tutorial 08 - The Big Calm");
156     hge->System_SetState(HGE_USESOUND, false);
157     hge->System_SetState(HGE_WINDOWED, true);
158     hge->System_SetState(HGE_SCREENWIDTH, SCREEN_WIDTH);
159     hge->System_SetState(HGE_SCREENHEIGHT, SCREEN_HEIGHT);
160     hge->System_SetState(HGE_SCREENBPP, 32);
161 
162     if(hge->System_Initiate())
163     {
164         fnt=new hgeFont("font2.fnt");
165         
166         if(!InitSimulation())
167         {
168             MessageBox(NULL, "Can't load resources. See log for details.", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
169             hge->System_Shutdown();
170             hge->Release();
171             return 0;
172         }
173 
174         hge->System_Start();
175 
176         DoneSimulation();
177         delete fnt;
178     }
179 
180     hge->System_Shutdown();
181     hge->Release();
182     return 0;
183 }
184 
185 
186 float GetTime()
187 {
188     SYSTEMTIME SysTime;
189     float tmp;
190 
191     GetLocalTime(&SysTime);
192     tmp=SysTime.wSecond;
193     tmp=SysTime.wMinute+tmp/60.0f;
194     tmp=SysTime.wHour+tmp/60.0f;
195 
196     return tmp;
197 }
198 
199 
200 bool InitSimulation()
201 {
202     // 加载纹理
203     texObjects=hge->Texture_Load("objects.png");
204     if(!texObjects) return false;
205 
206     // 创建精灵
207     sky=new hgeSprite(0, 0, 0, SCREEN_WIDTH, SKY_HEIGHT);
208     sea=new hgeDistortionMesh(SEA_SUBDIVISION, SEA_SUBDIVISION);
209     sea->SetTextureRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-SKY_HEIGHT);
210 
211     sun=new hgeSprite(texObjects,81,0,114,114);
212     sun->SetHotSpot(57,57);
213     moon=new hgeSprite(texObjects,0,0,81,81);
214     moon->SetHotSpot(40,40);
215     star=new hgeSprite(texObjects,72,81,9,9);
216     star->SetHotSpot(5,5);
217 
218     glow=new hgeSprite(texObjects,128,128,128,128);
219     glow->SetHotSpot(64,64);
220     glow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE);
221     seaglow=new hgeSprite(texObjects,128,224,128,32);
222     seaglow->SetHotSpot(64,0);
223     seaglow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHAADD | BLEND_NOZWRITE);
224 
225     // 初始化状态量
226     colWhite.SetHWColor(0xFFFFFFFF);
227     time=GetTime();
228     speed=0.0f;
229 
230     for(int i=0;i<NUM_STARS;i++) // 初始化星星的位置
231     {
232         starX[i]=hge->Random_Float(0, SCREEN_WIDTH);
233         starY[i]=hge->Random_Float(0, STARS_HEIGHT);
234         starS[i]=hge->Random_Float(0.1f, 0.7f);
235     }
236 
237     for(i=0;i<SEA_SUBDIVISION;i++) // 设置海洋波浪的相位转换
238     {
239         seaP[i]=i+hge->Random_Float(-15.0f, 15.0f);
240     }
241 
242     // 初始化完毕
243     return true;
244 }
245 
246 
247 void DoneSimulation()
248 {
249     // 删除精灵
250     
251     delete seaglow;
252     delete glow;
253     delete star;
254     delete moon;
255     delete sun;
256         
257     delete sky;
258     delete sea;
259 
260     // 释放纹理
261     hge->Texture_Free(texObjects);
262 }
263 
264 
265 void UpdateSimulation()
266 {
267     int i, j, k;
268     float zenith, a, dy, fTime;
269     float posX, s1, s2;
270     const float cellw=SCREEN_WIDTH/(SEA_SUBDIVISION-1);
271     hgeColor col1, col2;
272     DWORD dwCol1, dwCol2;
273 
274     // 更新时间
275     if(speed==0.0f) time=GetTime();
276     else
277     {
278         time+=hge->Timer_GetDelta()*speed;
279         if(time>=24.0f) time-=24.0f;
280     }
281 
282     seq_id=(int)(time/3);
283     seq_residue=time/3-seq_id;
284     zenith=-(time/12.0f*M_PI-M_PI_2);
285 
286     // 通过 插值计算 得到海洋和天空的颜色
287 
288     col1.SetHWColor(skyTopColors[seq[seq_id]]);
289     col2.SetHWColor(skyTopColors[seq[seq_id+1]]);
290     colSkyTop=col2*seq_residue + col1*(1.0f-seq_residue);
291 
292     col1.SetHWColor(skyBtmColors[seq[seq_id]]);
293     col2.SetHWColor(skyBtmColors[seq[seq_id+1]]);
294     colSkyBtm=col2*seq_residue + col1*(1.0f-seq_residue);
295     
296     col1.SetHWColor(seaTopColors[seq[seq_id]]);
297     col2.SetHWColor(seaTopColors[seq[seq_id+1]]);
298     colSeaTop=col2*seq_residue + col1*(1.0f-seq_residue);
299 
300     col1.SetHWColor(seaBtmColors[seq[seq_id]]);
301     col2.SetHWColor(seaBtmColors[seq[seq_id+1]]);
302     colSeaBtm=col2*seq_residue + col1*(1.0f-seq_residue);
303 
304     // 更新星星的信息
305     if(seq_id>=6 || seq_id<2)
306         for(int i=0; i<NUM_STARS; i++)
307         {
308             a=1.0f-starY[i]/STARS_HEIGHT;
309             a*=hge->Random_Float(0.6f, 1.0f);
310             if(seq_id>=6) a*=sinf((time-18.0f)/6.0f*M_PI_2);
311             else a*=sinf((1.0f-time/6.0f)*M_PI_2);
312             starA[i]=a;
313         }
314 
315     // 计算太阳的位置,缩放,颜色
316          if(seq_id==2) a=sinf(seq_residue*M_PI_2);
317     else if(seq_id==5) a=cosf(seq_residue*M_PI_2);
318     else if(seq_id>2 && seq_id<5) a=1.0f;
319     else a=0.0f;
320     
321     colSun.SetHWColor(0xFFEAE1BE);
322     colSun=colSun*(1-a)+colWhite*a;
323 
324     a=(cosf(time/6.0f*M_PI)+1.0f)/2.0f;
325     if(seq_id>=2 && seq_id<=6)
326     {
327         colSunGlow=colWhite*a;
328         colSunGlow.a=1.0f;
329     }
330     else colSunGlow.SetHWColor(0xFF000000);
331 
332     sunX=SCREEN_WIDTH*0.5f+cosf(zenith)*ORBITS_RADIUS;
333     sunY=SKY_HEIGHT*1.2f+sinf(zenith)*ORBITS_RADIUS;
334     sunS=1.0f-0.3f*sinf((time-6.0f)/12.0f*M_PI);
335     sunGlowS=3.0f*(1.0f-a)+3.0f;
336 
337     // 计算月亮的位置,缩放,颜色
338 
339     if(seq_id>=6) a=sinf((time-18.0f)/6.0f*M_PI_2);
340     else a=sinf((1.0f-time/6.0f)*M_PI_2);
341     colMoon.SetHWColor(0x20FFFFFF);
342     colMoon=colMoon*(1-a)+colWhite*a;
343 
344     colMoonGlow=colWhite;
345     colMoonGlow.a=0.5f*a;
346 
347     moonX=SCREEN_WIDTH*0.5f+cosf(zenith-M_PI)*ORBITS_RADIUS;
348     moonY=SKY_HEIGHT*1.2f+sinf(zenith-M_PI)*ORBITS_RADIUS;
349     moonS=1.0f-0.3f*sinf((time+6.0f)/12.0f*M_PI);
350     moonGlowS=a*0.4f+0.5f;
351 
352     // 计算海洋的光效
353 
354     if(time>19.0f || time<4.5f) // 月亮下的情况
355     {
356         a=0.2f; // 强度
357         if(time>19.0f && time<20.0f) a*=(time-19.0f);
358         else if(time>3.5f && time<4.5f) a*=1.0f-(time-3.5f);
359 
360         colSeaGlow=colMoonGlow;
361         colSeaGlow.a=a;
362         seaGlowX=moonX;
363         seaGlowSX=moonGlowS*3.0f;
364         seaGlowSY=moonGlowS*2.0f;
365     }
366     else if(time>6.5f && time<19.0f) // 太阳下的情况
367     {
368         a=0.3f; // 强度
369         if(time<7.5f) a*=(time-6.5f);
370         else if(time>18.0f) a*=1.0f-(time-18.0f);
371 
372         colSeaGlow=colSunGlow;
373         colSeaGlow.a=a;
374         seaGlowX=sunX;
375         seaGlowSX=sunGlowS;
376         seaGlowSY=sunGlowS*0.6f;
377     }
378     else colSeaGlow.a=0.0f;
379 
380     // 产生海浪并且更新海洋的颜色
381 
382     for(i=1; i<SEA_SUBDIVISION-1; i++)
383     {
384         a=float(i)/(SEA_SUBDIVISION-1);
385         col1=colSeaTop*(1-a)+colSeaBtm*a;
386         dwCol1=col1.GetHWColor();
387         fTime=2.0f*hge->Timer_GetTime();
388         a*=20;
389 
390         for(j=0; j<SEA_SUBDIVISION; j++)
391         {
392             sea->SetColor(j, i, dwCol1);
393 
394             dy=a*sinf(seaP[i]+(float(j)/(SEA_SUBDIVISION-1)-0.5f)*M_PI*16.0f-fTime);
395             sea->SetDisplacement(j, i, 0.0f, dy, HGEDISP_NODE);
396         }
397     }
398 
399     dwCol1=colSeaTop.GetHWColor();
400     dwCol2=colSeaBtm.GetHWColor();
401 
402     for(j=0; j<SEA_SUBDIVISION; j++)
403     {
404         sea->SetColor(j, 0, dwCol1);
405         sea->SetColor(j, SEA_SUBDIVISION-1, dwCol2);
406     }
407 
408     // 计算光线路径
409 
410     if(time>19.0f || time<5.0f) // 月亮下的情况
411     {
412         a=0.12f; // 强度
413         if(time>19.0f && time<20.0f) a*=(time-19.0f);
414         else if(time>4.0f && time<5.0f) a*=1.0f-(time-4.0f);
415         posX=moonX;
416     }
417     else if(time>7.0f && time<17.0f) // 太阳下的情况
418     {
419         a=0.14f; // 强度
420         if(time<8.0f) a*=(time-7.0f);
421         else if(time>16.0f) a*=1.0f-(time-16.0f);
422         posX=sunX;
423     }
424     else a=0.0f;
425 
426     if(a!=0.0f)
427     {
428         k=(int)floorf(posX/cellw);
429         s1=(1.0f-(posX-k*cellw)/cellw);
430         s2=(1.0f-((k+1)*cellw-posX)/cellw);
431 
432         if(s1>0.7f) s1=0.7f;
433         if(s2>0.7f) s2=0.7f;
434 
435         s1*=a;
436         s2*=a;
437     
438         for(i=0; i<SEA_SUBDIVISION; i+=2)
439         {
440             a=sinf(float(i)/(SEA_SUBDIVISION-1)*M_PI_2);
441 
442             col1.SetHWColor(sea->GetColor(k,i));
443             col1+=colSun*s1*(1-a);
444             col1.Clamp();
445             sea->SetColor(k, i, col1.GetHWColor());
446             
447             col1.SetHWColor(sea->GetColor(k+1,i));
448             col1+=colSun*s2*(1-a);
449             col1.Clamp();
450             sea->SetColor(k+1, i, col1.GetHWColor());
451         }
452     }
453 }
454 
455 
456 void RenderSimulation()
457 {
458     // 绘制天空
459     sky->SetColor(colSkyTop.GetHWColor(), 0);
460     sky->SetColor(colSkyTop.GetHWColor(), 1);
461     sky->SetColor(colSkyBtm.GetHWColor(), 2);
462     sky->SetColor(colSkyBtm.GetHWColor(), 3);
463     sky->Render(0, 0);
464 
465     // 绘制星星
466     if(seq_id>=6 || seq_id<2)
467         for(int i=0; i<NUM_STARS; i++)
468         {
469             star->SetColor((DWORD(starA[i]*255.0f)<<24) | 0xFFFFFF);
470             star->RenderEx(starX[i], starY[i], 0.0f, starS[i]);
471         }
472 
473     // 绘制太阳
474     glow->SetColor(colSunGlow.GetHWColor());
475     glow->RenderEx(sunX, sunY, 0.0f, sunGlowS);
476     sun->SetColor(colSun.GetHWColor());
477     sun->RenderEx(sunX, sunY, 0.0f, sunS);
478 
479     // 绘制月亮
480     glow->SetColor(colMoonGlow.GetHWColor());
481     glow->RenderEx(moonX, moonY, 0.0f, moonGlowS);
482     moon->SetColor(colMoon.GetHWColor());
483     moon->RenderEx(moonX, moonY, 0.0f, moonS);
484 
485     // 绘制海洋
486     // 绘制月亮和太阳的时候不需要对时间进行判定
487     // 原因是当在海平线以下的时候,进行海洋的绘制会覆盖掉太阳或者月亮
488     sea->Render(0, SKY_HEIGHT);
489     seaglow->SetColor(colSeaGlow.GetHWColor());
490     seaglow->RenderEx(seaGlowX, SKY_HEIGHT, 0.0f, seaGlowSX, seaGlowSY);
491     
492     // 总体上的绘制顺序就是后者会覆盖前者(当然,如果后者设置了一些融合属性,可能就不会完全的覆盖了,
493     // 但是本例中则是完全覆盖)
494 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM