利用C++實現的貪吃蛇遊戲

在tc 3.0下調試通過,因爲tc 3.0不支持bool 類型,所以程序中自定義了個枚舉類型變量bool

假如在vc或者bc中運行,可以把這個bool類型注釋掉.

貪吃蛇的核心算法時如何實現移動和吃掉食物.

沒有碰到食物的時候,把當前運動方向上的下個節點入隊,並以蛇節點的顔色重繪這個節點.

然後把頭指針所指的節點出隊,並以遊戲框架內部背景色重繪出隊的節點,這樣就可以達到移動的效果.

而在吃到食物的時候,則只需把食物入隊即可.

// greedsnake.cpp

#include <bios.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

#include <stdlib.h>

#include <time.h>

#include "conf.h"

typedef strUCt node

{

int x,y;

struct node *next;

}Node;

typedef struct

{

Node *head,*tail;

int length;

}Snake;

typedef struct

{

int left,top,right,bottom;

}Frame;

typedef enum //四個方向

{

up,down,left,right

}Direction;

typedef enum

{

false,true

}bool;

void InitGraphMode(); //初始化圖形驅動

void CloseGraphMode();

void Foot(int,int);

void Head(int,int);

void CreateFrame(); //完成整個遊戲框架的繪制

void CreateSnake(); //創建一條兩個節點的蛇,蛇的每一節是隊列中的一個節點

bool PlayGame(); //遊戲的主體函數,

int Hit(int,int); //判定是否越界,或者撞到自身,兩個參數分別是新的頭接點的x,y坐標

bool GameOver(); //繪制遊戲結束時彈出的對話框

void Enqueue(Node); //入隊函數

Node Dequeue(); //出隊函數

void ClearKeyBuf(); //清除鍵盤緩沖,此函數可以消除不停的按無效鍵的影響

Snake snake;

Frame frame;

void main()

{

InitGraphMode();

do

{

CreateFrame();

}while(PlayGame());

CloseGraphMode();

}

void InitGraphMode()

{

int gdriver=DETECT,gmode;

initgraph(&gdriver,&gmode,"../bgi/");

cleardevice();

}

void CloseGraphMode()

{

cleardevice();

closegraph();

}

void CreateFrame()

{

setbkcolor(CYAN);

//下面的四行代碼用于計算主框架的左上角和右下角的坐標

frame.left=(getmaxx()+1-BlockWidth*RowOfFrame)/2;

frame.top=(getmaxy()+1-BlockHeight*ColumnOfFrame)/2;

frame.right=frame.left+BlockWidth*RowOfFrame;

frame.bottom=frame.top+BlockHeight*ColumnOfFrame;

Head(frame.left+100,frame.top-20);

setfillstyle(SOLID_FILL,LIGHTGRAY);

bar(frame.left,frame.top,frame.right,frame.bottom);

setlinestyle(SOLID_LINE,1,1);

setcolor(DARKGRAY);

line(frame.left,frame.top,frame.right,frame.top);

line(frame.left,frame.top,frame.left,frame.bottom);

setlinestyle(SOLID_LINE,1,1);

setcolor(WHITE);

line(frame.left,frame.bottom,frame.right,frame.bottom);

line(frame.right,frame.top,frame.right,frame.bottom);

setlinestyle(DOTTED_LINE,1,1);

setcolor(BLUE);

for(int row=1;row<RowOfFrame;row++)

line(frame.left+row*BlockWidth,frame.top,frame.left+row*BlockWidth,frame.bottom);

for(int column=1;column<ColumnOfFrame;column++)

line(frame.left,frame.top+column*BlockHeight,frame.right,frame.top+column*BlockHeight);

Foot(frame.left,frame.bottom+20);

}

void CreateSnake()

