现在的位置: 首页 > 综合 > 正文

Linux GTK2.0 打砖块

2018年03月20日 ⁄ 综合 ⁄ 共 8251字 ⁄ 字号 评论关闭
#include <stdio.h>  
#include <gtk/gtk.h>  
#include <math.h>  
  
  
  
// 游戏区域的定义  
#define GAME_WIDTH 500  
#define GAME_LENGTH 600  
  
  
struct Ball  
{  
    int x, y;        // 小球的坐标(圆心)  
    int speed_x, speed_y;        // 小球的速度  
    int radius;        // 半径  
};  
  
  
struct Baffle  
{  
    int x, y;        // 挡板的坐标(挡板左上角)  
    int width, length;        // 挡板的长和宽  
};  
  
  
struct Bricks  
{  
    int matrix[8][12];   // 记录砖块群信息的矩阵  
    int width, length;   // 每一块砖块的长和宽  
};  
  
  
  
  
// 全局变量   
struct Ball ball;        // 小球  
struct Baffle baffle;    // 挡板  
struct Bricks bricks;    // 砖块  
  
GtkWidget *window = NULL;  // 游戏主窗口
GktWidget *lose = NULL;    // 游戏失败提示窗口
GtkWidget *win = NULL;       // 游戏胜利窗口
int pause = 1;            // 处理暂停的变量。0代表游戏继续,1代表游戏暂停  
  
  
  
// 函数声明  
void init(void);  
static gboolean expose_handler(GtkWidget * widget,   
                GdkEventExpose * event, gpointer data);  
                  
static gboolean time_handler(GtkWidget *widget);                  
  
void press_handler(GtkWidget *widget, GdkEventKey *event);  
  
  
  
int main(int argc, char **argv)  
{  
      
    init();  
    gtk_init(&argc,&argv);  
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  
      
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit),  
                        NULL);  
    g_signal_connect(G_OBJECT(window), "expose_event", G_CALLBACK(expose_handler),  
                        NULL);  
    g_signal_connect ( G_OBJECT ( window) , "key_press_event" ,  
                        G_CALLBACK (press_handler) , NULL ) ;  
  
    gtk_window_set_position ( GTK_WINDOW ( window) ,  
                                 GTK_WIN_POS_CENTER) ;  
    gtk_window_set_default_size ( GTK_WINDOW ( window) , GAME_LENGTH, GAME_WIDTH ) ;  
    gtk_widget_set_app_paintable ( window, TRUE ) ;  
    gtk_widget_show_all(window) ;  
      
    g_timeout_add(10, (GSourceFunc)time_handler, NULL);  
    gtk_main() ;  
    return 0;  
}  
  
  
  
/* 
 * 
 * name: init 
 * @param 
 * @return 
 * 
 * 完成初始化 
 */  
void init()  
{  
    int i,j;  
      
    // 挡板的初始化  
    baffle.length = 100;  
    baffle.width = 10;  
    baffle.x = GAME_LENGTH / 2 - baffle.length / 2;  
    baffle.y = GAME_WIDTH - baffle.width;  
      
    // 小球的初始化  
    ball.radius = 5;  
    ball.x = GAME_LENGTH / 2;  
    ball.y = baffle.y - ball.radius;  
    ball.speed_x = 1;  
    ball.speed_y = -1;  
      
    // 砖块群的初始化  
    bricks.length = 50;  
    bricks.width = 20;  
    for(i = 0; i < 8; i++)  
    {  
        for(j = 0; j < 12; j++)  
            bricks.matrix[i][j] = 1;  
    }  
}   
  
  
  
