2011-07-05 61 views
1

我正在使用SDL進行一些練習。我現在正在和星級,太陽和地球一起繪製空間。我可以把所有東西都渲染到屏幕上,但是當我用右箭頭鍵移動太陽時,我無法弄清楚如何刪除舊太陽以模擬視圖圍繞太陽旋轉。它只是在整個屏幕上創建一條大線。我想我需要清理屏幕,每次鑰匙關閉時重新繪製星星,太陽和地球。不過,我不能重新繪製星星,因爲它們超出範圍,如果我重新創建它們,它們將處於不同的位置,因爲我使用rand()來隨機化它們的位置。我遇到了很大的問題,希望得到任何建議。無法重繪空間中的圖像

代碼:

// Planet.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <SDL.h> 
#include <SDL_gfxPrimitives.h> 
#include <stdlib.h> 
#include <time.h> 

class Star 
{ 
private: 
    int x,y,rad,r,g,b,a; 
    SDL_Surface* screen; 
public: 
    Star(SDL_Surface* sc, int xx, int yy, int ra, int rr, int gg, int bb, int aa){screen=sc;x=xx;y=yy;rad=ra;r=rr;g=gg;b=bb;a=aa;} 
    ~Star(){} 
    void Show() 
    { 
     filledCircleRGBA(screen, x, y, rad, r, g, b, a); 
    } 
}; 

class Sun 
{ 
private: 
    int x,y,rad,r,g,b,a; 
    SDL_Surface* screen; 
public: 
    Sun(SDL_Surface* sc, int xx, int yy, int ra, int rr, int gg, int bb, int aa){screen=sc;x=xx;y=yy;rad=ra;r=rr;g=gg;b=bb;a=aa;} 
    ~Sun(){} 
    void Show() 
    { 
     for (int light=10;light<241;light+=10){ 
     filledCircleRGBA(screen, x, y, rad+(light/7), r, g, b+(light/2), a-light); 
     } 
    } 
    void Move(int a, int b) 
    { 
     x+=a; 
     y+=b; 
    } 
}; 

class Earth 
{ 
private: 
    int x,y,rad,r,g,b,a; 
    SDL_Surface* screen; 
public: 
    Earth(SDL_Surface* sc, int xx, int yy, int ra, int rr, int gg, int bb, int aa){screen=sc;x=xx;y=yy;rad=ra;r=rr;g=gg;b=bb;a=aa;} 
    ~Earth(){} 
    void Show() 
    { 
     for (int light=10;light<241;light+=10){ 
     filledCircleRGBA(screen, x, y, rad+(light/7), r, g, b+(light/2), a-(light/2)); 
     } 
     for (double light=0;light<.25;light+=.01){ 
     filledEllipseRGBA(screen, x, y-(rad*1.05), rad*(.60+light), rad*(.1+light), 170+(light*100), 170+(light*100), 170+(light*100), 255-(light*1000)); 
     } 
    } 
}; 

int main(int argc, char* args[]) 
{ 
    //Start SDL 
    SDL_Init(SDL_INIT_EVERYTHING); 
    SDL_Surface* screen = NULL; 
    screen = SDL_SetVideoMode(1366, 768, 32, SDL_FULLSCREEN | SDL_SWSURFACE); 
    srand((unsigned)time(NULL)); 
    //Stars 
    for (int x=0;x<1361;x+=25){ 
     for (int y=0;y<766;y+=25){ 
      int Special = rand()%3; 
      if(Special==0||Special==1){ 
      Star star(screen, x+(rand()%30), y+(rand()%30), 0+(rand()%1), 235+rand()%21, 235+rand()%21, 235+rand()%21, 205+rand()%51); 
      star.Show(); 
      } 
      if(Special==2){ 
      Star star(screen, x+(rand()%30), y+(rand()%30), 0+(rand()%2), 235+rand()%21, 235+rand()%21, 235+rand()%21, 205+rand()%51); 
      star.Show(); 
      } 
     } 
    } 
    //Sun 
    Sun sun(screen, 200, 300, 10, 255, 255, 0, 255); 
    sun.Show(); 
    //Earth 
    Earth earth(screen, 700, 400, 100, 0, 80, 255, 255); 
    earth.Show(); 
    SDL_Event event; 
    bool Running=1; 
    bool keysHeld[323]={false}; 
    while (Running) 
    { 
     // Handle input 
     if (SDL_PollEvent(&event)) 
     { 
     if (event.type == SDL_QUIT) 
     { 
      Running = false; 
     } 

     if (event.type == SDL_KEYDOWN) 
     { 
      keysHeld[event.key.keysym.sym] = true; 
     } 
     if (event.type == SDL_KEYUP) 
     { 
      keysHeld[event.key.keysym.sym] = false; 
     } 
     } 

     if (keysHeld[SDLK_ESCAPE]) 
     { 
     Running = false; 
     } 

     if (keysHeld[SDLK_LEFT]) 
     { 

     } 
     if (keysHeld[SDLK_RIGHT]) 
     { 
     SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); 
     sun.Move(4,0); 
     sun.Show(); 
     } 
     if (keysHeld[SDLK_UP]) 
     { 

     } 
     if (keysHeld[SDLK_DOWN]) 
     { 

     } 


     SDL_Flip(screen); 

    } 
    //Quit SDL 
    SDL_Quit(); 
    return 0; 
} 

回答

0

編輯

自從我上次回答是垃圾,我再試一次:

是的,的確,明星們走出去的範圍,因爲它們是在循環中聲明。你可以做的是保存陣列中的每一顆星星,但這是一個浪費字節的巨大浪費。

在我看來,更好的方法是在表面繪製所有星星,並在每次需要時在屏幕上將其閃爍。這應該是快速和高效的。我笑一個簡短的樣本:

Uint32 rmask, gmask, bmask, amask; 

    /* SDL interprets each pixel as a 32-bit number, so our masks must depend 
     on the endianness (byte order) of the machine */ 
#if SDL_BYTEORDER == SDL_BIG_ENDIAN 
    rmask = 0xff000000; 
    gmask = 0x00ff0000; 
    bmask = 0x0000ff00; 
    amask = 0x000000ff; 
#else 
    rmask = 0x000000ff; 
    gmask = 0x0000ff00; 
    bmask = 0x00ff0000; 
    amask = 0xff000000; 
#endif 
SDL_Surface* star_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 1361, 766, 32, rmask, gmask, bmask, amask); 

而現在,你畫你的明星到這面:作爲背景屏幕使用

... 
Star star(star_surface, x+(rand()%30), y+(rand()%30), 0+(rand()%1), 235+rand()%21, 235+rand()%21, 235+rand()%21, 205+rand()%51); 
star.Show(); 
... 

你需要它的時候,你的blit這個表面此功能:

int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); 
+0

對不起,我想我應該已經更清楚了。我可以清除屏幕,但我無法重新繪製圖像,因爲恆星的實例不再存在。它比SDL更像一個C++問題。 – Vince

+0

太棒了!這正是我一直在尋找的。謝謝! – Vince