Lazy Foo:Game Loops
英文原文连接:http://lazyfoo.net/articles/article04/index.php
废话我也就不翻译了,贴个代码然后注释一下吧。
1.游戏住循环
接收信息,然后操作,最后渲染
1 while( gameIsRunning ) 2 { 3 //Events 4 //Logic 5 //Rendering 6 }
2.游戏循环细节
这里强调一个动作事件处理(event handling)和表面的属性逻辑(logic)分离开来,分开来处理。
下面的程序先处理键盘事件,修改表面的属性;然后出了事件循环再根据属性的变化,落实操作,先渲染背景,再渲染前景
刷新屏幕,程序必须限制帧率,我以前写的一个五子棋没有限制帧率,每秒渲染18000次。。。一个CPU核心全速跑,伤不起啊。。
logic是最难的部分,其中包含很多东西,例如AI,碰撞检测,物理现象,动作,状态变化等等。
1 //Game Loop 2 while( quit == false ) 3 { 4 //Start the frame timer 5 fps.start(); //Events 6 while( SDL_PollEvent( &event ) ) 7 { 8 myDot.handle_input(); 9 10 if( event.type == SDL_QUIT ) 11 { 12 quit = true; 13 } 14 } 15 //Logic 16 myDot.move(); 17 //Rendering 18 SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); 19 20 myDot.show(); 21 22 if( SDL_Flip( screen ) == -1 ) 23 { 24 return 1; 25 } 26 while( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ){} 27 }
3.一个接收方向按键改变运动速率,和边界碰撞检测的输入检测
边界如果以下面这种情况处理,如果遇到,主平面长宽不能被物体长宽整除的情况,物体的显示会触不到边界,你遇到这种情况,
可以把物体显示到主平面长宽-物体长宽的位置。。。或者换一种实现
1 void Dot::handle_input() 2 { 3 if( event.type == SDL_KEYDOWN ) 4 { 5 switch( event.key.keysym.sym ) 6 { 7 case SDLK_UP: yVel -= DOT_HEIGHT / 2; break; 8 case SDLK_DOWN: yVel += DOT_HEIGHT / 2; break; 9 case SDLK_LEFT: xVel -= DOT_WIDTH / 2; break; 10 case SDLK_RIGHT: xVel += DOT_WIDTH / 2; break; 11 } 12 } 13 else if( event.type == SDL_KEYUP ) 14 { 15 switch( event.key.keysym.sym ) 16 { 17 case SDLK_UP: yVel += DOT_HEIGHT / 2; break; 18 case SDLK_DOWN: yVel -= DOT_HEIGHT / 2; break; 19 case SDLK_LEFT: xVel += DOT_WIDTH / 2; break; 20 case SDLK_RIGHT: xVel -= DOT_WIDTH / 2; break; 21 } 22 } 23 24 x += xVel; 25 26 if( ( x < 0 ) || ( x + DOT_WIDTH > SCREEN_WIDTH ) ) 27 { 28 x -= xVel; 29 } 30 31 y += yVel; 32 33 if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) ) 34 { 35 y -= yVel; 36 } 37 }
4.两个玩家的情况
下面这种逻辑不可取,这是不对的!!!
1 //Player 1 logic 2 player1->handle_collision(); 3 player1->set_status(); 4 player1->move(); 5 6 //Player 2 logic 7 player2->handle_collision(); 8 player2->set_status(); 9 player2->move();
一定要以下面这个形式:
1 //Handle collisionplayer1->handle_collision();player2->handle_collision(); 2 3 //Set status 4 player1->set_status(); 5 player2->set_status(); 6 7 //Move players 8 player1->move(); 9 player2->move();
——现在的努力是为了小时候吹过的牛B!!