static gboolean expose_handler(GtkWidget * widget,  
                GdkEventExpose * event, gpointer data)  
{  
    cairo_t *cr;  
    int i,j;  
      
      
    cr = gdk_cairo_create(widget ->window);  
      
    // 先画出挡板(矩形)  
    cairo_set_line_width(cr, 2);  
    cairo_set_source_rgb(cr, 0.69, 0.19, 0);  
    cairo_rectangle(cr, baffle.x, baffle.y, baffle.length, baffle.width);  
    cairo_stroke_preserve(cr);  
    cairo_set_source_rgb(cr, 0.3, 0.4, 0.6);  
    cairo_fill(cr);  
      
      
    // 再画出小球  
    cairo_set_line_width(cr, 0);  
    cairo_arc(cr, ball.x, ball.y, ball.radius, 0, 2 * M_PI);  
    cairo_stroke_preserve(cr);  
    cairo_set_source_rgb(cr, 1, 0, 0);  
    cairo_fill(cr);  
      
      
    // 画出砖块群  
    for(i = 0; i < 8; i++)  
    {  
        for(j = 0; j < 12; j++)  
        {  
            if(bricks.matrix[i][j] != 0)  
            {  
                cairo_set_line_width(cr, 1);  
                cairo_set_source_rgb(cr, 1, 1, 0);  
                cairo_rectangle(cr,  j * bricks.length, i * bricks.width, bricks.length, bricks.width);  
                cairo_stroke_preserve(cr);  
                cairo_set_source_rgb(cr, 0.4, 0.8, 0.2);  
                cairo_fill(cr);  
            }  
        }  
    }  
      
      
    cairo_destroy(cr);  
    return FALSE;  
}  
  
  
static gboolean time_handler(GtkWidget *widget)  
{  
    int top_ball, bottom_ball, right_ball, left_ball;  
    int virtual_x, virtual_y;  
      
    if(pause == 1)  
        return TRUE;  
      
    ball.x += ball.speed_x;  
    ball.y += ball.speed_y;  
    if(ball.x <= 0 + ball.radius || ball.x >= GAME_LENGTH - ball.radius)  
        ball.speed_x = -ball.speed_x;  
          
    if(ball.y <= 0 + ball.radius)  
        ball.speed_y = -ball.speed_y;  
    if(ball.y >= GAME_WIDTH - baffle.width - ball.radius)  
    {  
        if(ball.x >= baffle.x && ball.x <= baffle.x + baffle.length)  
            ball.speed_y = -ball.speed_y;  
    }  
          
        //  小球落入最下方,停止游戏  
        if(ball.y >= GAME_WIDTH - ball.radius)  
            return FALSE;  
      
      
    // 检测碰撞  
      
    // 当小球向右下方移动时,小球的右方和下方可能碰到砖块  
    if(ball.speed_x > 0 && ball.speed_y > 0)  
    {  
        bottom_ball = ball.y + ball.radius;  
        virtual_x = ball.x / bricks.length;  
        virtual_y = bottom_ball / bricks.width;  
          
        // 小球下方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_y = -ball.speed_y;  
            }  
        }  
          
        right_ball = ball.x + ball.radius;  
        virtual_x = right_ball / bricks.length;  
        virtual_y = ball.y / bricks.width;  
          
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0)  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_x = -ball.speed_x;  
            }  
        }  
    }  
      
    // 当小球向右上方移动时  
    else if(ball.speed_x > 0 && ball.speed_y < 0)  
    {  
        top_ball = ball.y - ball.radius;  
        virtual_x = ball.x / bricks.length;  
        virtual_y = top_ball / bricks.width;  
          
        // 小球上方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_y = -ball.speed_y;  
            }  
        }  
          
          
          
        right_ball = ball.x + ball.radius;  
        virtual_x = right_ball / bricks.length;  
        virtual_y = ball.y / bricks.width;  
          
        // 小球右方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_x = -ball.speed_x;  
            }  
        }  
          
    }  
      
    // 当小球向左下方移动时  
    else if(ball.speed_x < 0 && ball.speed_y > 0)  
    {  
          
        bottom_ball = ball.y + ball.radius;  
        virtual_x = ball.x / bricks.length;  
        virtual_y = bottom_ball / bricks.width;  
          
        // 小球下方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_y = -ball.speed_y;  
            }  
        }  
          
          
          
        left_ball = ball.x - ball.radius;  
        virtual_x = left_ball / bricks.length;  
        virtual_y = ball.y / bricks.width;  
          
        // 小球左方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_x = -ball.speed_x;  
            }  
        }  
    }  
      
      
    // 当小球向左上方移动时  
    else  
    {  
        top_ball = ball.y - ball.radius;  
        virtual_x = ball.x / bricks.length;  
        virtual_y = top_ball / bricks.width;  
          
        // 小球下方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_y = -ball.speed_y;  
            }  
        }  
          
          
          
        left_ball = ball.x - ball.radius;  
        virtual_x = left_ball / bricks.length;  
        virtual_y = ball.y / bricks.width;  
          
        // 小球左方碰撞到砖块  
        if(virtual_x >= 0 && virtual_x <= 11 && virtual_y >= 0 && virtual_y <= 7)  
        {  
            if(bricks.matrix[virtual_y][virtual_x] != 0) // 该砖块存在  
            {  
                bricks.matrix[virtual_y][virtual_x]--;  
                ball.speed_x = -ball.speed_x;  
            }  
        }  
    }  
      
    gdk_window_invalidate_rect(window ->window, NULL, FALSE);  
    return TRUE ;  
}  
  
void press_handler(GtkWidget *widget, GdkEventKey *event)  
{  
    switch(event ->keyval)  
    {  
        case 65361:  // 左键  
            if(baffle.x > 0)  
                baffle.x -= 10;  
            break;  
          
        case 65363:  // 右键  
            if(baffle.x < 600 - baffle.length)  
                baffle.x += 10;  
            break;  
          
        case 32:    // 空格(暂停)  
            pause = 1;  
            break;  
              
        case 65293:        // 回车  
            pause = 0;  
            break;  
          
        default:  
            break;  
    }  
      
}


抱歉!评论已关闭.