{

Node *node1=new Node;

Node *node2=new Node;

node1->x=frame.left+BlockWidth;

node1->y=frame.top;

node1->next=NULL;

snake.tail=node1;

node2->x=frame.left;

node2->y=frame.top;

node2->next=snake.tail;

snake.head=node2;

snake.length=2;

setfillstyle(SOLID_FILL,BLUE);

bar(snake.head->x+1,snake.head->y+1,snake.head->x+BlockWidth-1,snake.head->y+BlockHeight-1);

bar(snake.tail->x+1,snake.tail->y+1,snake.tail->x+BlockWidth-1,snake.tail->y+BlockHeight-1);

}

bool PlayGame()

{

int speed=300,key;

Direction CurrentDirection=right;

Node randomNode;

Node newNode,outNode;

bool neednode=true;

bool overlap=false;

int randx,randy;

CreateSnake();

while(true)

{

if(neednode==true)

{

randomize();

do

{

randx=frame.left+rand()%RowOfFrame*BlockWidth;

randy=frame.top+rand()%ColumnOfFrame*BlockHeight;

for(Node *p=snake.head;p!=NULL;p=p->next)//hit itself

if(randx==p->x&&randy==p->y)

{overlap=true;break;}

}

while(overlap==true);

randomNode.x=randx;

randomNode.y=randy;

randomNode.next=NULL;

setfillstyle(SOLID_FILL,RED);

bar(randomNode.x+1,randomNode.y+1,randomNode.x+BlockWidth-1,randomNode.y+BlockHeight-1);

neednode=false;

}

if((key=bioskey(1))!=0)

{

switch(key)

{

case ESC: return false;

case UP:

if(CurrentDirection!=down)

CurrentDirection=up;

ClearKeyBuf();

break;

case DOWN:

if(CurrentDirection!=up)

CurrentDirection=down;

ClearKeyBuf();

break;

case LEFT:

if(CurrentDirection!=right)

CurrentDirection=left;

ClearKeyBuf();

break;

case RIGHT:

if(CurrentDirection!=left)

CurrentDirection=right;

ClearKeyBuf();

break;

case PAGEUP:speed=speed-100;

if(speed<100)

speed=100;

ClearKeyBuf();

break;

case PAGEDOWN:speed=speed+100;

if(speed>500)

speed=500;

ClearKeyBuf();

break;

default :break;

}

}

int headx=snake.tail->x;

int heady=snake.tail->y;

switch(CurrentDirection)

{

case up: heady-=BlockHeight;break;

case down: heady+=BlockHeight;break;

case left: headx-=BlockWidth;break;

case right: headx+=BlockWidth;break;

}

if(Hit(headx,heady)) //whether the snake hit the wall or itself

return GameOver();

利用C++實現的貪吃蛇遊戲
更多內容請看C/C++技術專題 網絡遊戲攻略 遊戲開發專題,或

else

{ //eat

if(headx==randomNode.x&&heady==randomNode.y)

{

Enqueue(randomNode);

setfillstyle(SOLID_FILL,BLUE);

bar(randomNode.x+1,randomNode.y+1,randomNode.x-1+BlockWidth,randomNode.y-1+BlockHeight);

neednode=true;

}

else //no eat

{

newNode.x=headx;

newNode.y=heady;

newNode.next=NULL;

Enqueue(newNode);

outNode=Dequeue();

setfillstyle(SOLID_FILL,LIGHTGRAY);

bar(outNode.x+1,outNode.y+1,outNode.x+BlockWidth-1,outNode.y+BlockHeight-1);

setfillstyle(SOLID_FILL,BLUE);

bar(newNode.x+1,newNode.y+1,newNode.x-1+BlockWidth,newNode.y-1+BlockHeight);

}

}

delay(speed);

}

}

void ClearKeyBuf()

{

do

bioskey(0);

while(bioskey(1));

}

void Foot(int x,int y)

{

setcolor(BLUE);

outtextxy(x,y,"writer:[T]RealXL E-MAIL:realgeneral@hotmail.com");

}

void Head(int x,int y)

{

setcolor(RED);

outtextxy(x,y,"GREEDY SNAKE");

}

void Enqueue(Node inNode)

{

Node *p=new Node;

p->x=inNode.x;

p->y=inNode.y;

p->next=inNode.next;

snake.tail->next=p;

snake.tail=p;

snake.length++;

}

