我想求一个Java编写的贪吃蛇游戏,要有注释和流程图最好

我想求一个Java编写的贪吃蛇游戏,要有注释和流程图最好,第1张

用MVC方式实现的贪吃蛇游戏,共有4个类。运行GreedSnake运行即可。主要是观察者模式的使用,我已经添加了很多注释了。

1、

/

程序名称:贪食蛇

原作者:BigF

修改者:algo

说明:我以前也用C写过这个程序,现在看到BigF用Java写的这个,发现虽然作者自称是Java的初学者,

但是明显编写程序的素养不错,程序结构写得很清晰,有些细微得地方也写得很简洁,一时兴起之

下,我认真解读了这个程序,发现数据和表现分开得很好,而我近日正在学习MVC设计模式,

因此尝试把程序得结构改了一下,用MVC模式来实现,对源程序得改动不多。

我同时也为程序增加了一些自己理解得注释,希望对大家阅读有帮助。

/

package mvcTest;

/

@author WangYu

@version 10

Description:

</pre>

Create on :Date :2005-6-13 Time:15:57:16

LastModified:

History:

/

public class GreedSnake {

public static void main(String[] args) {

SnakeModel model = new SnakeModel(20,30);

SnakeControl control = new SnakeControl(model);

SnakeView view = new SnakeView(model,control);

//添加一个观察者,让view成为model的观察者

modeladdObserver(view);

(new Thread(model))start();

}

}

-------------------------------------------------------------

2、

package mvcTest;

//SnakeControljava

import javaawteventKeyEvent;

import javaawteventKeyListener;

/

MVC中的Controler,负责接收用户的 *** 作,并把用户 *** 作通知Model

/

public class SnakeControl implements KeyListener{

SnakeModel model;

public SnakeControl(SnakeModel model){

thismodel = model;

}

public void keyPressed(KeyEvent e) {

int keyCode = egetKeyCode();

if (modelrunning){ // 运行状态下,处理的按键

switch (keyCode) {

case KeyEventVK_UP:

modelchangeDirection(SnakeModelUP);

break;

case KeyEventVK_DOWN:

modelchangeDirection(SnakeModelDOWN);

break;

case KeyEventVK_LEFT:

modelchangeDirection(SnakeModelLEFT);

break;

case KeyEventVK_RIGHT:

modelchangeDirection(SnakeModelRIGHT);

break;

case KeyEventVK_ADD:

case KeyEventVK_PAGE_UP:

modelspeedUp();

break;

case KeyEventVK_SUBTRACT:

case KeyEventVK_PAGE_DOWN:

modelspeedDown();

break;

case KeyEventVK_SPACE:

case KeyEventVK_P:

modelchangePauseState();

break;

default:

}

}

// 任何情况下处理的按键,按键导致重新启动游戏

if (keyCode == KeyEventVK_R ||

keyCode == KeyEventVK_S ||

keyCode == KeyEventVK_ENTER) {

modelreset();

}

}

public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

}

}

-------------------------------------------------------------

3、

/

/

package mvcTest;

/

游戏的Model类,负责所有游戏相关数据及运行

@author WangYu

@version 10

Description:

</pre>

Create on :Date :2005-6-13 Time:15:58:33

LastModified:

History:

/

//SnakeModeljava

import javaxswing;

import javautilArrays;

import javautilLinkedList;

import javautilObservable;

import javautilRandom;

/

游戏的Model类,负责所有游戏相关数据及运行

/

