2016年1月13日 星期三

SDL - Step7俄羅斯方塊


螢幕截圖:

#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include"SDL/SDL.h"
#define height 400
#define width 400
#define speed 20
struct brick
{
 SDL_Rect a;
 int appearance;//the number of box
 struct brick *next;
};
typedef struct brick BRICK;
//方塊初始座標
int O[8]={80,100,100,80,20,20,0,0};
int I[8]={80,80,80,80,60,40,20,0};
int J[8]={100,80,80,80,0,40,20,0};
int L[8]={100,80,80,80,40,40,20,0};
int S[8]={100,100,80,80,40,20,20,0};
int Z[8]={80,80,100,100,40,20,20,0};
int T[8]={100,80,80,80,20,40,20,0};
void Create(int R[],int c);
void Button(void);
void Overlapping(void);
void Boundary(void);
void Correct(void);
void GameOver(void);
void JudgePositionAfterCorrect(void);
void Rotation(void);
void MoveToDown(BRICK *deliver);
void LeftAndRight(void);
void Drop(void);
void Cancellation(void);
BRICK *first,*current,*previous,*temp;
bool running=true,move=false,correcting=false,DN=false,LR=false,dropping=false;
int dx=20,dy=speed,number=0,acount=0,cycle=0,i,j,p,Cx,Cy,J1,I1,J2,I2,ee=0;
int main()
{
 printf("=======================\n");
 printf("= SPACE - high down   =\n");
 printf("= UP    - rotate      =\n");
 printf("= DOWN  - slow down   =\n");
 printf("= LEFT  - left        =\n");
 printf("= RIGHT - right       =\n");
 printf("=======================\n");
 SDL_Init(SDL_INIT_EVERYTHING);
 SDL_Surface* screen;
 screen=SDL_SetVideoMode(width,height,32,SDL_SWSURFACE);
 SDL_WM_SetCaption("---Tetris---",NULL);
 Uint32 bg=SDL_MapRGB(screen->format,0xff,0xff,0xff);//the color of background
 Uint32 bg1=SDL_MapRGB(screen->format,240,240,240);//the color of bacdground-1
 Uint32 color[7];//the color of box
 color[0]=SDL_MapRGB(screen->format,240,0,0);
 color[1]=SDL_MapRGB(screen->format,0,240,0);
 color[2]=SDL_MapRGB(screen->format,0,0,240);
 color[3]=SDL_MapRGB(screen->format,240,240,0);
 color[4]=SDL_MapRGB(screen->format,0,240,240);
 color[5]=SDL_MapRGB(screen->format,240,0,240);
 color[6]=SDL_MapRGB(screen->format,200,200,0);
 SDL_Rect ss[20][10];//the box of background
 for(i=0;i<20;i++)//set the value to the box of background
 {
  for(j=0;j<10;j++)
  {
   ss[i][j].x=j*20;
   ss[i][j].y=i*20;
   ss[i][j].w=20;
   ss[i][j].h=20;
  }
 }
 srand(time(NULL));
 //printf("Now Loading.......\n");
 //SDL_Delay(1000);
 while(running)
 { 
  if(cycle>0)Cancellation();
  if(move==false)//increase the box
  {
   p=rand()%7;
   if(p==0)Create(O,p);
   if(p==1)Create(I,p);
   if(p==2)Create(J,p);
   if(p==3)Create(L,p);
   if(p==4)Create(S,p);
   if(p==5)Create(Z,p);
   if(p==6)Create(T,p);
   GameOver();
   acount=0;
  }
  //Button();
  if(cycle%8==0)MoveToDown(first);
  if(LR)LeftAndRight();//if left or right was pushed
  if(DN)MoveToDown(first);//if down was pushed
  if(dropping)Drop();//if space was pushed
  //check the condition
  Overlapping();
  Boundary();
  if(correcting)Correct();
  //------------------------
  Overlapping();
  Boundary();
  //increase the box
  if(correcting)Correct();
  //------------------------
  JudgePositionAfterCorrect();
  //Display all box
  SDL_FillRect(screen,&screen->clip_rect,bg1);//background
  for(i=0;i<20;i++)//background
   for(j=0;j<10;j++)
    if(i%2==0&&j%2==1)
     SDL_FillRect(screen,&ss[i][j],bg);
    else if(i%2==1&&j%2==0)
     SDL_FillRect(screen,&ss[i][j],bg);
    else
     SDL_FillRect(screen,&ss[i][j],bg1);
  current=first;//the box
  while(current!=NULL)
  {
   if(current->appearance==0)SDL_FillRect(screen,&current->a,color[0]);
   if(current->appearance==1)SDL_FillRect(screen,&current->a,color[1]);
   if(current->appearance==2)SDL_FillRect(screen,&current->a,color[2]);
   if(current->appearance==3)SDL_FillRect(screen,&current->a,color[3]);
   if(current->appearance==4)SDL_FillRect(screen,&current->a,color[4]);
   if(current->appearance==5)SDL_FillRect(screen,&current->a,color[5]);
   if(current->appearance==6)SDL_FillRect(screen,&current->a,color[6]);
   current=current->next;
  }
  SDL_Flip(screen);
  SDL_Delay(120);//Delay
  cycle++;
  Button();
 }
 SDL_Quit();
}
void Button(void)
{
 SDL_Event event;
 while(SDL_PollEvent(&event))
 {
  switch(event.type)
  {
   case SDL_QUIT:
                  running=false;
                  break;
   case SDL_KEYDOWN:
                  switch(event.key.keysym.sym)
                  {
                     case SDLK_ESCAPE://Quit
                           running=false;
                           break;
     case SDLK_SPACE://Drop
      dropping=true;
      break;
     case SDLK_UP://rotation
      Rotation();
      break;
     case SDLK_DOWN:
      dy=20;
      DN=true;
      break;
     case SDLK_LEFT:
      dx=-20;
      LR=true;
      break;
     case SDLK_RIGHT:
      dx=20;
      LR=true;
      break;
    }
    break;
   case SDL_KEYUP:
    switch(event.key.keysym.sym)
    {
     case SDLK_DOWN:
      dy=speed;
      DN=false;
      break;
     case SDLK_LEFT:
      LR=false;
      break;
     case SDLK_RIGHT:
      LR=false;
      break;
    }
    break;
  }
 }
}
void Create(int R[],int c)
{ 
 //printf("-create-%d\n",number);
 int i; 
 for(i=0;i<4;i++)
 {
  current=(BRICK *)malloc(sizeof(BRICK));
  current->a.x=R[i];
  current->a.y=R[i+4];
  current->a.w=20;
  current->a.h=20;
  current->appearance=c;
  if(number==0&&i==0)
  {
   first=current;
   current->next=NULL;
   //previous=current;
  }
  else
  {
   current->next=first;
   first=current;
  }
 }
 number++;
 move=true;
}
void Overlapping(void)
{
 //printf("-Overlapping\n");
 current=first;
 i=0;
 while(i<4)
 {
  temp=first;
  for(j=0;j<4;j++)temp=temp->next;
  while(temp!=NULL)
   {
   if(current->a.y==temp->a.y)
   {
    if(current->a.x==temp->a.x)correcting=true;
   }
   temp=temp->next;
  }
  current=current->next;
  i++;
 }
}
void Boundary(void)
{
 //printf("--BottomAndBoundary\n");
 current=first;
 i=0;
 while(i<4)
 {
  if(current->a.x<0)correcting=true;
  if(current->a.x>200-current->a.w)correcting=true;
  current=current->next;
  i++;
 }
}
void Correct(void)
{
 //printf("Correct\n");
 current=first;
 for(j=0;j<4;j++)
 {
  current->a.x=current->a.x-dx;
  current=current->next;
 }
 correcting=false;
}
void GameOver(void)
{
 //Game over
 current=first;
 i=0;
 while(i<4)
 {
  temp=first;
  for(j=0;j<4;j++)temp=temp->next;
  while(temp!=NULL)
  {
   if(current->a.x==temp->a.x)
   {
    if(current->a.y==temp->a.y)running=false;
   }
   temp=temp->next;
  }
  current=current->next;
  i++;
 }
 if(running==false)printf("Game Over!!\n");
}
void JudgePositionAfterCorrect(void)
{
 current=first;
 i=0;
 while(i<4)
 {
  temp=first;
  for(j=0;j<4;j++)temp=temp->next;
  while(temp!=NULL)
  {
   if(current->a.x==temp->a.x)
   {
    if(current->a.y==temp->a.y-20)move=false;
   }
   temp=temp->next;
  }
  if(current->a.y>=400-current->a.h)
  {
   current->a.y=400-current->a.h;
   move=false;
  }
  current=current->next;
  i++;
 }
}
void Rotation(void)
{
 current=first; 
 J1=current->a.x;
 I1=current->a.y;
 switch(p)//find the center(Cx,Cy) of box
 {
  case 1:
   if(acount==0)
   {
    Cx=((J1+20)+J1)/2;
    Cy=((I1+80)+I1)/2;
   }
   if(acount==1)
   {
    Cx=((J1-60)+(J1+20))/2;
    Cy=((I1+20)+I1)/2;
   }
   if(acount==2)
   {
    Cx=((J1+20)+J1)/2;
    Cy=((I1-60)+(I1+20))/2;
   }
   if(acount==3)
   {
    Cx=((J1+80)+J1)/2;
    Cy=((I1+20)+I1)/2;
   }
   break;
  case 2:
  case 3:
  case 4:
  case 6:
   if(acount==0)
   {
    Cx=((J1+40)+J1)/2;
    Cy=((I1+60)+I1)/2;
   }
   if(acount==1)
   {
    Cx=((J1-40)+(J1+20))/2;
    Cy=((I1+40)+I1)/2;
   }
   if(acount==2)
   {
    Cx=J1;
    Cy=((I1-40)+(I1+20))/2;
   }
   if(acount==3)
   {
    Cx=((J1+60)+J1)/2;
    Cy=I1;
   }
   break;
  case 5:
   if(acount==0)
   {
    Cx=J1;
    Cy=((I1+60)+I1)/2;
   }
   if(acount==1)
   {
    Cx=((J1-40)+(J1+20))/2;
    Cy=I1;
   }
   if(acount==2)
   {
    Cx=((J1+40)+J1)/2;
    Cy=((I1-40)+(I1+20))/2;
   }
   if(acount==3)
   {
    Cx=((J1+60)+J1)/2;
    Cy=((I1+40)+I1)/2;
   }
   break;
 }
 i=0;//(J1,I1)->(J2,I2)
 while(i<4)
 {
  if(p==0)break;
  J1=current->a.x;
  I1=current->a.y;
  //J2=(J1-Cx)*cos(Theta)-(I1-Cy)*sin(Theta)+Cx
  //I2=(J1-Cx)*sin(Theta)+(I1-Cy)*cos(Theta)+Cy
  J2=(0-(I1-Cy)*1)+Cx;
  I2=((J1-Cx)*1)+Cy;
  //------------------------------
  if(acount>=2)current->a.x=J2-30;
  else
   current->a.x=J2-10;
  if(acount%2==0)current->a.y=I2-10;
  else
   current->a.y=I2+10;
  current=current->next;
  i++;
 }
 if(acount==3)acount=0;
 else
  acount++;
}
void MoveToDown(BRICK *deliver)
{
 i=0;
 while(i<4)
 {
  deliver->a.y=deliver->a.y+dy;
  deliver=deliver->next;
  i++;
 }
}
void LeftAndRight(void)
{
 current=first;
 i=0;
 while(i<4)
 {
  current->a.x=current->a.x+dx;
  current=current->next;
  i++;
 }
}
void Drop(void)
{
 while(1)
 {
  MoveToDown(first);
  JudgePositionAfterCorrect();
  if(move==false)break;
 }
 dropping=false;
}
void Cancellation(void)
{
 i=0;
 while(i<=380)
 { 
  current=first;
  for(j=0;j<4;j++)current=current->next;
  while(current!=NULL)
  {
   if(current->a.y==i)ee++;
   current=current->next;
  }
  if(ee==10)
  { 
   current=first;
   //for(j=0;j<4;j++)current=current->next;
   while(current!=NULL)//delete the node
   {
    if(current->a.y!=i)
    {
     temp=current;
     current=current->next;
    }
    else
    {
     temp->next=current->next;
     previous=current;
     current=current->next;
     free(previous);
    }
   }
   current=first;
   //for(j=0;j<4;j++)current=current->next;
   while(current!=NULL)
   {
    if(current->a.y<i)current->a.y=current >a.y+20;
    current=current->next;
   }
  }
  ee=0;
  i=i+20;
 }
}