利用C++實現的貪吃蛇遊戲
更多內容請看C/C++技術專題 網絡遊戲攻略 遊戲開發專題,或

Node Dequeue()

{

Node *p=snake.head;

Node outNode=*p;

snake.head=p->next;

snake.length--;

delete p;

return outNode;

}

int Hit(int x,int y)

{

if(x<frame.leftx>=frame.righty<frame.topy>=frame.bottom)//hit the wall

return 1;

Node *p=snake.head->next;

for(int i=snake.length-1;i>3;i--,p=p->next)//hit itself

if(x==p->x&&y==p->y)

return 1;

return 0;

}

bool GameOver()

{

int x=getmaxx()/2-50;

int y=getmaxy()/2-20;

setfillstyle(SOLID_FILL,DARKGRAY);

bar(x+3,y+3,x+103,y+43);

setfillstyle(SOLID_FILL,MAGENTA);

bar(x,y,x+100,y+40);

setlinestyle(0,3,1);

setcolor(RED);

rectangle(x,y,x+100,y+40);

outtextxy(x+20,y+10,"GAGE OVER!");

char c;

while(true) //按q或Q表示退出程序,按r或R表示重新開始遊戲

{

c=getch();

if(c=='q'c=='Q')

return false;

else if(c=='r'c=='R')

return true;

}

}

//conf.h

#ifndef _conf_h

#define _conf_h

#define RowOfFrame 20 //主框架的行數

#define ColumnOfFrame 20 //主框架的列數

#define BlockWidth 15 //每個蛇節點的寬度

#define BlockHeight 15 //每個蛇節點的高度

#define UP 18432

#define DOWN 20480

#define LEFT 19200

#define RIGHT 19712

#define ESC 283

#define ENTER 7181

#define PAGEUP 18688

#define PAGEDOWN 20736

#endif

 
用MIDP實現貪吃蛇遊戲(一)
  貪吃蛇是一款非常經典的手機遊戲,本文將使用MIDP實現這款著名的遊戲。首先我將介紹下主要用到的七個類:   WormMain:最主要的類,控制所有其它類的運行和銷毀。   WormPit:處理鍵盤輸入事件並實例化Worm類...查看完整版>>用MIDP實現貪吃蛇遊戲(一)
 
貪吃蛇遊戲的MIDP實現
概述 相信大家都玩過Nokia手機上的貪吃蛇遊戲。在該遊戲中,玩家操縱一條貪吃的蛇在迷宮裏行走,貪吃蛇按玩家所按的方向鍵折行,蛇頭吃到各種食物(比如大力丸)後,會有各種反應(比如蛇身變長),如果貪吃蛇碰上牆壁或...查看完整版>>貪吃蛇遊戲的MIDP實現
 
Excel下實現貪吃蛇小遊戲
上次我們在Excel下實現了一個華容道式的小遊戲,使用了Excel中的小部分屬性和功能,不到100行語句就完成了。這次我們要把貪吃蛇搬到Excel中,就不那麽容易了。首先要解決遊戲顯示的問題。對我們來說,小遊戲最好的平...查看完整版>>Excel下實現貪吃蛇小遊戲
 
Delphi實現貪吃蛇遊戲
Borland公司推出的開發工具Delphi6.0功能強大,我現在爲大家介紹一下利用Delphi來制作手機遊戲貪吃蛇。首先,打開New菜單,新建一個Form1,將它的Caption屬性命名爲貪吃蛇,打開System選項卡,在表單中添加一個PaintBo...查看完整版>>Delphi實現貪吃蛇遊戲
 
cleverpig分享用MIDP實現貪吃蛇遊戲的全過程
  本文由Matrix的j2me版版主cleverpig原創.clever是Matrix j2me版版主cleverpig的blog: http://www.matrix.org.cn/blog/cleverpig本文原址:http://matrix.org.cn/forum_view.ASP?forum_id=4&view_id=17199貪吃...查看完整版>>cleverpig分享用MIDP實現貪吃蛇遊戲的全過程