class SnakeModel extends Observable implements Runnable {

boolean[][] matrix; // 指示位置上有没蛇体或食物

LinkedList nodeArray = new LinkedList(); // 蛇体

Node food;

int maxX;

int maxY;

int direction = 2; // 蛇运行的方向

boolean running = false; // 运行状态

int timeInterval = 200; // 时间间隔,毫秒

double speedChangeRate = 075; // 每次得速度变化率

boolean paused = false; // 暂停标志

int score = 0; // 得分

int countMove = 0; // 吃到食物前移动的次数

// UP and DOWN should be even

// RIGHT and LEFT should be odd

public static final int UP = 2;

public static final int DOWN = 4;

public static final int LEFT = 1;

public static final int RIGHT = 3;

public SnakeModel( int maxX, int maxY) {

thismaxX = maxX;

thismaxY = maxY;

reset();

}

public void reset(){

direction = SnakeModelUP; // 蛇运行的方向

timeInterval = 200; // 时间间隔,毫秒

paused = false; // 暂停标志

score = 0; // 得分

countMove = 0; // 吃到食物前移动的次数

// initial matirx, 全部清0

matrix = new boolean[maxX][];

for (int i = 0; i < maxX; ++i) {

matrix[i] = new boolean[maxY];

Arraysfill(matrix[i], false);

}

// initial the snake

// 初始化蛇体,如果横向位置超过20个,长度为10,否则为横向位置的一半

int initArrayLength = maxX > 20 10 : maxX / 2;

nodeArrayclear();

for (int i = 0; i < initArrayLength; ++i) {

int x = maxX / 2 + i;//maxX被初始化为20

int y = maxY / 2; //maxY被初始化为30

//nodeArray[x,y]: [10,15]-[11,15]-[12,15]~~[20,15]

//默认的运行方向向上,所以游戏一开始nodeArray就变为:

// [10,14]-[10,15]-[11,15]-[12,15]~~[19,15]

nodeArrayaddLast(new Node(x, y));

matrix[x][y] = true;

}

// 创建食物

food = createFood();

matrix[foodx][foody] = true;

}

public void changeDirection(int newDirection) {

// 改变的方向不能与原来方向同向或反向

if (direction % 2 != newDirection % 2) {

direction = newDirection;

}

}

/

运行一次

@return

/

public boolean moveOn() {

Node n = (Node) nodeArraygetFirst();

int x = nx;

int y = ny;

// 根据方向增减坐标值

switch (direction) {

case UP:

y--;

break;

case DOWN:

y++;

break;

case LEFT:

x--;

break;

case RIGHT:

x++;

break;

}

// 如果新坐标落在有效范围内,则进行处理

if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {

if (matrix[x][y]) { // 如果新坐标的点上有东西(蛇体或者食物)

if (x == foodx && y == foody) { // 吃到食物,成功

nodeArrayaddFirst(food); // 从蛇头赠长

// 分数规则,与移动改变方向的次数和速度两个元素有关

int scoreGet = (10000 - 200 countMove) / timeInterval;

score += scoreGet > 0 scoreGet : 10;

countMove = 0;

food = createFood(); // 创建新的食物

matrix[foodx][foody] = true; // 设置食物所在位置

return true;

} else // 吃到蛇体自身,失败

return false;

} else { // 如果新坐标的点上没有东西(蛇体),移动蛇体

nodeArrayaddFirst(new Node(x, y));

matrix[x][y] = true;

n = (Node) nodeArrayremoveLast();

matrix[nx][ny] = false;

countMove++;

return true;

}

}

return false; // 触到边线,失败

}

public void run() {

running = true;

while (running) {

try {

Threadsleep(timeInterval);

} catch (Exception e) {

break;

}

if (!paused) {

if (moveOn()) {

setChanged(); // Model通知View数据已经更新

notifyObservers();

} else {

JOptionPaneshowMessageDialog(null,

"you failed",

"Game Over",

JOptionPaneINFORMATION_MESSAGE);

break;

}

}

}

running = false;

}

private Node createFood() {

int x = 0;

int y = 0;

// 随机获取一个有效区域内的与蛇体和食物不重叠的位置

do {

Random r = new Random();

x = rnextInt(maxX);

y = rnextInt(maxY);

} while (matrix[x][y]);

return new Node(x, y);

}

public void speedUp() {

timeInterval = speedChangeRate;

}

public void speedDown() {

timeInterval /= speedChangeRate;

}

public void changePauseState() {

paused = !paused;

}

public String toString() {

String result = "";

for (int i = 0; i < nodeArraysize(); ++i) {

Node n = (Node) nodeArrayget(i);

result += "[" + nx + "," + ny + "]";

}

return result;

}

}

class Node {

int x;

int y;

Node(int x, int y) {

thisx = x;

thisy = y;

}

}

------------------------------------------------------------

4、

package mvcTest;

//SnakeViewjava

import javaxswing;

import javaawt;

import javautilIterator;

import javautilLinkedList;

import javautilObservable;