SDL - Step6 貪食蛇



螢幕截圖:

#include<stdio.h>
#include<stdlib.h>
#include<SDL/SDL.h>
#include<time.h>
#include<stdbool.h>
#define length 800
#define wide 600
#define num 5
struct node
{
 SDL_Rect snake;
 struct node *next;
};
typedef struct node rect; 
int main(int argc,char** argv)
{
 SDL_Init(SDL_INIT_EVERYTHING);
 SDL_Surface *screen;
 screen=SDL_SetVideoMode(length,wide,32,SDL_SWSURFACE);
 SDL_WM_SetCaption("((((^.^))))****TaiQing's SDL Snake****((((^.^))))",NULL);
 bool running=true;
 Uint32 start; 
 Uint32 color=SDL_MapRGB(screen->format,0,0,0);
 Uint32 color1=SDL_MapRGB(screen->format,255,0,0);
 Uint32 color2=SDL_MapRGB(screen->format,255,255,255);
 int i,dx=-22,dy=0;
 srand(time(NULL));
 SDL_Rect food;
 food.x=rand()%36*22+4;
 food.y=rand()%27*22+14;
 food.w=20;
 food.h=20;
 rect *first,*current,*previous,*increase; 
 //first第一個節點 current正在處理的節點 previous前一節點指標 increase新節點
for(i=0;i<num;i++) 
 {
  current=(rect *) malloc(sizeof(rect));
  current->snake.x=(400+22*i);
  current->snake.y=300;
  current->snake.w=20;
  current->snake.h=20;
  if(i==0)
   first=current;
  else
   previous->next=current;
  current->next=NULL;
  previous=current;
 }
 while(running)
 {
  start=SDL_GetTicks();
  SDL_Event event;
  //keyboard  
  while(SDL_PollEvent(&event))
        {
   switch(event.type) 
   {
case SDL_QUIT:
      running=false;
      break;
     case SDL_KEYDOWN:
      switch(event.key.keysym.sym) 
      {
       case SDLK_ESCAPE:
        running=false;
        break;
       case SDLK_UP:
        if(dx!=0)        
         dy=-22;
        dx=0;         
        break;
       case SDLK_DOWN:
        if(dx!=0)        
         dy=22;
        dx=0;
        break;
       case SDLK_LEFT:
        if(dy!=0)
         dx=-22;
        dy=0;
        break;
       case SDLK_RIGHT:
        if(dy!=0)
         dx=22;
        dy=0;
        break;
      }
      break;     
   }
  }
  //move
  current=first;  
  while(current->next!=NULL)
   current=current->next;
  while(current!=first)
  {
   previous=first; 
   while(previous->next!=current)
    previous=previous->next;
   current->snake.x=previous->snake.x;
   current->snake.y=previous->snake.y;
   current=previous;
  }
  first->snake.x+=dx;
  first->snake.y+=dy;
  //eat food and change length
  if(first->snake.x==food.x && first->snake.y==food.y)
  {
   food.x=rand()%36*22+4;
   food.y=rand()%27*22+14;
   increase=(rect *) malloc(sizeof(rect));
   current=first;  
   while(current->next!=NULL)
    current=current->next;
   if(current->next==NULL)
   {
    increase->snake=current->snake;
    increase->next=NULL;
    current->next=increase;
   }
  }
  //die or dorder
  if(first->snake.x<0 || first->snake.x>780)
   running=false;
  if(first->snake.y<0 || first->snake.y>580)
   running=false;
  current=first;
  current=current->next;
  while(current!=NULL)
  {
   if(current->snake.x==first->snake.x && current->snake.y==first->snake.y)
    running=false;
   current=current->next;
  }
  //render
  SDL_FillRect(screen,&screen->clip_rect,color);
  SDL_FillRect(screen,&food,color2);
  current=first;    
  while(current!=NULL)
  {     
   SDL_FillRect(screen,&(current->snake),color1);
   current=current->next;  
  } 
 SDL_Flip(screen);
 SDL_Delay(100);    
 }
 SDL_Quit();
 return 0;  
}

