做游戲,學編程(C語言) 1 實現彈跳小球
原文鏈接:https://zhuanlan.zhihu.com/p/24633092
知乎我玩的比較少,應不少同學的要求,開始試着開一個系列的教程:做游戲,學編程。有問題大家可以反饋給我改進。
首先,這個教程不會講解C語言的基礎知識,大家可以找些經典的教材,在每次教程前,我會寫上所需的基礎語法知識,大家可以事先學習。主要會給多個步驟的代碼,每個步驟提供對應的要求,以及相應的參考代碼。大家可以先在前一個步驟代碼的基礎上,自己嘗試實現下一個步驟的要求;如果有困難的話,再參考我們給出的代碼。
這次教程,我們實現一個彈跳小球。缺省編譯器為VC,需要學習完基礎的變量、運算符、表達式,printf、scanf輸入輸出函數的用法,if-else、while、for語句的用法。
第1步,顯示靜止的小球。效果為:

// 在坐標(x,y)處輸出一個小球 #include <stdio.h> void main() { int i,j; int x = 5; int y = 10; // 輸出小球上面的空行 for(i=0;i<x;i++) printf("\n"); // 輸出小球左邊的空格 for (j=0;j<y;j++) printf(" "); printf("o"); // 輸出小球o printf("\n"); }
第二步,通過改變小球坐標的變量,讓小球下落
#include <stdio.h> #include <stdlib.h> void main() { int i,j; int x = 1; int y = 10; for (x=1;x<10;x++) { system("cls"); // 清屏函數 // 輸出小球上面的空行 for(i=0;i<x;i++) printf("\n"); // 輸出小球左邊的空格 for (j=0;j<y;j++) printf(" "); printf("o"); // 輸出小球o printf("\n"); } }
這里利用了一個清屏函數system("cls");,只需要加上頭文件#include <stdlib.h>即可。
第三步,實現小球的上下彈跳,在上面一步代碼的基礎上,增加記錄速度的變量,小球的新位置=舊位置+速度。判斷小球到達上下邊界時,速度改變方向,即改變正負號。
#include <stdio.h> #include <stdlib.h> void main() { int i,j; int x = 5; int y = 10; int hight = 20; int velocity = 1; while (1) { x=x+velocity; system("cls"); // 清屏函數 // 輸出小球前的空行 for(i=0;i<x;i++) printf("\n"); for (j=0;j<y;j++) printf(" "); printf("o"); // 輸出小球o printf("\n"); if (x==hight) velocity = -velocity; if (x==0) { velocity = -velocity; } } }
第四步,讓程序更有趣,讓小球斜着彈跳。主要思路是增加x,y兩個方向的速度控制變量,一個碰到上下邊界后改變正負號,一個碰到左右邊界后改變正負號。
#include <stdio.h> #include <stdlib.h> void main() { int i,j; int x = 0; int y = 5; int velocity_x = 1; int velocity_y = 1; int left = 0; int right = 20; int top = 0; int bottom = 10; while (1) { x = x+velocity_x; y = y+velocity_y; system("cls"); // 清屏函數 // 輸出小球前的空行 for(i=0;i<x;i++) printf("\n"); for (j=0;j<y;j++) printf(" "); printf("o"); // 輸出小球o printf("\n"); if ((x==top)||(x==bottom)) velocity_x = -velocity_x; if ((y==left)||(y==right)) velocity_y = -velocity_y; } }
大家盡量養成良好的編碼習慣,上面的邊界坐標盡量不要在程序中寫數字,可以用定義的變量或常量。這樣程序可讀性更好,后面也更容易調整。
第五步,介紹一個Sleep函數,可以讓游戲中間等待,從而可以控制小球彈跳的速度。使用這個函數,需要#include<windows.h>
#include <stdio.h> #include <stdlib.h> #include<windows.h> void main() { int i,j; int x = 0; int y = 5; int velocity_x = 1; int velocity_y = 1; int left = 0; int right = 20; int top = 0; int bottom = 10; while (1) { x = x + velocity_x; y = y + velocity_y; system("cls"); // 清屏函數 // 輸出小球前的空行 for(i=0;i<x;i++) printf("\n"); for (j=0;j<y;j++) printf(" "); printf("o"); // 輸出小球o printf("\n"); Sleep(50); // 等待若干毫秒 if ((x==top)||(x==bottom)) velocity_x = -velocity_x; if ((y==left)||(y==right)) velocity_y = -velocity_y; } }
這里出個思考題,如果沒有sleep函數的話,能否利用循環,實現小球速度變慢的效果?
結果:
#include <math.h> #include<stdio.h> #include<stdlib.h> #include<windows.h> main() { int i, j; int x = 0; int y = 5; int velocity_x = 1; int velocity_y = 1; int left = 0; int right = 20; int top = 0; int bottom = 10; while (1) { x = x + velocity_x; y = y + velocity_y; system("cls"); //清屏函數 for (i = 0; i < x; i++) printf("\n"); for (j = 0; j < y; j++) { printf(" "); } printf("o"); printf("\n"); /* for (int k = 0; k < 1000000000; k++) { continue; }*/ //拖慢小球運行速度 Sleep(50); //等待若干毫秒 if ((x == top) || (x == bottom)) velocity_x = -velocity_x; if ((y == left || y == right)) velocity_y = -velocity_y; } }
另外,大家可以嘗試下 printf("\a"); 實現小球碰到邊界時響鈴。