import javautilObserver;

/

MVC模式中得Viewer,只负责对数据的显示,而不用理会游戏的控制逻辑

/

public class SnakeView implements Observer {

SnakeControl control = null;

SnakeModel model = null;

JFrame mainFrame;

Canvas paintCanvas;

JLabel labelScore;

public static final int canvasWidth = 200;

public static final int canvasHeight = 300;

public static final int nodeWidth = 10;

public static final int nodeHeight = 10;

public SnakeView(SnakeModel model, SnakeControl control) {

thismodel = model;

thiscontrol = control;

mainFrame = new JFrame("GreedSnake");

Container cp = mainFramegetContentPane();

// 创建顶部的分数显示

labelScore = new JLabel("Score:");

cpadd(labelScore, BorderLayoutNORTH);

// 创建中间的游戏显示区域

paintCanvas = new Canvas();

paintCanvassetSize(canvasWidth + 1, canvasHeight + 1);

paintCanvasaddKeyListener(control);

cpadd(paintCanvas, BorderLayoutCENTER);

// 创建底下的帮助栏

JPanel panelButtom = new JPanel();

panelButtomsetLayout(new BorderLayout());

JLabel labelHelp;

labelHelp = new JLabel("PageUp, PageDown for speed;", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutNORTH);

labelHelp = new JLabel("ENTER or R or S for start;", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutCENTER);

labelHelp = new JLabel("SPACE or P for pause", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutSOUTH);

cpadd(panelButtom, BorderLayoutSOUTH);

mainFrameaddKeyListener(control);

mainFramepack();

mainFramesetResizable(false);

mainFramesetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);

mainFramesetVisible(true);

}

void repaint() {

Graphics g = paintCanvasgetGraphics();

//draw background

gsetColor(ColorWHITE);

gfillRect(0, 0, canvasWidth, canvasHeight);

// draw the snake

gsetColor(ColorBLACK);

LinkedList na = modelnodeArray;

Iterator it = naiterator();

while (ithasNext()) {

Node n = (Node) itnext();

drawNode(g, n);

}

// draw the food

gsetColor(ColorRED);

Node n = modelfood;

drawNode(g, n);

updateScore();

}

private void drawNode(Graphics g, Node n) {

gfillRect(nx nodeWidth,

ny nodeHeight,

nodeWidth - 1,

nodeHeight - 1);

}

public void updateScore() {

String s = "Score: " + modelscore;

labelScoresetText(s);

}

public void update(Observable o, Object arg) {

repaint();

}

}

制作贪吃蛇程序一吃就死是因为代码输入错误,代码有漏洞,同学们可以用window_size设置蛇可以活动的区域大小。foods 是一个存储着所有食物位置信息的列表,每次蛇体移动后都会调用 check_eat_food 函数检查是不是吃到了某一个食物。

可以发现,检查是不是吃到和吃下去这两个动作我分为了两个函数,以做到每个函数一心一意方便后期修改。但是作为一只能照顾自己的贪吃蛇,同学们还需要能够判断当前自身状态。

贪吃蛇的程序组成思路

贪吃蛇这个游戏可以分为三大块:界面:负责显示相关的所有工作;游戏流程控制:判断游戏输赢、游戏初始化等;蛇和食物:移动自身、判断是否死亡、是否被吃等。

每一块都被做成了单独的对象,通过相互配合实现游戏。对于贪吃蛇游戏里面的蛇来讲,它可以做的事情有三种:移动,死亡(吃到自己,撞墙)和吃东西围绕着这三个功能,同学们可以首先写出一个简陋的蛇。

/

贪吃蛇游戏,由于是C++源码 且 用到Windows API ,是控制台界面不是图形界面,需要用VC++60 或 VC++2010 在windows环境编译运行。如果符合上述条件一定可以编译运行zjlj,2015316

/

#define DEBUG 0 //当程序在调试阶段时 DEBUG为 1

#include<iostream>

#include<windowsh>

#include<timeh>

#include<conioh>

using namespace std;

void readini(FILE fphead, int score, char argv[]) //创建或打开一个和运行文件对应的ini文件,读取最高纪录