SDL - Step5 打磚塊


螢幕截圖:

#include<stdio.h>
#include<stdlib.h>
#include<SDL/SDL.h>
#include<time.h>
#include<stdbool.h>
#define m 4
int main(int argc,char** argv)
{
   SDL_Init(SDL_INIT_EVERYTHING);
   SDL_Surface *screen;
   screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);

   bool running=true;
   int dx=1,dy=-1,R=255,G=255,B=255;
   bool a[2]={0,0};
   bool b[m]={0}; 
   Uint32 start;
   SDL_Rect rect,board,brick[m];
   srand(time(NULL));

/*ball*/
   rect.x=180;
   rect.y=175;
   rect.w=15;
   rect.h=15;

/*board*/
   board.x=110;
   board.y=295;
   board.w=60;
   board.h=5;

/*brick*/
   int i;
   for(i=0;i<m;i++)
 {
    brick[i].x=75*i;
    brick[i].y=40;
    brick[i].w=70;
    brick[i].h=20;      
 }

   Uint32 color=SDL_MapRGB(screen->format,0,0,0);
   Uint32 color2;
   Uint32 color3=SDL_MapRGB(screen->format,255,0,0);
   Uint32 color4=SDL_MapRGB(screen->format,0,0,255);   
   
   while(running)
   {  
        start = SDL_GetTicks();
 SDL_Event event;
        Uint32 color2=SDL_MapRGB(screen->format,R,G,B);
        while(SDL_PollEvent(&event))
        {
             switch(event.type) 
             {
                    case SDL_QUIT:
                         running=false;
                         break;
                    case SDL_KEYDOWN:
                         switch(event.key.keysym.sym) 
                         {
                                case SDLK_ESCAPE:
  running=false;
        break;
    case SDLK_LEFT:
                                    a[0]=1;
                                    break;
                                case SDLK_RIGHT:
                                    a[1]=1;
                                    break;
                         }
                         break;     
                   case SDL_KEYUP:
                        switch(event.key.keysym.sym)
                        {
                                case SDLK_LEFT:
                                    a[0]=0;
                                    break;
                                case SDLK_RIGHT:
                                    a[1]=0;
                                    break;                                
                        }
                        break;           
            
             }                          
        }
        /*red board move*/
        if(a[0])
          board.x-=3;
        if(a[1])
          board.x+=3;
        /*red board move 邊界*/
        if(board.x<=0)
          board.x=0;
        if(board.x>=240)
          board.x=240; 
  

/*變色*/  
if(rect.x==0 || rect.x==285)
 {  
   R=rand()%256;
   G=rand()%256;
   B=rand()%256;
 }

/*ball移動*/
rect.x+=dx;
rect.y+=dy;

/*ball死亡後,復活條件*/
if(rect.y>=300)
 {
   rect.x=125;
   rect.y=180;
   rect.w=15;
   rect.h=15;
 }

/*上,左,右邊界*/
if(rect.y<=0)
 dy=-dy;
if(rect.x<=0)
 dx=-dx;
if(rect.x>=285)
  dx=-dx;

if(rect.y<=0)
 rect.y=0;
if(rect.x<=0)
 rect.x=0;
if(rect.x>=285)
 rect.x=285;

/*brick 消失 and ball 反彈*/
for(i=0;i<m;i++)
{
   if(b[i]==0)
   { 
 if(rect.x+15>=brick[i].x && rect.x<=brick[i].x+70)
 {
  if(rect.y+15==40 || rect.y==60)
  {
   dy=-dy;
   b[i]=1;
  }
  
 }

 if(rect.y<=brick[i].y+20 && rect.y+15>=brick[i].y)
 {
  if(rect.x+15== brick[i].x || rect.x==brick[i].x+70)
  {
   dy=-dy;
   b[i]=1;
  }
 }
   }
}
 
  
/*ball and  board 反彈*/
if(rect.y==280)
   if(rect.x>=board.x-15 && rect.x<=board.x+60)
      {
 dy=-dy;
 rect.y=280;
      }

        /*render*/
         SDL_FillRect(screen,&screen->clip_rect,color);
         SDL_FillRect(screen,&rect,color2);
  SDL_FillRect(screen,&board,color3);
 for(i=0;i<4;i++)
   { 
    if(b[i]==0)   
             SDL_FillRect(screen,&brick[i],color4);
   }
   
         SDL_Flip(screen);
        SDL_Delay(10);

    }
   SDL_Quit();
  return 0;
}

