皮卡丘推西瓜遊戲 2019年1月12日
以下內容僅供娛樂,歡迎隨時探討,請多指教!
(1)遊戲共有五關,由易到難,每一關都有初始化、按鍵處理、重置、退出功能。
(2)初始化包括屏幕初始化和每一關關卡的初始化,屏幕被初始化爲寬600、高660。
(3)更新記錄模塊,實現學生個人信息和成績信息的修改。
(4)按鍵處理包括移動小人和移動箱子,通過移動上下左右鍵控制小人的移動,從而推動箱子,以把箱子推到指定的目的地爲完成通關。
(5)每一關都可以重置,按r鍵,可以重置當前關,空格回退一步。
(6)按Esc鍵可以在任何時候退出程序。
(7)輸入信息有效性驗證模塊,驗證用戶數據輸入是否有效合法。
想要源代碼可以參考百度雲文件,下面?
鏈接:https://pan.baidu.com/s/17YZvTb3512e9YmbB76IVQA 提取碼:c9nz 複製這段內容後打開百度網盤手機App,操作更方便哦
以上是完整源程序代碼鏈接。
——————————————分割線—————————————————
以下是遊戲效果展示圖。
以下爲代碼:
///////////////////////////////////////////////////////////
// 程序名稱:皮卡丘推西瓜
// 編譯環境:Visual C++ 6.0
////////////////////////////////////////////////////////////
//遊戲中用0表示空地,1表示人物,2表示箱子,3表示目的地,6表示圍牆
////////////////////////////////////////////////////////////
#include "myhead.h"
#include "graphics.h"// 引用圖形庫頭文件,可以置入圖片
#include "conio.h"
#include "dos.h"
#include "stdio.h"
#include "stdlib.h"
#include "ctype.h"
#include "time.h"
#include "windows.h"
#define M 21 //設置密碼位數爲20
/*定義結構體,儲存信息*/
typedef struct winer
{
struct winer *before;
int t[10][10];
struct winer *next;
} winer;
int x,y; //人物座標
int loop; //控制是否重新開始
IMAGE img[8]; //定義IMAGE對象數組來保存圖片
int b[10][10]; //設置當前地圖數組,用來接收地圖便於讀寫
char user[M]; //設置賬戶名
char password[M]; //設置密碼
int count=0; //記錄步數
int begin, end; //定義開始和結束標誌位
//遊戲中用0表示空地,1表示人物,2表示箱子,3表示目的地,6表示圍牆
const int map[5][10][10]= //定義三維地圖數組
{
{ {0},
{0, 0, 6, 6, 6},
{0, 0, 6, 3, 6},
{0, 0, 6, 0, 6, 6, 6, 6},
{6, 6, 6, 2, 0, 2, 3, 6},
{6, 3, 0, 2, 1, 6, 6, 6},
{6, 6, 6, 6, 2, 6},
{0, 0, 0, 6, 3, 6},
{0, 0, 0, 6, 6, 6}
},
{ {6, 6, 6, 6, 6},
{6, 1, 0, 0, 6},
{6, 0, 2, 0, 6, 0, 6, 6, 6},
{6, 0, 0, 0, 6, 0, 6, 3, 6},
{6, 6, 6, 2, 6, 6, 6, 3 , 6},
{0, 6, 6, 0, 0, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 6, 0, 0, 6},
{0, 6, 0, 0, 0, 6, 6, 6, 6},
{0, 6, 6, 6, 6, 6}
},
{ {0, 6, 6, 6, 6},
{0, 6, 1, 0, 6, 6, 6},
{0, 6, 0, 0, 0, 0, 6},
{6, 6, 6, 0, 6, 0, 6, 6},
{6, 3, 6, 0, 6, 0, 0, 6},
{6, 0, 2, 0, 0, 6, 0, 6},
{6, 3, 0, 0, 0, 2, 0, 6},
{6, 6, 6, 6, 6, 6, 6, 6}
},
{ {0, 6, 6, 6, 6, 6, 6, 6},
{0, 6, 0, 1, 0, 3, 3, 6},
{0, 6, 0, 0, 0, 6, 6, 6, 6},
{6, 6, 6, 0, 0, 0, 0, 0, 6},
{6, 0, 0, 0, 6, 2, 6, 0, 6},
{6, 0, 2, 0, 6, 0, 0, 0, 6},
{6, 0, 0, 0, 6, 6, 6, 6, 6},
{6, 6, 6, 6, 6}
},
{ {0, 6, 6, 6, 6, 6},
{0, 6, 0, 1, 0, 6, 6, 6},
{6, 6, 0, 6, 2, 0, 0, 6},
{6, 0, 0 ,3, 0, 3, 0, 6},
{6, 0, 0, 2, 2, 0, 6, 6},
{6, 6, 6, 0, 6, 3, 6},
{0, 0, 6, 0, 0, 0, 6},
{0, 0, 6, 6, 6, 6, 6}
}
};
//遊戲中用0表示空地,1表示人物,2表示箱子,3表示目的地,6表示圍牆
/*自定義函數原型*/
//
void blank(int x1,int y1); //畫空地
void man (int x1,int y1); //畫皮卡丘
void box (int x1,int y1); //畫箱子
void dest (int x1,int y1); //畫目的地
void man1 (int x1,int y1); //畫在目的地上的皮卡丘
void box1 (int x1,int y1); //畫在目的地上的箱子
void wall (int x1,int y1); //畫圍牆
void man2 (int x1,int y1); //畫在勝利的皮卡丘
void print(int b[][10]); //把數組裏的全畫出來
void chush(); //初始化過程
winer *chushihua(); //初始化鏈表
void Drawjm(); //畫標誌
void scanpassword(); //從文件讀入密碼
void free_list(winer *head); //釋放鏈表
//xiao
void move (int b[][10],int x1, int y1); //移動
void find (int b[][10]); //找人物座標
int win (int b[][10]); //判斷遊戲是否結束
void saveinformation(int i); //該函數用於玩家遊戲信息
void changepassword(); //該函數用於修改系統密碼
//chen
void huanying(); //歡迎界面
int play (int b[][10],int i); //遊戲過程
void tips(); //輸出提示信息
void pass(); //密碼登錄界面
int passyanz(); //此函數用於驗證密碼,密碼支持20位的字符
void savepassword(); //該函數用於文件保存系統密碼
void Printspace(int a); //輸出空格
void Drawmenu(); //畫菜單
void playguanka(); //遊戲關卡
//li
/*自定義函數原型*/
winer *head=chushihua(); //頭
winer *p=NULL,*q=head; //鏈表相關
/*******************函數定義*******************/
void Drawmenu()
{
Printspace(50);
printf("╔═══════════════╗\n");
Printspace(50);
printf("║ 1.開始遊戲 ║\n");
Printspace(50);
printf("╚═══════════════╝\n\n");
Printspace(50);
printf("╔═══════════════╗\n");
Printspace(50);
printf("║ 2.修改密碼 ║\n");
Printspace(50);
printf("╚═══════════════╝\n\n");
Printspace(50);
printf("╔═══════════════╗\n");
Printspace(50);
printf("║ 3.提示信息 ║\n");
Printspace(50);
printf("╚═══════════════╝\n\n");
Printspace(50);
printf("╔═══════════════╗\n");
Printspace(50);
printf("║ 4.退出遊戲 ║\n");
Printspace(50);
printf("╚═══════════════╝\n\n");
}
//輸出空格
void Printspace(int a)
{
for(int i=0;i<a;i++)
printf(" ");
}
//畫界面
void Drawjm()
{
Printspace(35);
printf("╔");
for(int i=1;i<=46;i++)
printf("═");
printf("╗\n");
Printspace(35);
printf("║");
Printspace(18);
printf(" 推 箱 子 ");
Printspace(18);
printf("║\n");
Printspace(35);
printf("╚");
for(i=1;i<=46;i++)
printf("═");
printf("╝\n");
printf("\n\n");
}
//從文件讀入密碼
void scanpassword()
{
FILE *fp;
fp=fopen("user.txt","r");
if(fp == NULL)
{
printf("打開失敗!\n");
getch();
}
else
{
fscanf(fp,"%s",password);
printf("打開成功,讀寫成功!1\n");
fclose(fp);
}
}
//此函數用於驗證密碼,密碼支持20位的字符
int passyanz()
{
int x,n=1;
system("cls");
Drawjm();
printf("請輸入用戶名:");
scanf("%s",user);
printf("tips:初始密碼爲123\n");
for(;; n++)
{
if(n<=3)
{
char ch,inpassword[M];
int i=0;
printf("請輸入密碼:");
while((ch=getch())!='\r' && i<=M)
{
if(ch=='\b')
{
if(i>0)
{
i--;
printf("\b \b");// 密碼支持退格的實現
}
else
putchar(7);
}
else
{
inpassword[i++]=ch;
printf("*");
}
}
inpassword[i]='\0';
if(strcmp(inpassword,password) == 0)
{
printf("\n密碼正確\t請繼續操作\n");
x=1;
return x;
}
else
{
printf("\n密碼錯誤\t您還有%d次機會\n",3-n);
}
}
else
{
printf("\n密碼均錯誤\t無法繼續操作!\n");
x=0;
return x;
}
}
system("pause");
}
//該函數用於修改系統密碼
void changepassword()
{
char ch1,ch2,passwordtemp[M],password2[M];
int i=0,j=0,x;
do
{
i=0,j=0;
printf("請輸入新密碼\n");
while((ch1=getch())!='\r' && i<=M)
{
if(ch1=='\b')
{
if(i>0)
{
i--;
printf("\b \b");// 密碼支持退格的實現
}
else
putchar(7);
}
else
{
passwordtemp[i++]=ch1;
printf("*");
}
}
passwordtemp[i]='\0';
printf("\n請確認新密碼\n");
while((ch2=getch())!='\r' && j<=M)
{
if(ch2=='\b')
{
if(j>0)
{
j--;
printf("\b \b");// 密碼支持退格的實現
}
else
putchar(7);
}
else
{
password2[j++]=ch2;
printf("*");
}
}
password2[j]='\0';
if(strcmp(passwordtemp,password2)==0)
{
x=0;
printf("\n密碼修改成功!\n");
system("pause");
}
else
{
x=1;
printf("\n兩次輸入密碼不同,請再設置一遍\n");
}
}
while(x);
for(i=0; i<=M; i++)
{
password[i]=passwordtemp[i];
}
savepassword();
}
//該函數用於文件保存系統密碼
void saveinformation(int i)//該函數用於玩家遊戲信息
{
FILE *fp;
fp=fopen("information.txt","a");
if(fp == NULL)
{
printf("打開失敗!\n");
getch();
}
else
{
fprintf(fp,"%s\t%d\t%d\t%.2f\n",user,i+1,count,1.0*(end-begin)/1000);
printf("打開成功,讀寫成功!2\n");
fclose(fp);
}
}
void savepassword()
{
FILE *fp;
fp=fopen("user.txt","w");
if(fp == NULL)
{
printf("打開失敗!\n");
getch();
}
else
{
fprintf(fp,"%s",password);
printf("打開成功,讀寫成功!2\n");
fclose(fp);
}
}
//初始化背景和載入圖片
void chush()
{
initgraph(600,660);
setbkcolor(LIGHTCYAN);
cleardevice();
loadimage(&img[0], "圖片\\0.jpg");
loadimage(&img[1], "圖片\\1.jpg");
loadimage(&img[2], "圖片\\2.jpg");
loadimage(&img[3], "圖片\\3.jpg");
loadimage(&img[4], "圖片\\4.jpg");
loadimage(&img[5], "圖片\\5.jpg");
loadimage(&img[6], "圖片\\6.jpg");
loadimage(&img[7], "圖片\\7.jpg");
}
//畫空地
void blank(int x1, int y1)
{
putimage(y1, x1, &img[0]); // 在座標 (y1, x1) 位置顯示 IMAGE 對象
}
//畫皮卡丘
void man(int x1, int y1)
{
putimage(y1, x1, &img[1]);
}
//畫箱子
void box(int x1, int y1)
{
putimage(y1, x1, &img[2]);
}
//畫目的地
void dest(int x1, int y1)
{
putimage(y1, x1, &img[3]);
}
//畫在目的地上的皮卡丘
void man1(int x1, int y1)
{
putimage(y1, x1, &img[4]);
}
//畫在目的地上的箱子
void box1(int x1, int y1)
{
putimage(y1, x1, &img[5]);
}
//畫圍牆
void wall(int x1, int y1)
{
putimage(y1, x1, &img[6]);
}
//畫勝利的皮卡丘
void man2(int x1, int y1)
{
putimage(y1, x1, &img[7]);
}
//把數組裏的全畫出來
void print(int b[][10])
{
for(int x1 = 0; x1 < 10; x1++)
for(int y1 = 0; y1 < 10; y1++)
putimage(60 * y1, 60 * x1, &img[b[x1][y1]]);
}
//輸出提示信息
void tips()
{
printf("遊戲玩法:"
"遊戲一共5關\n"
"1.方向鍵和wsad上下左右移動\n"
"2.r鍵重新開始當前關\n"
"3.空格回退(請不要瘋狂點)\n"
"4.經典的推箱子是一個來自日本的古老遊戲,目的是在訓練你的邏輯思考能力。\n"
"在一個狹小的倉庫中,要求把西瓜放到指定的位置,稍不小心就會出現西瓜\n"
"無法移動或者通道被堵住的情況,所以需要巧妙的利用有限的空間和通道,\n"
"合理安排移動的次序和位置,才能順利的完成任務。 每一關經過精心篩選,\n"
"絕對具有挑戰性!下面請開始你的遊戲。\n\n\n");
}
//釋放鏈表
void free_list(winer *head)
{
winer *temp=head ;
while(temp!=NULL)
{
head=head->next;
free(temp);
temp=head;
}
}
//找人物座標x,y
void find(int b[][10])
{
for(x = 0; x < 10; x++)
for(y = 0; y < 10; y++)
if(b[x][y] == 1) return;
}
//判斷遊戲是否結束
int win(int b[][10])
{
for(int x1 = 0; x1 < 10; x1++)
for(int y1 = 0; y1 < 10; y1++)
if(b[x1][y1] == 2) return 0; //如果還有箱子返回假
return 1; //如果沒有箱子返回真
}
//移動過程函數
void move(int b[][10], int x1, int y1)
{
if(b[x+x1][y+y1] == 0 || b[x+x1][y+y1] == 3)
{
count++;
p=(winer*)malloc(sizeof(struct winer));
q->next=p;//接起
for(int j = 0; j < 10; j++)
for(int k = 0; k < 10; k++)
p->t[j][k] = b[j][k];//記錄信息
p->next=NULL;
p->before=q;//接起
q=p;
b[x][y]--;
b[x + x1][y + y1]++;
for(int i = 0; i < 60; i++) //過渡動畫,看起來舒服
{
blank(60 * x + i * x1, 60 * y + i * y1); //畫空地
man(60 * x + (i + 1) * x1, 60 * y + (i + 1) * y1);
Sleep(10);
}
if(b[x][y] == 3)
dest(60 * x, 60 * y);
x += x1;
y += y1;
if(b[x][y] == 4)
man1(60 * x, 60 * y);
}
else if((b[x+x1][y+y1] == 2 || b[x+x1][y+y1] == 5) && (b[x+2*x1][y+2*y1] == 0 || b[x+2*x1][y+2*y1] == 3))
{
count++;
p=(winer*)malloc(sizeof(struct winer));
q->next=p;//接起
for(int j = 0; j < 10; j++)
for(int k = 0; k < 10; k++)
p->t[j][k] = b[j][k];//記錄信息
p->next=NULL;
p->before=q;//接起
q=p;
b[x][y]--;
b[x + x1][y + y1]--;
b[x + 2 * x1][y + 2 * y1] += 2; //並用,全部爲箱子的不同狀態
for(int i = 0; i < 60; i++) //過渡動畫,看起來舒服
{
blank(60 * (x + x1) + i * x1, 60 * (y + y1) + i * y1); //畫空地
box(60 * (x + x1) + (i + 1) * x1, 60 * (y + y1) + (i + 1) * y1);
blank(60 * x + i * x1, 60 * y + i * y1); //畫空地
man(60 * x + (i + 1) * x1, 60 * y + (i + 1) * y1);
Sleep(10);
}
if(b[x][y] == 3)
dest(60 * x, 60 * y);
x += x1;
y += y1;
if(b[x][y] == 4)
man1(60 * x, 60 * y);
if(b[x+x1][y+y1] == 5)
box1(60 * (x + x1), 60 * (y + y1));
}
}
//遊戲過程
int play(int b[][10],int i)
{
loop = 0;
int m,n;
chush();
print(b); //畫界面
find(b); //通過find函數尋找人物的x, y座標
do
{
switch(getch()) //獲取鍵盤
{
case 'w':
case 'W':
move(b, -1, 0);
break; //上移
case 'a':
case 'A':
move(b, 0, -1);
break; //左移
case 'd':
case 'D':
move(b, 0, 1);
break; //右移
case 's':
case 'S':
move(b, 1, 0);
break; //下移
case 'r':
case 'R'://重新開始當前關
loop = 1;
return 0;
case ' '://回退功能
if(p == NULL || p->before==NULL || p==head)
{
break;
}
else
{
for(m = 0; m < 10; m++)
for(n = 0; n < 10; n++)
b[m][n] = p->t[m][n];
p=p->before;
free(p->next);
p->next=NULL;
find(b);
print(b);//畫界面
count--;
break;
}
case 27: //ESC結束
exit(0); //結束遊戲
break;
case 0:
case 0xE0: //如果是方向鍵
switch(getch()) //再次獲取鍵盤
{
case 72:
move(b, -1, 0);
break;
case 75:
move(b, 0, -1);
break;
case 77:
move(b, 0, 1);
break;
case 80:
move(b, 1 , 0);
}
}
char grade[M] = { 0 };
sprintf(grade, "%d", count);
setbkmode(0);//文字背景透明
settextcolor(LIGHTMAGENTA);
settextstyle(50, 0, _T("宋體"));
clearrectangle(0, 600,600, 660);
outtextxy(0, 600, "步數:");
outtextxy(150, 600, grade);
end=clock();//結束計時
char time[M] = { 0 };
sprintf(time, "%.2f秒",1.0*(end-begin)/1000 );
outtextxy(275, 600, "時間:");
outtextxy(400, 600, time);
}
while(!win(b)); //通過win函數判斷是否通過
man2(60 * x, 60 * y);//畫一個開心的皮卡丘
saveinformation(i);
getch();
free_list(head); //釋放鏈表
huanying(); //過渡動畫
return 0;
}
//遊戲關卡
void playguanka()
{
int i;
while(1)
{
system("color f9");
system("cls");
Drawjm();
tips();
do
{
printf("請輸入你想要玩第幾關(1—5)\ttips:0退出\n");
scanf("%d",&i);
if(i<0 || i>5)printf("輸入有錯誤!\n");
}
while(i<0 || i>5);
i--;
if(-1 == i)return;
huanying();
do
{
loop=0; //loop置爲0
for(int x1 = 0; x1 < 10; x1++)
for(int y1 = 0; y1 < 10; y1++)
b[x1][y1] = map[i][x1][y1]; //對當前地圖數組分別賦值
count=0;
begin=clock();
play(b,i);
}
while(loop); //如果loop被置爲1則重新開始
//printf("重新選擇\n");
}
}
//歡迎界面
void huanying()
{
initgraph(210, 210); // 創建繪圖窗口,大小爲 210x210 像素
for(int i=0; i<6; i++)
{
// 設置背景色爲藍色
setbkcolor(RGB(rand()%256,rand()%256,rand()%256));
// 用背景色清空屏幕
cleardevice();
setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 10);
setlinecolor(RGB(rand()%256,rand()%256,rand()%256));//設置線顏色
setfillcolor(RGB(rand()%256,rand()%256,rand()%256));//設置填充顏色
fillrectangle(50,50,150,150);//畫矩形
circle(100, 100, 100); // 畫圓,圓心(200, 200),半徑 100
setfillcolor(RGB(rand()%256,rand()%256,rand()%256));//設置填充顏色
fillcircle(100,100,35);
setfillcolor(RGB(rand()%256,rand()%256,rand()%256));//設置填充顏色
//solidpolygon
// 設置當前字體爲高 16 像素的“宋體”。
settextstyle(16, 0, _T("宋體"));
settextcolor(RGB(rand()%256,rand()%256,rand()%256));
// 在屏幕中央輸出字符串
RECT r = {0, 0, 210, 210};
drawtext(_T("遊戲載入中..."), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
srand(time(NULL));
Sleep(500);
}
closegraph(); // 關閉繪圖窗
}
//初始化鏈表
winer *chushihua()
{
winer *head;
head=(winer*)malloc(sizeof (winer));
if(head == NULL)
{
printf("申請頭結點失敗!\n");
return NULL;
}
head->next=NULL;
head->before=NULL;
return head;
}
//密碼登錄界面
void pass()
{
scanpassword();
passyanz();
}
//主函數
int main()
{
system("color f9");
huanying();
pass();
while(1)
{
int c;
back:
system("cls");
Drawjm();
do
{
Drawmenu();
scanf("%d",&c);
}
while(c<1 || c>4);
switch(c)
{
case 1:
printf("回車開始遊戲\n");
getch();
system("cls");
huanying();
playguanka();
break;
case 2:
passyanz();
changepassword();
goto back;
break;
case 3:
tips();
getch();
break;
case 4:
exit(0);
break;
default:
printf("錯誤輸入!!!\n");
break;
}
closegraph();
}
return 0;
}