{

 char filename[200],pfilename;

 int flag=-1,i;

     

    strcpy(filename,argv[0]);

    for(i=0;filename[i]!='\0';i++)

 {

  if (''==filename[i])flag=1;

 }

  

 if(1==flag)

 {

 filename[i-1]='i';

    filename[i-2]='n';

 filename[i-3]='i';

 }

 else

 {

  filename[i]='';

 filename[i+1]='i';

 filename[i+2]='n';

    filename[i+3]='i';

    filename[i+4]='\0';

 }

 for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];

    if ( (fphead=fopen(pfilename, "rb+"))==NULL)

 {

        if ( (fphead=fopen(pfilename, "wb+"))==NULL)

  {

    printf("无法创建或打开\"%s\"文件\n",pfilename);

    system("pause");

       exit(0);

  }

    }

 else

 {

  fread(score,sizeof(int),1,fphead);

 }

}

void writeini(FILE fphead, int score, char argv[])  //打开一个和运行文件对应的ini文件,写入最高纪录

{

 char filename[200],pfilename;

 int flag=-1,i;

    

    strcpy(filename,argv[0]);

    for(i=0;filename[i]!='\0';i++)

 {

  if (''==filename[i])flag=1;

 }

  

 if(1==flag)

 {

 filename[i-1]='i';

    filename[i-2]='n';

 filename[i-3]='i';

 }

 else

 {

  filename[i]='';

 filename[i+1]='i';

 filename[i+2]='n';

    filename[i+3]='i';

    filename[i+4]='\0';

 }

 for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];

    if ( (fphead=fopen(pfilename, "wb+"))==NULL)

 {

          printf("无法写入\"%s\"文件,磁盘写保护!\n",pfilename);

    system("pause");

       exit(0);

 }

 else

 {

  rewind(fphead);

  fwrite(score,sizeof(int),1,fphead);

  fclose(fphead);

 }

}

void gotoxy(int x,int y)//光标定位,光标定位函数SetConsoleCursorPosition是左上角位置是0,0然后向左向下延伸

{

COORD pos;

posX=2y;

posY=x;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

}

void color(int a)//颜色函数

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);

}

 

void Refresh(int q[][22], int grade, int gamespeed, int length,int score) //  输出贪吃蛇棋盘

{

 int i,j;

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

 {

  for(j=0;j<22;j++)

  {

   if(q[i][j]==0)//输出棋盘空白

   {

    gotoxy(i,j);

    color(11);

    cout<<"■";

   }

   if(q[i][j]==1||q[i][j]==2)//输出棋盘墙壁

   {  

    gotoxy(i,j);

    color(11);

    cout<<"□";

   }

   if(q[i][j]==3)//输出蛇头

   {  

    gotoxy(i,j);

    color(14);

    cout<<"★";

   }

   if(q[i][j]==4)//输出蛇身

   {  

    gotoxy(i,j);

    color(12);

    cout<<"◆";

   }

     if(q[i][j]==5)//输出果子

   {  

    gotoxy(i,j);

    color(12);

    cout<<"●";

   }

  }

  if(i==0) cout << "\t";

  if(i==1) cout << "\t等级为:" << grade;//显示等级

  if(i==3) cout << "\t自动前进时间";

  if(i==4) cout << "\t间隔为:" << gamespeed << "ms";//显示时间

     if(i==6) cout << "\t历史最高分为:" << score << "分";

  if(i==7) cout << "\t你现在得分为:" << (length+(grade-1)8)10 << "分";

  if(i==8) cout << "\t";

     if(i==9) cout << "\t游戏说明:";

     if(i==10) cout << "\t(1)用小键盘方向键控制";

  if(i==11) cout << "\t蛇头运动方向;";

  if(i==12) cout << "\t(2)蛇每吃一个果子蛇身";

  if(i==13) cout << "\t增加一节;";

  if(i==14) cout << "\t(3)蛇咬到自己或碰到墙";

  if(i==15) cout << "\t壁游戏结束。";

  if(i==18) cout << "\t";

     if(i==19) cout << "\tC/C++语言作业:";

     if(i==20) cout << "\tzjlj,20150316 ";

 }

}

  