SDL - Step4 打乒乓球


螢幕截圖:
#include"SDL/SDL.h"
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(int argc,char** argv)
{
   SDL_Init(SDL_INIT_EVERYTHING);
   SDL_Surface *screen;
   screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);

   bool running=true;
   int dx=1,dy=1,R=255,G=255,B=255;
   bool a[2]={0,0};
   bool b[2]={0,0};
 
   Uint32 start;
   SDL_Rect rect,board1,board2;
   srand(time(NULL));

/*ball*/
   rect.x=145;
   rect.y=145;
   rect.w=20;
   rect.h=20;

/*board1*/
   board1.x=290;
   board1.y=0;
   board1.w=10;
   board1.h=80;

/*board2*/
   board2.x=0;
   board2.y=0;
   board2.w=10;
   board2.h=80;

   Uint32 color=SDL_MapRGB(screen->format,0,0,0);
   Uint32 color2;
   Uint32 color3=SDL_MapRGB(screen->format,255,0,0);
   Uint32 color4=SDL_MapRGB(screen->format,0,255,0);   
   
   while(running)
   {  
        start = SDL_GetTicks();
 SDL_Event event;
        Uint32 color2=SDL_MapRGB(screen->format,R,G,B);
        while(SDL_PollEvent(&event))
        {
             switch(event.type) 
             {
                    case SDL_QUIT:
                         running=false;
                         break;
                    case SDL_KEYDOWN:
                         switch(event.key.keysym.sym) 
                         {
                                case SDLK_ESCAPE:
        running=false;
        break;
    case SDLK_UP:
                                    a[0]=1;
                                    break;
                                case SDLK_DOWN:
                                    a[1]=1;
                                    break;
                                case SDLK_w:
                                    b[0]=1;
                                    break;
                                case SDLK_x:
                                    b[1]=1;
                                    break;
                         }
                         break;     
                   case SDL_KEYUP:
                        switch(event.key.keysym.sym)
                        {
                                case SDLK_UP:
                                    a[0]=0;
                                    break;
                                case SDLK_DOWN:
                                    a[1]=0;
                                    break;
                                case SDLK_w:
                                    b[0]=0;
                                    break;
                                case SDLK_x:
                                    b[1]=0;
                                    break;
                        }
                        break;           
            
             }                          
        }
/*red board move*/
        if(a[0])
          board1.y-=10;
        if(a[1])
          board1.y+=10;
        /*red board move 邊界*/
        if(board1.y<=0)
          board1.y=0;
        if(board1.y>=220)
          board1.y=220; 
        /*green board move*/
        if(b[0])
          board2.y-=10;
        if(b[1])
          board2.y+=10;
        /*green board move邊界*/
        if(board2.y<=0)
          board2.y=0;
        if(board2.y>=220)
          board2.y=220;

/*變色*/  
if(rect.y==0 || rect.y==280)
 {  
   R=rand()%256;
   G=rand()%256;
   B=rand()%256;
 }

rect.x+=dx;
rect.y+=dy;
/*ball死亡條件*/
if(rect.x<0)
 {
   rect.x=145;
   rect.y=145;
   rect.w=20;
   rect.h=20;
 }
if(rect.x>=300)
 { 
   rect.x=145;
   rect.y=145;
   rect.w=20;
   rect.h=20;
 }
if(rect.y<=0)
dy=-dy;
if(rect.y>=280)
dy=-dy;

/*上下邊界*/
if(rect.y<=0)
rect.y=0;
if(rect.y>=280)
rect.y=280;

/*ball and green board 反彈*/
if(rect.x==10)
   if(rect.y>=board2.y-20 && rect.y<=board2.y+80)
      {
        dx=-dx;
        rect.x=10;
      }

/*ball and red board 反彈*/
if(rect.x==270)
   if(rect.y>=board1.y-20 && rect.y<=board1.y+80)
      {
        dx=-dx;
        rect.x=270;
      }
        /*render*/
         SDL_FillRect(screen,&screen->clip_rect,color);
         SDL_FillRect(screen,&rect,color2);
  SDL_FillRect(screen,&board1,color3);
         SDL_FillRect(screen,&board2,color4);
         SDL_Flip(screen);
    
        SDL_Delay(10);

    }
 SDL_Quit();
 return 0;

}

SDL - Step3 方塊碰撞邊界會反彈並且變色


螢幕截圖:
#include<stdio.h>
#include<stdlib.h>
#include<SDL/SDL.h>
#include<time.h>
int main(int argc,char** argv)
{
   SDL_Init(SDL_INIT_EVERYTHING);
   SDL_Surface *screen;
   screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);
   bool running=true;
   int dx=1,dy=1,R=255,G=255,B=255; 
   Uint32 start;
   SDL_Rect rect;
   srand(time(NULL));
   rect.x=145;
   rect.y=145;
   rect.w=20;
   rect.h=20;
   Uint32 color=SDL_MapRGB(screen->format,0,0,0);
   Uint32 color2;
  
   
   while(running)
   {  
        start = SDL_GetTicks();
 SDL_Event event;
        Uint32 color2=SDL_MapRGB(screen->format,R,G,B);
        while(SDL_PollEvent(&event))
        {
switch(event.type) 
             {
                    case SDL_QUIT:
                         running=false;
                         break;
                    case SDL_KEYDOWN:
                         switch(event.key.keysym.sym) 
                         {
                                case SDLK_UP:
                                    dy=-1;
                                    break;
                                case SDLK_LEFT:
                                    dx=-1;
                                    break;
                                case SDLK_DOWN:
                                    dy=1;
                                    break;
                                case SDLK_RIGHT:
                                    dx=1;
                                    break;


                                case SDLK_a:
                                     if(dx>=0 && dy>=0)
                                      {  
                                        dx++;
                                        dy++;
                                      } 
                if(dx>=0 && dy<=0)
                                      { 
                                        dx++;
                                        dy--;
                                      }
                if(dx<=0 && dy>=0)
                                      { 
                                        dx--;
                                        dy++;
                                      }
                       if(dx<=0 && dy<=0)
                                      { 
                                        dx--;
                                        dy--;
                                      } 
                                    break;
                                case SDLK_d:
                                      if(dx>=0 && dy>=0)
                                      {
                                        dx--;
                                        dy--;
                                      }
                                     if(dx>=0 && dy<=0)
                                      {
                                        dx--;
                                        dy++;
                                      }
                                     if(dx<=0 && dy>=0)
                                      {
                                        dx++;
                                        dy--;
                                      }
                                     if(dx<=0 && dy<=0)
                                      {
                                        dx++;
                                        dy++;
                                      } 
                                    break;
                          }
                          break;                       
             }                          
        }
if(rect.x==0 || rect.x==280 || rect.y==0 || rect.y==280)
 {  
   R=rand()%256;
   G=rand()%256;
   B=rand()%256;
 }
if(R==0 && G==0 && B==0)
      { 
        R=rand()%256;
        G=rand()%256; 
        B=rand()%256;
      }
rect.x+=dx;
rect.y+=dy;
if(rect.x<=0)
dx=-dx;
if(rect.x>=280)
dx=-dx;
if(rect.y<=0)
dy=-dy;
if(rect.y>=280)
dy=-dy;


if(rect.x<=0)
rect.x=0;
if(rect.x>=280)
rect.x=280;
if(rect.y<=0)
rect.y=0;
if(rect.y>=280)
rect.y=280;

    //render
    SDL_FillRect(screen,&screen->clip_rect,color);
    SDL_FillRect(screen,&rect,color2);
    SDL_Flip(screen);
    
    SDL_Delay(10);

    }
 SDL_Quit();
 return 0;

}