int main(int argc, char argv[]){

    int tcsQipan[22][22];     //  贪吃蛇棋盘是一个二维数组(如2222,包括墙壁)

    int i,j,score,directiontemp;

 FILE  fpini;//fpini 信息文件

 readini(&fpini, &score, argv);//读取ini文件的最高纪录

 if (score<0)//最高成绩小于零设置为零,初建文件会是负数

  score=0;

 while(1)

 {

  for(i=1;i<=20;i++)

   for(j=1;j<=20;j++)

    tcsQipan[i][j]=0;    //贪吃蛇棋盘相应坐标标上中间空白部分的标志0

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

   tcsQipan[0][i] = tcsQipan[21][i] = 1;      //贪吃蛇棋盘相应坐标标上上下墙壁的标志1

  for(i=1;i<=20;i++)

   tcsQipan[i][0] = tcsQipan[i][21] = 2;      //贪吃蛇棋盘相应坐标标上左右墙壁的标志2

  int tcsZuobiao[2][500];     //蛇的坐标数组

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

  {

   tcsZuobiao[0][i] = 1;//蛇身和蛇头的x坐标

   tcsZuobiao[1][i] = i + 1;//蛇身和蛇头的y坐标

  }

  int head = 3,tail = 0;//标示蛇头和蛇尾的数组偏移量

  for(i=1;i<=3;i++)

   tcsQipan[1][i]=4;    //蛇身

  tcsQipan[1][4]=3;       //蛇头

  int x1, y1;           // 随机出果子

  srand(time(0));//设置随机种子

  do

  {

   x1=rand()%20+1;

   y1=rand()%20+1;

  }

  while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子

  tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5

  color(12);

  cout<<"\n\n\t\t\t\t贪吃蛇游戏即将开始 !"<<endl;//准备开始

  long start,starttemp;

  int grade = 1, length = 4;  //设置初始等级和蛇的初始长度

  int gamespeed = 500;  //设置初始前进时间间隔

  for(i=3;i>=0;i--)

  {

   start=clock();

   while(clock()-start<=1000);

   system("cls");

   if(i>0)

    cout << "\n\n\t\t\t\t进入倒计时:" << i << endl;  //倒计时显示

   else

    Refresh(tcsQipan,grade,gamespeed,length,score);  //初始棋盘显示

  }

  int timeover=1,otherkey=1;//初始化超时时间和按键判断参数

  char direction = 77;  // 设置初始情况下,向右运动

  int x=tcsZuobiao[0][head],y=tcsZuobiao[1][head];//保存蛇头坐标到x,y变量

  while(1)//运行一局游戏

  {

   start = clock();

   while((timeover=((starttemp=clock())-start<=gamespeed))&&!kbhit());//如果有键按下或时间超过自动前进时间间隔则终止循环

   if(direction==72||direction==80||direction==75 ||direction==77)

   directiontemp=direction;//保留上一次方向按键

            //starttemp=gamespeed+start-starttemp;//保留停留时间

   if(timeover)

   {

    #if (DEBUG==1)

    direction = getch();//调试代码

             #else

    if((direction =getch())==-32)

     direction = getch();

       #endif

   }

             #if (DEBUG==1)//调试代码

       start=clock();

    while(clock()-start<=2000);

    gotoxy(24,4);

    cout << "\t按键ASCII代码"<<(int)direction<<"    "<<endl;

             #endif

    if(!(direction==72||direction==80||direction==75 ||direction==77))

    {   

     otherkey=0;//  按键非方向键,otherkey设置为0

    }

    else

    {

     otherkey=1;//  按键为方向键,otherkey设置为1

    }

             if(direction==72 && directiontemp==80)//忽略反方向按键

    {

        direction=32;

     otherkey=0;

                 //start = clock();

        //while(clock()-start<=starttemp);

    }

    else if(direction==80 && directiontemp==72)

   {

        direction=32;//设置按键为非方向键

      otherkey=0;//  按键为非方向键,otherkey设置为0

                // start = clock();

       //while(clock()-start<=starttemp);//补偿等待时间

    }

    else if(direction==75 && directiontemp==77)

    {

        direction=32;

     otherkey=0;

                 //start = clock();

        //while(clock()-start<=starttemp);

    }

    else if(direction==77 && directiontemp==75)

    {

        direction=32;

     otherkey=0;

                 //start = clock();

        //while(clock()-start<=starttemp);

    }

     

     

    switch(direction)//判断方向键

    {

     case 72: x= tcsZuobiao[0][head]-1; y= tcsZuobiao[1][head];break;      // 向上

     case 80: x= tcsZuobiao[0][head]+1; y= tcsZuobiao[1][head];break;      // 向下

     case 75: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]-1;break;      // 向左

     case 77: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]+1;break;      // 向右

     default: break;

    }

    

  

    if(x==0 || x==21 ||y==0 || y==21)      // 蛇头碰到墙壁,结束本局游戏

    {  

     gotoxy(22,12);

     cout << "\t游戏已结束!" << endl;

     if(score>=(length+(grade-1)8)10)//判断是否破记录

     {

      gotoxy(10,7);

      color(12);

      cout << "闯关失败 加油耶!" << endl;

      fclose(fpini);//关闭ini文件

     }

     else

     {

      gotoxy(10,7);

      color(12);

      cout << "恭喜您打破记录" << endl;

      score=(length+(grade-1)8)10;

      writeini(&fpini, &score, argv);//写入ini文件的最高纪录

     }

     gotoxy(23,12);

        cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示

     break;//退出该局游戏

    }

    if(tcsQipan[x][y]!=0&&!(x==x1&&y==y1)&&tcsQipan[x][y]!=3) //   蛇头碰到蛇身,结束本局游戏

    {

     gotoxy(22,12);

     cout << "\t游戏已结束!" << endl;

     if(score>=(length+(grade-1)8)10)//判断是否破记录

     {

      gotoxy(10,7);

      color(12);

      cout << "闯关失败 加油耶!" << endl;

      fclose(fpini);//关闭ini文件

     }

     else

     {

      gotoxy(10,7);

      color(12);

      cout << "恭喜您打破记录" << endl;

      score=(length+(grade-1)8)10;

      writeini(&fpini, &score, argv);//写入ini文件的最高纪录

     }

     gotoxy(23,12);

     cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示

     break;//退出该局游戏

    }

    /

    游戏运行时的核心算法开始

    /

    if(x==x1 && y==y1) //  吃果子,长度加1

    {   

     length ++;

     if(length>=8)//长度大于等于8重新计算长度,等级加1

     {

      length -= 8;//重新计算长度

      grade ++;//等级加1

      if(gamespeed>50)//控制最快速度为50

       gamespeed = 550 - grade  50; // 改变自动前进时间间隔

     }

     tcsQipan[x][y]= 3;//贪吃蛇棋盘相应坐标现在蛇头标志改为蛇头标志3

     tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 4;//贪吃蛇棋盘相应坐标原来蛇头标志改为蛇身标志4

     head = (head+1)%400;//防止数组越界

     tcsZuobiao[0][head] = x;//蛇头的x坐标

     tcsZuobiao[1][head] = y;//蛇头的y坐标

     do//随机出果子

     {

      x1=rand()%20+1;

      y1=rand()%20+1;

     }

     while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子

     tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5

     gotoxy(22,12);

     cout << "\t游戏进行中!" << endl;

     Refresh(tcsQipan,grade,gamespeed,length,score);

    }

    else  //  不吃果子

    {  

     if(otherkey)

     {

      tcsQipan [tcsZuobiao[0][tail]][tcsZuobiao[1][tail]]=0;

      tail=(tail+1)%400;//防止数组越界

      tcsQipan [tcsZuobiao[0][head]][tcsZuobiao[1][head]]=4;

      head=(head+1)%400;//防止数组越界

      tcsZuobiao[0][head]=x;//蛇头的x坐标

      tcsZuobiao[1][head]=y;//蛇头的y坐标

      tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]]=3;

      gotoxy(22,12);

      cout << "\t游戏进行中!" << endl;

      Refresh(tcsQipan,grade,gamespeed,length,score);

     }

     else

     {

      gotoxy(22,12);

      cout << "\t游戏暂停中!" << endl;

     }

    }

    /

    游戏运行时的核心算法结束

    /

       }

    while(1)

    {

     while(!kbhit());

     if((direction =getch())==13)//按回车键开始下一局

      break;

     if(direction ==27)//按ESC退出游戏

      exit(0);

    }

       system("cls");//清除屏幕重新开始

 }

 return 0;

}