SDL- Step2 鍵盤按鍵控制方塊的移動


#include<stdlib.h>
#include<SDL/SDL.h>
int main(int argc,char** argv)
{
   SDL_Init(SDL_INIT_EVERYTHING);
   SDL_Surface *screen;
   screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);
   bool running=true;

   Uint32 start;
   bool b[4]={0,0,0,0};
   SDL_Rect rect;
   rect.x=145;
   rect.y=145;
   rect.w=10;
   rect.h=10;
   Uint32 color=SDL_MapRGB(screen->format,0,0,0);
   Uint32 color2=SDL_MapRGB(screen->format,0xff,0xff,0xff);
   while(running)
   {
        start = SDL_GetTicks();
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
switch(event.type)
             {
                    case SDL_QUIT:
                         running=false;
                         break;
                    case SDL_KEYDOWN:
                         switch(event.key.keysym.sym)
                         {
                                case SDLK_UP:
                                    b[0]=1;
                                    break;
                                case SDLK_LEFT:
                                    b[1]=1;
                                    break;
                                case SDLK_DOWN:
                                    b[2]=1;
                                    break;
                                case SDLK_RIGHT:
                                    b[3]=1;
                                    break;

                          }
                          break;
                     case SDL_KEYUP:
                          switch(event.key.keysym.sym)
                          {
                                 case SDLK_UP:
                                     b[0]=0;
                                     break;
                                 case SDLK_LEFT:
                                     b[1]=0;
                                     break;
                                 case SDLK_DOWN:
                                     b[2]=0;
                                     break;
                                 case SDLK_RIGHT:
                                     b[3]=0;
                                     break;
                          }
                          break;
             }

        }
        //logic
        if(b[0])
          rect.y-=10;
        if(b[1])
          rect.x-=10;
        if(b[2])
          rect.y+=10;
        if(b[3])
          rect.x+=10;


        if( rect.y<0)
                rect.y=0;
        if(rect.y>290)
                rect.y=290;
        if(rect.x<0)
                rect.x=0;
        if(rect.x>290)
                rect.x=290;
        //render
         SDL_FillRect(screen,&screen->clip_rect,color);
         SDL_FillRect(screen,&rect,color2);
         SDL_Flip(screen);
   SDL_Delay(50);
   }
 SDL_Quit();
 return 0;

}

編譯指令 : g++ XXX.c -o LLL -lSDL

SDL - step1 隨機產生方塊


螢幕截圖:

#include"SDL/SDL.h"
#include<string.h>
#include<time.h>
#include<math.h>

int main(int argc,char** argv)

{

   SDL_Init(SDL_INIT_EVERYTHING);

   SDL_Surface *screen;

   screen=SDL_SetVideoMode(300,300,32,SDL_SWSURFACE);

   Uint32 start;

   SDL_Rect rect;

   srand(time(NULL));

   int i;

   for(i=0;i<=50;i++)

    {

       rect.x=rand()%290;
       rect.y=rand()%290;
       rect.w=10;
       rect.h=10;
       Uint32 color=SDL_MapRGB(screen->format,0,0,0);
       Uint32 color2=SDL_MapRGB(screen->format,0xff,0xff,0xff);



       SDL_FillRect(screen,&screen->clip_rect,color);
       SDL_FillRect(screen,&rect,color2);
       SDL_Flip(screen);

       SDL_Delay(50);
    }  
    SDL_Quit();
  return 0; } 