这有一个最简单的贪吃蛇的控制过程。

一般对于此类的游戏,都分为控制算法,显示算法,判定算法等几个大部分。

供参考:

#include <stdioh>

#include <windowsh>

#include <stdlibh>

#include <stringh>

#include <conioh>

#include <timeh> //使用当前时间做种子;

enum dir{up,down,left,right}; //枚举类型enum dir;

//围墙;

void InitFence();

void OutputF();

char game[20][20];

//画框框;

void InitFence(){

int i,j;

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

for(j=0; j<20; j++){

if(i==0||i==19||j==0||j==19)

game[i][j]= '';

else game[i][j]= ' ';

}

}

//显示框框;

void OutputF(){

int i,j;

for(i=0; i<20; i++){

for(j=0; j<20; j++)

printf("%c ",game[i][j]);

printf("\n");

}

}

//蛇结点;

struct SnakeNode{

int x,y;

struct SnakeNode prior,next;

}head=NULL, tail =NULL;

void add_head(int x,int y);

int get_x(struct SnakeNode p);

int get_y(struct SnakeNode p);

void delete_tail();

//插入头结点;

void add_head(int x,int y){

struct SnakeNode q= (struct SnakeNode )malloc(sizeof(struct SnakeNode));

q->x =x; q->y =y;

q->next =head;

q->prior =NULL;

if(head) head->prior =q;

head =q;

if(!tail) tail =head;

game[x][y]= ''; //f对象可以在定义Fence类时定义; 且Fence类在SnakeNode类前定义;

}