編譯指令 : g++ XXX.c -o LLL -lSDL

SDL是一個C語言的函式庫,所以必須有C語言的編譯環境(gcc、g++、cpp)
XXX.c為程式碼的檔案名稱
LLL為編譯出來的可執行檔,之後指令可以下 ./LLL 來執行

2016年1月8日 星期五

SDL - Step0

學習目標的心智圖:

一、參考網址:
  1. 官方網址 : https://www.libsdl.org/ (務必要下載SDL函式庫)
  2. youtube教學網址 : https://goo.gl/JN2GtZ
  3. 自行上網搜尋
二、SDL介紹 :
  1. OpenSource
  2. 使用C語言寫成的函式庫
  3. 提供影像、聲音、I/O等函式
  4. 多用於開發遊戲、模擬器等
  5. 可跨平台執行

2016年1月1日 星期五

C# - 影像處理圖片截圖並與原圖匹配找相同部份再繪矩形標示

練習:
  • 截取圖片 crop()
  • 詳細模板匹配 ExhaustiveTemplateMatching()
  • 繪出矩形 Drawing.Rectangle()
  • 加入 Stopwatch() 碼表計數影像處理時間。
說明:
  • 以 crop() 方法截圖,再使用 ExhaustiveTemplateMatching() 比對原圖與截圖兩者相同處,最後用 Drawing.Rectangle() 繪製矩形至原圖來標示所截圖的位置。
  • ExhaustiveTemplateMatching() 需要花用較多的處理時間,本文用兩圖測試花了:3分23秒、52秒。
##ReadMore##

Step1. 檔案 → 新增專案 → Windows Form 應用程式 → 拉物件 Form1.cs[設計] → 撰寫 Form1.cs

Step2. 方案總管 → 參考 → 右鍵加入參考 → 瀏灠(預設路徑) C:\Program Files (x86)\AForge.NET\Framework\Release → 加入參考:
  • AForge.Imaging.dll 
  • AForge.Imaging.Formats.dll

Step3. Windows Form 拉入需要工具:
  • pictureBox × 3
  • button × 3 
  • textBox × 2
  • Label × 2
  • openFileDialog × 1

Step4. Coding
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Imaging;
using System.Diagnostics;
using AForge.Imaging;
using AForge.Imaging.Formats;
using AForge.Imaging.Filters;

namespace CropAndMatch
{
    public partial class Form1 : Form
    {
        Bitmap sourceImage, templateImage;
        Stopwatch stopWatch = new Stopwatch();

        public Form1()
        {
            InitializeComponent();
        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "所有檔案(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                sourceImage = ImageDecoder.DecodeFromFile(openFileDialog1.FileName);
                pictureBox1.Image = sourceImage;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Crop filter = new Crop(new Rectangle(100, 150, 128, 128));
            templateImage = filter.Apply(sourceImage);
            pictureBox3.Image = templateImage;

            
        }

        private void button3_Click(object sender, EventArgs e)
        {
            stopWatch.Reset();
            stopWatch.Start();
            // create template matching algorithm's instance
            ExhaustiveTemplateMatching tm = new
            ExhaustiveTemplateMatching(0.99f);
            // find all matchings with specified above similarity
            

            TemplateMatch[] matchings = tm.ProcessImage(sourceImage, templateImage);
            // highlight found matchings
            BitmapData data = sourceImage.LockBits(
            new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
            ImageLockMode.ReadWrite, sourceImage.PixelFormat);
            foreach (TemplateMatch m in matchings)
            {
                Drawing.Rectangle(data, m.Rectangle, Color.White);

                textBox2.Text = m.Rectangle.Location.ToString();
                // do something else with matching
            }
            sourceImage.UnlockBits(data);
            pictureBox2.Image = sourceImage;
            stopWatch.Stop();
            // Get the elapsed time as a TimeSpan value.
            TimeSpan ts = stopWatch.Elapsed;
            textBox1.Text = ts.ToString();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

C# - 捕捉滑鼠座標及圖片 Pixel RGB 值

練習:
  • 顯示 Window Form 內滑鼠位置座標。
  • 顯示圖片內之滑鼠座標下像素的 RGB 值。
##ReadMore##

Step1. 檔案 → 新增專案 → Windows Form 應用程式 → 拉物件 Form1.cs[設計] → 撰寫 Form1.cs

Step2. 將圖片放至「專案/bin/Debug」目錄內。

Step3. Windows Form 拉入需要工具:
  • pictureBox × 1 
  • button × 1
  • textBox × 5
  • Label × 5
  • openFileDialog × 1

Step4. 於 Form1.cs[設計] → pictureBox1 屬性 → sizeMode 改為 StretchImage

Step5. Coding Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MouseGraphic
{
    public partial class Form1 : Form
    {

        //Bitmap imgone = new Bitmap("lena.png");
        Bitmap imgone;
        Color colorPixel;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            imgone = new Bitmap("lena.png");
            pictureBox1.Image = imgone;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog OpenImage = new OpenFileDialog();
            if (OpenImage.ShowDialog() == DialogResult.OK)
            {
                imgone = new Bitmap(OpenImage.FileName);
                pictureBox1.Image = imgone;
            }
            
        }

        // 自建一個 Mouse Move Listener
        private void imgone_MouseMove(object sender, MouseEventArgs e)
        {
            //顯示滑鼠座標
            textBox1.Text = e.X.ToString();
            textBox2.Text = e.Y.ToString();

            // 當滑鼠進入圖片內時才捉 RGB 值
            if ((e.X < imgone.Width) && (e.Y < imgone.Height))
            {
                //取得pixel的RGB值
                colorPixel = imgone.GetPixel(e.X, e.Y);
                textBox3.Text = colorPixel.R.ToString();
                textBox4.Text = colorPixel.G.ToString();
                textBox5.Text = colorPixel.B.ToString();
            }
        }
    }
}

Step6.
修改 Form1.Designer.cs → 展開全部程式 → 找到「// pictureBox1」分類 →於其下方加入:
            // 
            // pictureBox1
            // 
            this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imgone_MouseMove);

C# - 影像處理 RotateBicubic() 做圖片旋轉

練習:
  • 使用 RotateBicubic() 讓圖片旋轉 30 度角。
  • 加入 Stopwatch() 顯示圖片處理所花的時間。
##ReadMore##

Step1. 檔案 → 新增專案 → Windows Form 應用程式 → 拉物件 Form1.cs[設計] → 撰寫 Form1.cs

Step2. 方案總管 → 參考 → 右鍵加入參考 → 瀏灠(預設路徑) C:\Program Files (x86)\AForge.NET\Framework\Release → 加入參考:

  • AForge.Imaging.dll 
  • AForge.Imaging.Formats.dll


Step3. 使用測試圖片:

Step4. Windows Form 拉入需要工具:
  • pictureBox × 2
  • button × 2
  • textBox × 1
  • openFileDialog × 1

Step5. Coding
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using AForge.Imaging;
using AForge.Imaging.Formats;
using AForge.Imaging.Filters;
using System.Diagnostics;

namespace rotateDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Bitmap imgone;
        Stopwatch stopWatch = new Stopwatch();

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "所有檔案(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                imgone = ImageDecoder.DecodeFromFile(openFileDialog1.FileName);
                pictureBox1.Image = imgone;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            stopWatch.Reset();
            stopWatch.Start();

            RotateBicubic filter = new RotateBicubic(30, true);

            Bitmap rotateImg = filter.Apply(imgone);
            pictureBox2.Image = rotateImg;

            stopWatch.Stop();
            TimeSpan ti = new TimeSpan();
            textBox1.Text = ti.ToString();
        }
    }
}

C# - 使用 timer 實作一個計數碼表

練習:
  • 使用時間計數器 timer 實作一個碼表,每次增加單位 0.1 秒。
  • 有按鍵 start, stop, reset 做控制。
##ReadMore##

Step1. 檔案 → 新增專案 → Windows Form 應用程式 → 拉物件 Form1.cs[設計] → 撰寫 Form1.cs

Step2. Windows Form 拉入需要工具:
  • Label × 1 
  • button × 3
  • timer × 1

Step3. Coding
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace myTimer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        double sec;

        private void label1_Click(object sender, EventArgs e)
        {
            
        }

        // Form Init
        private void Form1_Load(object sender, EventArgs e)
        {
            label1.BackColor = Color.Black;
            label1.ForeColor = Color.LightGreen;
            label1.TextAlign = ContentAlignment.MiddleCenter;
            button3_Click(sender, e);
        }

        // Timer
        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = string.Format("{0:0000.0 秒}", sec += 0.1);
        }

        // Start
        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        // Stop
        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }

        // Reset
        private void button3_Click(object sender, EventArgs e)
        {
            sec = 0;
            label1.Text = string.Format("{0:0000.0 秒}", sec);
        }
    }
}

C# - 使用碼表 Stopwatch() 測試二維陣列 [i, j] 及 [j, i] 執行時間

宣告一個二維陣列 array[,] 放到兩層 for-loop 裡,並測試:
  • array[i, j] 與 array[j, i] 執行速度上的差別。
  • 使用碼表:Stopwatch() 顯示執行時間。
##ReadMore##

Step1. 檔案 → 新增專案 → Windows Form 應用程式 → 拉物件 Form1.cs[設計] → 撰寫 Form1.cs

Step2. Windows Form 拉入需要工具:
  • textBox × 1
  • button × 1

Step3. Coding
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Elapsed_Time
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Stopwatch stopWatch = new Stopwatch();


        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            stopWatch.Reset();
            stopWatch.Start();

            int maxi = 5000;
            int maxj = 5000;

            int[,] array = new int[maxi, maxj];
            
            for (int i = 0; i < maxi; i++)
            {
                for (int j = 0; j < maxj; j++)
                {
                    /* 測試 Array [i, j] 與 [j, i] 執行速度差異(二選一來執行) */

                    /* [i, j] 會執行比較快 */
                    array[i, j] = i * j;

                    /* [j, i] 比較慢,較花時間 */
                    //array[j, i] = i * j;
                }
            }

            stopWatch.Stop();
            // Get the elapsed time as a TimeSpan value.
            TimeSpan ts = stopWatch.Elapsed;
            textBox1.Text = ts.ToString();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}