int get_x(struct SnakeNode p){

return p->x;

}

int get_y(struct SnakeNode p){

return p->y;

}

//删除尾结点;

void delete_tail(){

struct SnakeNode p =tail;

game[get_x(tail)][get_y(tail)]= ' ';//把尾结点的坐标表示的''置为空格;

if(tail==head)

tail= head= NULL;

else{

tail= tail->prior;

tail->next= NULL;

}

free(p);

}

//move移动;

struct move{

enum dir point; //枚举变量point: 控制方向;

int food_x;

int food_y;

};

void moving(struct move m);

void change_point(char,struct move m); //改变方向;

void get_food(struct move m);

void get_food(struct move m){

srand((unsigned int) time(NULL)); //做种子(程序运行时间);

m->food_x= rand()%18+1;

m->food_y= rand()%18+1;

game[m->food_x][m->food_y]= '';

}

void moving(struct move m){

int a,b;

a= get_x(head); //取得头结点横坐标

b= get_y(head); //头结点纵坐标

switch(m->point){

case up: --a; break;

case down: ++a; break;

case left: --b; break;

case right: ++b; break;

}

if(a==19||b==19||a==0||b==0){ //判断是否撞墙;

printf("game over!!!\n");

exit(0);

}

if(a==m->food_x && b==m->food_y){ //吃food;

add_head(a,b);

get_food(m);

}

else{

add_head(a,b); //插入头结点;

delete_tail(); //删除尾结点;

}

}

void change_point(char keydown,struct move m){

switch(keydown){

// case 'w': m->point= up; break;

// case 's': m->point= down; break;

// case 'a': m->point= left; break;

// case 'd': m->point= right; break;

case 72: m->point= up; break;

case 80: m->point= down; break;

case 75: m->point= left; break;

case 77: m->point= right; break;

}

}

//main();

int main(){

struct move m;

printf("Using 'w,s,a,d'to control direction!!!\n\n\n");

InitFence();

add_head(4,3);

add_head(4,4);

add_head(4,5);

get_food(&m);

OutputF();

while (1){

char keydown= getch(); //getch()返回键盘上读取的字符;包含头文件<conioh>

change_point(keydown,&m);

while(!kbhit()){ //判断有没有按键落下;

system("cls"); //清屏函数;

moving(&m);

OutputF();

Sleep(200);

}

}

return 0;

}

以上就是关于我想求一个Java编写的贪吃蛇游戏,要有注释和流程图最好全部的内容,包括:我想求一个Java编写的贪吃蛇游戏,要有注释和流程图最好、制作贪吃蛇程序怎么一吃就死、求c++贪吃蛇的代码等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9520405.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存