用java编写的贪吃蛇游戏代码
- 格式:doc
- 大小:51.00 KB
- 文档页数:12
j a v a版的贪吃蛇毕业论文Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】贪吃蛇姓名:摘要:本文用J2SE实现大家耳熟能详的一个贪吃蛇游戏来综合运用所学知识,本游戏运用软件工程思想(螺旋模型),打好游戏主体框架,JAVA的面向对象思想,封装类,接口等概念,来完成本游戏,打到综合运用知识的目的。
⑴.本游戏开发平台:WINXP;⑵.JAVA开发环境: +Eclipse;⑶.开发语言:J2SE关键词:中央控制器;游戏面板;食物;蛇;石头The Greed SnakeAbstract: In this paper, J2SE implementation of a Snake game familiar to the integrated use of what they have learned, this game is the use of software engineering thinking (spiral model), the main framework of the fight game, JAVA object-oriented thinking, wrapper classes, interface concepts to complete this game, hitting the integrated use of knowledge and purpose.⑴. The game development platform: WINXP;⑵. JAVA Development Environment: + Eclipse;⑶. Development Languages: J2SEKeywords:Controller;GamePanel;Food;Snake;Ground前言贪吃蛇游戏背景:蛇引诱夏娃吃了苹果之后,就被贬为毒虫,阴险的象征。
附录1.SnakeView类package com.example.android_snake.view;import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.Timer;import java.util.TimerTask;import com.example.android_snake.R;import com.example.android_snake.food.Food;import com.example.android_snake.snake.Body;import com.example.android_snake.snake.Head;import com.example.android_snake.snake.Snake;import com.example.android_snake.snake.SnakeDirection; import com.example.android_snake.stone.Stone;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.os.Handler;import android.util.DisplayMetrics;import android.view.Display;import android.view.MotionEvent;import android.view.View;import android.view.ViewManager;import android.view.WindowManager;import android.widget.Toast;public class SnakeView extends View {private Context context;private Bitmap headBitmap;private Bitmap bodyBitmap;private Bitmap foodBitmap;private Bitmap stoneBitmap;// 屏幕的高度和宽度private int screenHeight;private int screenWidth;// 每个小格子的高度和宽度private int eachHeight;private int eachWidth;private Snake snake;private Food food;private Stone stone;private int [] listx;private int [] listy;private Timer timer = new Timer();Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {moveSnake();invalidate();}};public SnakeView(Context context) {super(context);this.context = context;listx =new int[100];listy =new int[100];// 获得屏幕的高和宽DisplayMetrics metrics = new DisplayMetrics();WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);windowManager.getDefaultDisplay().getMetrics(metrics);screenHeight = metrics.heightPixels;screenWidth = metrics.widthPixels;eachHeight = screenHeight / 32;eachWidth = screenWidth / 20;// 初始化图片headBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.head);bodyBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.body);foodBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.food);stoneBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.stone);this.initSnake();this.initFood();this.initstone();gameRun();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();// 定义画笔paint.setColor(Color.GRAY);// 设置画笔颜色paint.setAntiAlias(true);// 去除锯齿paint.setStyle(Style.STROKE);// 设置空心实心paint.setTextSize(40);drawLines(canvas, paint);drawStone(canvas, paint);if(isCollide()){canvas.drawText("Game Over!", screenWidth/4, screenHeight/3, paint);canvas.drawText("得分", screenWidth/4, screenHeight/2, paint);timer.cancel();}else{this.drawSnake(canvas, paint);}boolean flag = IsRectCollision(snake.getHead().getPointX(), snake.getHead().getPointY(), eachWidth, eachHeight,food.getPointX(), food.getPointY(), eachWidth, eachHeight);if (flag) {food = null;snake.getBodyList().add(new Body());this.initFood();this.initstone();} else {this.drawFood(canvas, paint);this.drawStone(canvas, paint);}}//方向控制@Overridepublic boolean onTouchEvent(MotionEvent event) {int x = (int) event.getX();int y = (int) event.getY();SnakeDirection nowDir = snake.getSnakeDirection();int m = -screenHeight * x + screenHeight * screenWidth - screenWidth * y;int n = screenHeight * x - screenWidth * y;if ((m > 0 && n > 0) && (nowDir != SnakeDirection.DOWN)) {snake.setSnakeDirection(SnakeDirection.UP);} else if ((m > 0 && n < 0) && (nowDir != SnakeDirection.RIGHT)) { snake.setSnakeDirection(SnakeDirection.LEFT);} else if ((m < 0 && n > 0) && (nowDir != SnakeDirection.LEFT)) { snake.setSnakeDirection(SnakeDirection.RIGHT);} else if ((m < 0 && n < 0) && (nowDir != SnakeDirection.UP)) { snake.setSnakeDirection(SnakeDirection.DOWN);}return super.onTouchEvent(event);}public void gameRun() {timer.scheduleAtFixedRate(new TimerTask() {public void run() {handler.obtainMessage().sendToTarget();}}, 100, 400);}/** 画网格线*/public void drawLines(Canvas canvas, Paint paint) {int startX = 0, startY = 0;for (int i = 0; i < 100; i++) {canvas.drawLine(0, startY, screenWidth, startY, paint);startY = startY + eachHeight;}for (int i = 0; i < 100; i++) {canvas.drawLine(startX, 0, startX, screenHeight, paint);startX = startX + eachWidth;}canvas.drawLine(0, 0, screenWidth, screenHeight, paint);canvas.drawLine(0, screenHeight, screenWidth, 0, paint);}// 初始化蛇public void initSnake() {List<Body> bodies = new ArrayList<Body>();Head head = new Head(eachWidth * 4, eachHeight * 2, headBitmap);Body body1 = new Body(eachWidth * 3, eachHeight * 2, bodyBitmap);Body body2 = new Body(eachWidth * 2, eachHeight * 2, bodyBitmap);Body body3 = new Body(eachWidth * 1, eachHeight * 2, bodyBitmap);Body body4 = new Body(eachWidth * 0, eachHeight * 2, bodyBitmap);bodies.add(body1);bodies.add(body2);bodies.add(body3);bodies.add(body4);snake = new Snake(head, bodies, SnakeDirection.RIGHT);}// 画蛇public void drawSnake(Canvas canvas, Paint paint) {canvas.drawBitmap(headBitmap, snake.getHead().getPointX(), snake .getHead().getPointY(), paint);for (int i = 0; i < snake.getBodyList().size(); i++) {canvas.drawBitmap(bodyBitmap, snake.getBodyList().get(i).getPointX(), snake.getBodyList().get(i).getPointY(), paint);}}// 改变蛇身的位置public void changSnakePosition(int pointX, int pointY) {for (int i = snake.getBodyList().size() - 1; i > 0; i--) {snake.getBodyList().get(i).setPointX(snake.getBodyList().get(i - 1).getPointX());snake.getBodyList().get(i).setPointY(snake.getBodyList().get(i - 1).getPointY());}snake.getBodyList().get(0).setPointX(snake.getHead().getPointX());snake.getBodyList().get(0).setPointY(snake.getHead().getPointY());}// 移动蛇public void moveSnake() {int nowPointX = snake.getHead().getPointX();int nowPointY = snake.getHead().getPointY();if (snake.getSnakeDirection() == SnakeDirection.RIGHT) {changSnakePosition(nowPointX, nowPointY);if (nowPointX >= screenWidth - eachWidth) {snake.getHead().setPointX(0);} else {snake.getHead().setPointX(nowPointX + eachWidth);}} else if (snake.getSnakeDirection() == SnakeDirection.DOWN) { changSnakePosition(nowPointX, nowPointY);if (nowPointY >= screenHeight - eachHeight) {snake.getHead().setPointY(0);} else {snake.getHead().setPointY(nowPointY + eachHeight);}} else if (snake.getSnakeDirection() == SnakeDirection.LEFT) {changSnakePosition(nowPointX, nowPointY);if (nowPointX <= 0) {snake.getHead().setPointX(screenWidth - eachWidth);} else {snake.getHead().setPointX(nowPointX - eachWidth);}} else if (snake.getSnakeDirection() == SnakeDirection.UP) {changSnakePosition(nowPointX, nowPointY);if (nowPointY <= 0) {snake.getHead().setPointY(screenHeight - eachHeight);} else {snake.getHead().setPointY(nowPointY - eachHeight);}}}// 初始化foodpublic void initFood() {int x = new Random().nextInt(19);int y = new Random().nextInt(29);food = new Food(eachWidth * x, eachHeight * y, foodBitmap);}// 在界面上画出Foodpublic void drawFood(Canvas canvas, Paint paint) {if (food != null) {canvas.drawBitmap(foodBitmap, food.getPointX(), food.getPointY(),paint);}}// 初始化stonepublic void initstone() {int x = new Random().nextInt(17);int y = new Random().nextInt(23);stone = new Stone(eachWidth * x, eachHeight * y, stoneBitmap);int i=0,j=0;listx[i++]=x;listy[j++]=y;}// 在界面上画出Stonepublic void drawStone(Canvas canvas, Paint paint) {if (true) {canvas.drawBitmap(stoneBitmap, stone.getPointX(), stone.getPointY(),paint);for(int k=0;k<100;k++){//food = new Food(eachWidth * listx[k], eachHeight * listy[k], foodBitmap);//canvas.drawBitmap(stoneBitmap,listx[k], listy[k],paint);}}}/*** 矩形碰撞检测参数为x,y,width,height** @param x1* 第一个矩形的x* @param y1* 第一个矩形的y* @param w1* 第一个矩形的w* @param h1* 第一个矩形的h* @param x2* 第二个矩形的x* @param y2* 第二个矩形的y* @param w2* 第二个矩形的w* @param h2* 第二个矩形的h* @return是否碰撞*/public boolean IsRectCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {if (x2 > x1 && x2 >= x1 + w1) {return false;} else if (x2 < x1 && x2 <= x1 - w2) {return false;} else if (y2 > y1 && y2 >= y1 + h1) {return false;} else if (y2 < y1 && y2 <= y1 - h2) {return false;} else {return true;}}//检测蛇头是否与蛇身碰撞//检测蛇头与墙的碰撞//public boolean isCollide() {boolean flag = false;for (int i = 0; i < snake.getBodyList().size(); i++) {flag = IsRectCollision(snake.getHead().getPointX(),snake.getHead().getPointY(), eachWidth, eachHeight,snake.getBodyList().get(i).getPointX(),snake.getBodyList().get(i).getPointY(),eachWidth,eachHeight);for(int j=0;j<100;j++){flag = IsRectCollision(snake.getHead().getPointX(),snake.getHead().getPointY(), eachWidth, eachHeight,listx[j],listy[j], eachWidth,eachHeight);if(flag){break;}}if ((snake.getHead().getPointX() < 1) ||(snake.getHead().getPointY() < 1) ||(snake.getHead().getPointX() > screenWidth - 1)||(snake.getHead().getPointY() > screenHeight - 1)){flag = true;}if(flag){break;}}return flag;}}2.MainActivity类package com.example.android_snake;import com.example.android_snake.R;import com.example.android_snake.view.SnakeView;//Downloads By import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.MenuItem;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);//设置全屏getWindow().setFlags(youtParams.FLAG_FULLSCREEN, youtParams.FLAG_FULLSCREEN);SnakeView view = new SnakeView(this);setContentView(view);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu);return true;}}3.Food类package com.example.android_snake.food;import android.graphics.Bitmap;public class Food {private int pointX;private int pointY;private Bitmap foodBitmap;public Food() {super();}public Food(int pointX, int pointY, Bitmap foodBitmap) { super();this.pointX = pointX;this.pointY = pointY;this.foodBitmap = foodBitmap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getFoodBitmap() {return foodBitmap;}public void setFoodBitmap(Bitmap foodBitmap) {this.foodBitmap = foodBitmap;}}4.Body类package com.example.android_snake.snake;import android.graphics.Bitmap;public class Body {private int pointX;private int pointY;private Bitmap bodyBitMap;public Body() {super();}public Body(int pointX, int pointY, Bitmap bodyBitMap) { super();this.pointX = pointX;this.pointY = pointY;this.bodyBitMap = bodyBitMap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getBodyBitMap() {return bodyBitMap;}public void setBodyBitMap(Bitmap bodyBitMap) {this.bodyBitMap = bodyBitMap;}}5.Head类package com.example.android_snake.snake;import android.graphics.Bitmap;public class Head {private int pointX;private int pointY;private Bitmap headBitMap;public Head() {super();}public Head(int pointX, int pointY, Bitmap headBitMap) {super();this.pointX = pointX;this.pointY = pointY;this.headBitMap = headBitMap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getHeadBitMap() {return headBitMap;}public void setHeadBitMap(Bitmap headBitMap) {this.headBitMap = headBitMap;}}6.Snake类package com.example.android_snake.snake;import java.util.ArrayList;import java.util.List;import android.graphics.Bitmap;public class Snake {private Head head;private Body body;private List<Body> bodyList;private SnakeDirection snakeDirection;public Snake(){}public Snake(Head head,List<Body> bodyList,SnakeDirection snakeDirection){ super();this.head = head;this.bodyList = bodyList;this.snakeDirection = snakeDirection;}public Head getHead() {return head;}public void setHead(Head head) {this.head = head;}public Body getBody() {return body;}public void setBody(Body body) {this.body = body;}public List<Body> getBodyList() {return bodyList;}public void setBodyList(List<Body> bodyList) {this.bodyList = bodyList;}public SnakeDirection getSnakeDirection() {return snakeDirection;}public void setSnakeDirection(SnakeDirection snakeDirection) { this.snakeDirection = snakeDirection;}}7.SnakeDirection类package com.example.android_snake.snake;public enum SnakeDirection {UP,DOWN,LEFT,RIGHT;}8.Stone类package com.example.android_snake.stone;import android.graphics.Bitmap;public class Stone {private int pointX;private int pointY;private Bitmap stoneBitmap;public Stone() {super();}public Stone(int pointX, int pointY, Bitmap foodBitmap) { super();this.pointX = pointX;this.pointY = pointY;this.stoneBitmap = stoneBitmap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getStoneBitmap() {return stoneBitmap;}public void setFoodBitmap(Bitmap foodBitmap) { this.stoneBitmap = stoneBitmap;}}。
《简单的贪吃蛇游戏代码示例,使用Python语言和pygame库实现:》import pygameimport random# 初始化pygamepygame.init()# 设置窗口大小和标题screen_width = 640screen_height = 480screen = pygame.display.set_mode((screen_width, screen_height))pygame.display.set_caption("Snake Game")# 设置颜色white = (255, 255, 255)black = (0, 0, 0)red = (255, 0, 0)# 定义蛇的初始位置和长度snake_pos = [[100, 50], [90, 50], [80, 50]]snake_len = len(snake_pos)# 定义游戏结束标志和得分game_over = Falsescore = 0# 定义蛇的移动方向和速度direction = "right"speed = 10# 定义食物的初始位置和大小food_pos = [random.randint(1, screen_width-1), random.randint(1, screen_height-1)]food_size = 20# 定义边界和障碍物的大小和位置border = 10obstacle_size = 200obstacle_pos = [random.randint(border, screen_width-border), random.randint(border, screen_height-border)]obstacle_speed = 2# 游戏循环while not game_over:# 处理事件for event in pygame.event.get():if event.type == pygame.QUIT:game_over = Trueelif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP and direction != "down":direction = "up"elif event.key == pygame.K_DOWN and direction != "up":direction = "down"elif event.key == pygame.K_LEFT and direction != "right":direction = "left"elif event.key == pygame.K_RIGHT and direction != "left":direction = "right"elif event.type == pygame.KEYUP:if event.key == pygame.K_UP and direction == "up":direction = "right" if random.randint(0, 1) else "left"elif event.key == pygame.K_DOWN and direction == "down": direction = "right" if random.randint(0, 1) else "left"elif event.key == pygame.K_LEFT and direction == "left":direction = "up" if random.randint(0, 1) else "down"elif event.key == pygame.K_RIGHT and direction == "right": direction = "up" if random.randint(0, 1) else "down"。
贪吃蛇(HTML小游戏使用JavaScript开发)贪吃蛇:HTML小游戏使用JavaScript开发在游戏界,贪吃蛇是非常经典和受欢迎的一款小游戏。
它的简单和上瘾性使得无数玩家沉迷其中。
今天,我们将学习如何使用HTML和JavaScript来开发一个贪吃蛇的小游戏。
一、游戏的基本思路贪吃蛇的游戏规则非常简单明了。
玩家控制蛇的移动,通过吃食物来不断增长蛇的长度。
当蛇碰到墙壁或者自己的身体时,游戏结束。
游戏的目标是使蛇长得尽可能长,挑战自己的最高得分。
二、HTML布局首先,我们需要在HTML文件中创建游戏画布。
这个画布将用于显示游戏的界面。
我们可以通过HTML的"canvas"元素来实现。
```html<!DOCTYPE html><html><head><title>贪吃蛇</title><style>#gameCanvas {border: 1px solid black;}</style></head><body><canvas id="gameCanvas" width="400" height="400"></canvas><script>// 在这里编写JavaScript代码</script></body></html>```上面的代码中,我们创建了一个宽高为400像素的画布,并给它设置了一个边框。
三、JavaScript逻辑接下来,我们需要使用JavaScript来实现游戏的逻辑。
我们将使用一个JavaScript类来表示贪吃蛇,并在其中实现移动、吃食物等功能。
```javascript<script>class SnakeGame {constructor(canvasId) {this.canvas = document.getElementById(canvasId);this.context = this.canvas.getContext("2d");this.snake = new Snake();this.food = new Food();// 在这里添加事件监听器,监听用户的方向键输入this.gameLoop();}// 游戏主循环gameLoop() {// 清空画布this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); // 更新蛇的位置this.snake.update();// 绘制蛇和食物this.snake.draw(this.context);this.food.draw(this.context);// 在下一帧时再次调用游戏主循环requestAnimationFrame(() => this.gameLoop()); }}class Snake {constructor() {// 在这里初始化蛇的位置和长度等信息}update() {// 在这里更新蛇的位置和长度等信息}draw(context) {// 在这里使用context绘制蛇的形状}}class Food {constructor() {// 在这里初始化食物的位置等信息}draw(context) {// 在这里使用context绘制食物的形状}}// 创建一个名为"game"的SnakeGame实例const game = new SnakeGame("gameCanvas");</script>```在上面的代码中,我们创建了一个`SnakeGame`类来表示游戏,`Snake`类来表示蛇,和`Food`类来表示食物。
JAVA开放性实验报告贪吃蛇实验目的:本实验旨在利用Java语言实现一个经典的贪吃蛇游戏,通过实践提升对面向对象程序设计的理解和应用能力,加深对Java语言的熟练程度,并提高解决问题的能力和编程实践经验。
实验内容:1.设计游戏界面:通过Java中的Swing库实现游戏窗口的设计,包括游戏区域、游戏开始按钮、得分显示等。
2.实现游戏逻辑:设计贪吃蛇的移动规则,食物的生成和吃掉判定,碰撞检测等游戏逻辑。
同时实现游戏的主循环,控制游戏的进行。
3.实现键盘控制:通过监听键盘事件,实现玩家控制贪吃蛇的移动方向。
4.设计游戏机制:设置游戏的难度等级,增加贪吃蛇的移动速度、食物生成间隔等参数,使游戏更具挑战性。
5.设计游戏结束逻辑:当贪吃蛇头碰到墙壁或自身时,游戏结束并显示得分。
玩家可以选择重新开始游戏或退出。
实验步骤:1.设计游戏界面:创建一个JFrame窗口,在窗口中添加游戏画布,开始按钮和得分显示等组件。
2.实现游戏逻辑:设计Snake类和Food类,表示贪吃蛇和食物。
通过ArrayList存储贪吃蛇的身体节点,并实现移动、吃食物等方法。
3.实现键盘控制:通过实现KeyListener接口来监听键盘事件,根据按键控制贪吃蛇的移动方向。
4.设计游戏机制:设置贪吃蛇的移动速度、食物生成间隔等参数,根据难度级别逐步增加,使游戏更具挑战性。
5.设计游戏结束逻辑:当贪吃蛇头碰到墙壁或自身时,游戏结束并显示得分。
提供重新开始游戏和退出游戏的选项。
实验结果:经过实验设计和编码实现,成功完成了Java贪吃蛇游戏的开发。
游戏界面美观,操作流畅,游戏逻辑完整,玩家能够通过控制贪吃蛇吃到食物并获得得分。
随着游戏的进行,贪吃蛇会不断变长,玩家需要避开障碍,控制蛇头移动,体验游戏的乐趣和挑战。
实验总结:通过本次实验,我深入学习了Java语言的面向对象编程思想和应用,掌握了Swing库的使用方法,加深了对Java语言的理解和应用。
JAVA贪吃蛇源代码SnakeGame。
javapackage SnakeGame;import javax.swing。
*;public class SnakeGame{public static void main( String[]args ){JDialog。
setDefaultLookAndFeelDecorated( true ); GameFrame temp = new GameFrame();}}Snake.javapackage SnakeGame;import java。
awt.*;import java。
util。
*;class Snake extends LinkedList{public int snakeDirection = 2;public int snakeReDirection = 4;public Snake(){this。
add( new Point( 3, 3 ));this。
add(new Point(4, 3 ));this.add( new Point(5,3 ) );this。
add( new Point(6,3 ) );this。
add(new Point(7,3 ));this。
add( new Point( 8,3 ) );this。
add( new Point( 9, 3 ));this。
add( new Point( 10,3 ));}public void changeDirection( Point temp, int direction ) {this。
snakeDirection = direction;switch(direction ){case 1://upthis.snakeReDirection = 3;this。
add( new Point(temp.x,temp.y - 1 ));break;case 2://rightthis。
近年来,Java作为一种新的编程语言,以其简单性、可移植性和平台无关性等优点,得到了广泛地应用,特别是Java与万维网的完美结合,使其成为网络编程和嵌入式编程领域的首选编程语言。
Eclipse是一个开放源代码的、基于Java的可扩展开发平台,同时它也是是著名的跨平台的自由集成开发环境,它以其友好的开发界面、强大的组件支持等优点,得到广大程序员的接受和认可。
贪吃蛇是人们手机中是一个很常见的一个经典小游戏,人们对它并不陌生,在紧张的现实生活中给人们带来了不少的乐趣,编写这个贪吃蛇小游戏能让人们在业余时间里适当的放松,保持好的心态。
在这个程序中我采用了Java中的图形用户界面技术,同时引入了线程来编写。
本次设计主要是对我之前所学Java知识的一个巩固,不仅提高了我综合运用以前所学知识的能力,同时也锻炼了我的实际动手能力。
整个游戏代码简单易懂,用户在娱乐的同时也可以简单的看一下代码,有助于初涉Java者语言水平的提高。
贪吃蛇的核心算法是如何实现移动和吃掉食物,在当前运动方向上头指针所指的位置之前添加一个节点,然后删除尾节点,最后把链表中的所有节点依次画出来,这样就可以达到移动的效果。
对是否吃到食物,需要对蛇和食物进行碰撞检测,检测未碰撞在一起则只需要执行移动操作,碰撞在一起时表示吃到食物,则只需把食物入队即可,即在蛇的节点链表上再添加一个节点,从而达到身体增长的效果。
本次设计的重点之处在于编程思想的形成,设计图像界面,产生随机食物及其位置。
难点在于程序编写中,整个程序框架的架构。
这就要求我们不仅要对这个游戏的玩法特别熟悉,而且还要熟练掌握Java 语言。
实现贪吃蛇的四个类模块,分别为游戏界面、蛇、食物和方向。
其具体设计如下:1产生游戏界面Yard.java包括界面的位置、大小的设定,绘制游戏界面,启动键盘监听器。
1)在launch()中添加代码:this.setBounds(200,200,COLS*BLOCK_SIZE,ROWS*BLOCK _SIZE);设定界面的位置、大小。
代码:一:::::::public class Cell {// 格子:食物或者蛇的节点private int x;private int y;private Color color;// 颜色public Cell() {}public Cell(int x, int y) {this.x = x;this.y = y;}public Cell(int x, int y, Color color) { this.color = color;this.x = x;this.y = y;}public Color getColor() {return color;}public int getX() {return x;}public int getY() {return y;}public String toString() {return"[" + x + "]" + "[" + y + "]";}}二::::::::::public class Worm {private int currentDirection;// 蛇包含的格子private Cell[] cells;private Color color;public static final int UP = 1;public static final int DOWN = -1;public static final int RIGHT = 2;public static final int LEFT = -2;// 创建对象创建默认的蛇:(0,0)(1,0)(2,0)······(11,0)public Worm() {// 构造器初始化对象color = Color.pink;// 蛇的颜色cells = new Cell[12];// 创建数组对象for (int x = 0, y = 0, i = 0; x < 12; x++) { // for(int y=0;;){}cells[i++] = new Cell(x, y, color);// 添加数组元素}currentDirection = DOWN;}public boolean contains(int x, int y) {// 数组迭代for (int i = 0; i < cells.length; i++) {Cell cell = cells[i];if (cell.getX() == x && cell.getY() == y) {return true;}}return false;}public String toString() {return Arrays.toString(cells);}public void creep() {for (int i = this.cells.length - 1; i >= 1; i--) {cells[i] = cells[i - 1];}cells[0] = createHead(currentDirection);}// 按照默认方法爬一步private Cell createHead(int direction) {// 根据方向,和当前(this)的头结点,创建新的头结点int x = cells[0].getX();int y = cells[0].getY();switch (direction) {case DOWN:y++;break;case UP:y--;break;case RIGHT:x++;break;case LEFT:x--;break;}return new Cell(x, y);}/*** food 食物**/public boolean creep(Cell food) {Cell head = createHead(currentDirection);boolean eat = head.getX() == food.getX() && head.getY() == food.getY();if (eat) {Cell[] ary = Arrays.copyOf(cells, cells.length + 1);cells = ary;// 丢弃原数组}for (int i = cells.length - 1; i >= 1; i--) { cells[i] = cells[i - 1];}cells[0] = head;return eat;}// 吃到东西就变长一格public boolean creep(int direction, Cell food) {if (currentDirection + direction == 0) {return false;}this.currentDirection = direction;Cell head = createHead(currentDirection);boolean eat = head.getX() == food.getX() && head.getY() == food.getY();if (eat) {Cell[] ary = Arrays.copyOf(cells, cells.length + 1);cells = ary;// 丢弃原数组}for (int i = cells.length - 1; i >= 1; i--) { cells[i] = cells[i - 1];}cells[0] = head;return eat;}// 检测在新的运动方向上是否能够碰到边界和自己(this 蛇)public boolean hit(int direction) {// 生成下个新头节点位置// 如果新头节点出界返回true,表示碰撞边界// ···············if (currentDirection + direction == 0) {return false;}Cell head = createHead(direction);if(head.getX() < 0 || head.getX() >= WormStage.COLS || head.getY() < 0|| head.getY() >= WormStage.ROWS) {return true;}for (int i = 0; i < cells.length - 1; i++) { if (cells[i].getX() == head.getX()&& cells[i].getY() == head.getY()) {return true;}}return false;}public boolean hit() {return hit(currentDirection);}// 为蛇添加会制方法// 利用来自舞台面板的画笔绘制蛇public void paint(Graphics g) {g.setColor(this.color);for (int i = 0; i < cells.length; i++) {Cell cell = cells[i];g.fill3DRect(cell.getX() * WormStage.CELL_SIZE, cell.getY()* WormStage.CELL_SIZE, WormStage.CELL_SIZE,WormStage.CELL_SIZE, true);}}}三:::::::::public class WormStage extends JPanel {/** 舞台的列数 */public static final int COLS = 35;/** 舞台的行数 */public static final int ROWS = 35;/** 舞台格子的大小 */public static final int CELL_SIZE = 10;private Worm worm;private Cell food;public WormStage() {worm = new Worm();food = createFood();}/*** 随机生成食物,要避开蛇的身体 1 生成随机数 x, y 2 检查蛇是否包含(x,y)* 3 如果包含(x,y) 返回 1 4 创建食物节点* */private Cell createFood() {Random random = new Random();int x, y;do {x = random.nextInt(COLS);// COLS列数y = random.nextInt(ROWS);// WOWS行数} while (worm.contains(x, y));return new Cell(x, y, Color.green);// 食物颜色/** 初始化的舞台单元测试 */public static void test() {WormStage stage = new WormStage();System.out.println(stage.worm);System.out.println(stage.food);}/*** 重写JPanel绘制方法paint:绘制,绘画,涂抹Graphics 绘图,* 理解为:绑定到当前面板的画笔*/public void paint(Graphics g) {// 添加自定义绘制!// 绘制背景g.setColor(Color.darkGray);// 背景色g.fillRect(0, 0, getWidth(), getHeight());g.setColor(Color.cyan);// 边框上的颜色// draw 绘制 Rect矩形g.drawRect(0, 0, this.getWidth() - 1, this.getHeight() - 1);// 绘制食物g.setColor(food.getColor());// fill 填充 3D 3维 Rect矩形突起的立体按钮形状g.fill3DRect(food.getX() * CELL_SIZE, food.getY() * CELL_SIZE,CELL_SIZE, CELL_SIZE, true);// 绘制蛇worm.paint(g);// 让蛇自己去利用画笔绘制private Timer timer;/*** 启动定时器驱动蛇的运行 1 检查碰撞是否将要发生* 2 如果发生碰撞:创建新的蛇和食物,重写开始* 3 如果没有碰撞就爬行,并检查是否能够吃到食物* 4如果吃到食物:重新创建新的食物* 5 启动重新绘制界面功能 repaint() 更新界面显示效果! repaint()* 方法会尽快调用paint(g) 更新界面!*/private void go() {if (timer == null)timer = new Timer();timer.schedule(new TimerTask() {public void run() {if (worm.hit()) {// 如果蛇碰到边界或自己worm = new Worm();// 创建新的蛇food = createFood();// 创建新食物} else {// 如果没有碰到自己boolean eat = worm.creep(food);// 蛇向前(当前方向)爬行,返回结果表示是否吃到食物if(eat) {// 如果吃到食物,就生成新食物food = createFood();}}repaint();}}, 0, 1000 / 5);this.requestFocus();this.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {int key = e.getKeyCode();switch (key) {case KeyEvent.VK_UP:creepForFood(Worm.UP);break;case KeyEvent.VK_DOWN:creepForFood(Worm.DOWN);break;case KeyEvent.VK_LEFT:creepForFood(Worm.LEFT);break;case KeyEvent.VK_RIGHT:creepForFood(Worm.RIGHT);break;}}});}private void creepForFood(int direction) { if (worm.hit(direction)) {worm = new Worm();food = createFood();} else {boolean eat = worm.creep(direction, food);if (eat) {food = createFood();}}}/** 软件启动的入口方法 */public static void main(String[] args) {// 启动软件....JFrame frame = new JFrame("贪吃蛇");// 一个画框对象frame.setSize(450, 480);// size 大小,setSize 设置大小// frame.setLocation(100,50);//Locationq位置frame.setLocationRelativeTo(null);// 居中// 设置默认的关闭操作为在关闭时候离开软件frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);// Visible可见的设置可见性frame.setLayout(null);// 关闭默认布局管理,避免面板充满窗口WormStage stage = new WormStage();// System.out.println("CELL_SIZE * COLS:"+CELL_SIZE * COLS);stage.setSize(CELL_SIZE* COLS, CELL_SIZE* ROWS);stage.setLocation(40, 50);stage.setBorder(new LineBorder(Color.BLACK));frame.add(stage);// 在窗口添加舞台stage.go();// 启动定时器驱动蛇自动运行}}。
用Java编写的贪吃蛇代码下面是我用java编写的一个贪吃蛇游戏源代码.我个人是比较喜欢玩游戏的,所以学习编程二年多了,很想做个游戏程序,由于能力有限,一直没能做好,后来突然看同学在手机上玩“贪吃蛇”,故想做出来,其一是因为此游戏界面容易设计,算法也比较简单,今天我就把我程序的代码和算法介绍一下,顺便把程序界面皮肤设计说一下......程序中一个关于游戏信息的类如下,由于类的说明在程序中写的很清楚了,就不再多解释了:#include "time.h"//方向定义const CPoint UP(CPoint(0,-1));const CPoint DOWN(CPoint(0,1));const CPoint LEFT(CPoint(-1,0));const CPoint RIGHT(CPoint(1,0));//速度快慢定义const int HIGH = 75;const int NORMAL = 180;const int SLOW = 300;const int MAX = 80; //表示转向数const int LENGTH = 10;class GameMsg{public:GameMsg(void): m_icon(0){InitGame();}void InitGame(int up = VK_UP, int down = VK_DOWN, int left = VK_LEFT, int right = VK_RIGHT){srand((unsigned)time(NULL));m_gameSpeed = NORMAL;m_speedNum = 2;m_snakeNum = 4;for(int i=0; i<m_snakeNum; ++i)m_snakePoint[i] = CPoint(5+LENGTH*2*5+LENGTH,LENGTH*2*(i+5));m_run = true;m_direction = RIGHT;turnUP = up;turnDOWN = down;turnLEFT = left;turnRIGHT = right;}public:int m_gameSpeed;//游戏速度int m_speedNum;//游戏速度数CPoint m_foodPoint; //食物定义bool m_run;//游戏状态,运得态还是暂停(结束)态CPoint m_snakePoint[MAX]; //蛇身定义CPoint m_direction;//蛇运动方向int m_snakeNum; //蛇身结点数int m_icon;//用来设定食物是那种图标的int turnUP;//用来表示玩家“上”键设的键int turnDOWN;//用来表示玩家“下”键设的键int turnLEFT;//用来表示玩家“左”键设的键int turnRIGHT;//用来表示玩家“右”键设的键int m_num;//用来记录所选水果的编号};再让读者看一下程序主干类的设计,其中以下只列出由我们自己添加的一些变量的说明,其他的是由程序向导自动生成的,我就不说了:public:afx_msg void OnTimer(UINT_PTR nIDEvent);//程序中运行函数,即是一个定时器,时间就是上面类中的m_gameSpeed来控制的CStatic *m_staticArray;//这是一个蛇定义,是用来显示蛇的,上面只告诉蛇身结点的中心点位置坐标,然后在此中心画一个控件就类似于蛇身了afx_msg void OnClose();//结束,主要是在其中销毁定时器的void GameOver(void);//游戏结束函数afx_msg void OnRButtonDown(UINT nFlags, CPoint point);//当点击鼠标右键出现菜单afx_msg void OnNewGame();//菜单选项,新游戏afx_msg void OnPauseOrStart();//菜单选项,暂停/开始游戏afx_msg void OnUpdateQuick(CCmdUI *pCmdUI);//这3个函数本来是来标记速度的,和上面类中的m_speedNum对应,但是没有标记成功afx_msg void OnUpdateNormal(CCmdUI *pCmdUI);afx_msg void OnUpdateSlow(CCmdUI *pCmdUI);afx_msg void OnNormal();//菜单选项,设定为普通速度afx_msg void OnSlow();//菜单选项,设定为慢速度afx_msg void OnQuick();//菜单选项,设定为快速度afx_msg void OnIntroduce();//游戏介绍,就是弹出一个对话框而以afx_msg void OnMoreprogram();//进入我的博客的函数afx_msg void OnAbout();//关于“贪吃蛇”说明的对话框afx_msg void OnExit();//退出游戏CFont m_font;//这就是上图中显示“空心字体”的字体设置void ShowHollowFont(int cx, int cy, CString str);//显示空心字体函数,在(Cx,Cy)处显示字符串strafx_msg void OnBnClickedExit();//退出游戏private:int m_icon1;//表明蛇吃第1种水果的个数int m_icon2;//表明蛇吃第2种水果的个数int m_icon3;//表明蛇吃第3种水果的个数然后给读者写的是我程序运行很重要的一个函数,WM_TIMER显示函数,里面有食物位置随机出现,判断蛇死,蛇移动等:void CSnakeDlg::OnTimer(UINT_PTR nIDEvent){if(game.m_snakePoint[0].x < 0 || game.m_snakePoint[0].y < LENGTH || game.m_snakePoint[0].x > 700 || game.m_snakePoint[0].y > 500)//当蛇跑出边界,游戏结束{GameOver();}for(int j=game.m_snakeNum-1; j>0; --j)//蛇移动的量的变化,当重新设定这些控件的位置时也就是让蛇移动起来game.m_snakePoint[j] = game.m_snakePoint[j-1];game.m_snakePoint[0].x += game.m_direction.x * LENGTH * 2;//蛇头移动game.m_snakePoint[0].y += game.m_direction.y * LENGTH * 2;for(int i=0; i<game.m_snakeNum; ++i){m_staticArray[i].SetWindowPos( NULL, game.m_snakePoint[i].x - LENGTH, game.m_snakePoint[i].y - LENGTH, game.m_snakePoint[i].x + LENGTH, game.m_snakePoint[i].y + LENGTH,SW_SHOW);}for(int j=1; j<game.m_snakeNum; ++j)//当蛇撞到自己也结束游戏if(game.m_snakePoint[0] == game.m_snakePoint[j]){GameOver();}m_staticArray[MAX].ModifyStyle(0xF,SS_ICON | SS_CENTERIMAGE);//显示水果m_staticArray[MAX].SetIcon(AfxGetApp()->LoadIcon(game.m_icon));m_staticArray[MAX].SetWindowPos( NULL, game.m_foodPoint.x, game.m_foodPoint.y, 32, 32,SW_SHOW);//当蛇吃到水果if(game.m_snakePoint[0].x < game.m_foodPoint.x+20+LENGTH && game.m_snakePoint[0].x > game.m_foodPoint.x-LENGTH && game.m_snakePoint[0].y < game.m_foodPoint.y+20+LENGTH && game.m_snakePoint[0].y > game.m_foodPoint.y-LENGTH){game.m_foodPoint = CPoint(LENGTH*game.RandNum(2,37), LENGTH*game.RandNum(2,27));CString str;if(game.m_num == 0){++m_icon1;str.Format("%d",m_icon1);GetDlgItem(IDC_EDIT1)->SetWindowTextA(str);}else if(game.m_num == 1){++m_icon2;str.Format("%d",m_icon2);GetDlgItem(IDC_EDIT2)->SetWindowTextA(str);}else{++m_icon3;str.Format("%d",m_icon3);GetDlgItem(IDC_EDIT3)->SetWindowTextA(str);}game.m_num = game.RandNum(0,3);game.m_icon = IDI_ICON1 + game.m_num;//重新加1个水果game.m_snakeNum++;//蛇的长度加1 str.Format("%d",game.m_snakeNum);GetDlgItem(IDC_EDIT4)->SetWindowTextA(str);}CDialog::OnTimer(nIDEvent);}如下再介绍应用在对话框中来响应键盘消息,我写的是一个键盘“钩子”,代码如下:HHOOK g_hKeyboard = NULL;HWND g_hWnd = NULL;LRESULT CALLBACK KeyboardProc(int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information){if(wParam == game.turnUP){if(game.m_direction.y == 0) game.m_direction = UP;}else if(wParam == game.turnDOWN){if(game.m_direction.y == 0) game.m_direction = DOWN;}else if(wParam == game.turnLEFT){if(game.m_direction.x == 0) game.m_direction = LEFT;}else if(wParam == game.turnRIGHT){if(game.m_direction.x == 0) game.m_direction = RIGHT;}else;return 1;}然后介绍一下,点击鼠标右键出现菜单:void CSnakeDlg::OnRButtonDown(UINT nFlags, CPoint point){if(game.m_run)KillTimer(1);CMenu oMenu;if (oMenu.LoadMenu(IDR_MENU1)){CMenu* pPopup = oMenu.GetSubMenu(0);ASSERT(pPopup != NULL);CPoint oPoint;GetCursorPos(&oPoint);SetForegroundWindow();pPopup->TrackPopupMenu(TPM_LEFTALIGN,oPoint.x,oPoint.y,this);}if(game.m_run) SetTimer(1,game.m_gameSpeed,NULL);CDialog::OnRButtonDown(nFlags, point);}然后来介绍一下程序中是怎样来改变按键的,首先说一下,我开始用EDIT控件来让用户输入,但是程序中我用的是键盘“钩子”来处理消息的,所以EDIT控件在程序中是不可以输入信息的,所以我选的是下拉列表,代码如下,解释也在程序中相应给出:int keyNum[40] = {//定义玩家可以设的键,把所有的键信息存在这个数组中VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT, 'A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X', 'Y','Z', VK_NUMPAD0,VK_NUMPAD1,VK_NUMPAD2, VK_NUMPAD3,VK_NUMPAD4,VK_NUMPAD5, VK_NUMPAD6,VK_NUMPAD7,VK_NUMPAD8,VK_NUMPAD9};void CSnakeDlg::OnKeyset()//键盘设置响应消息函数{// TODO:在此添加命令处理程序代码if(game.m_run)KillTimer(1);CKeySetDlg dlg;if(dlg.DoModal() == IDOK){if(dlg.m_up == dlg.m_down || dlg.m_up == dlg.m_left || dlg.m_up == dlg.m_right || dlg.m_down == dlg.m_left || dlg.m_down == dlg.m_right || dlg.m_left == dlg.m_right){MessageBox("键位不能设置为重复的,设置失败!");if(game.m_run) SetTimer(1,game.m_gameSpeed,NULL);return;}game.turnUP = keyNum[GetMarkNum(dlg.m_up)];//重新设置键game.turnDOWN = keyNum[GetMarkNum(dlg.m_down)];game.turnLEFT = keyNum[GetMarkNum(dlg.m_left)];game.turnRIGHT = keyNum[GetMarkNum(dlg.m_right)];}if(game.m_run) SetTimer(1,game.m_gameSpeed,NULL);}int CSnakeDlg::GetMarkNum(CString str)//返回重新设置键对应数组的“索引”{int backNum = 0;if(str == "上")backNum = 0;else if(str == "下")backNum = 1;else if(str == "左")backNum = 2;else if(str == "右")backNum = 3;else{CString ss;for(char i='A'; i<='Z'; ++i){ss.Format("%c",i);if(ss == str.Right(1)){backNum = i - 'A' + 4;return backNum;}}for(int i=0; i<=9; ++i){ss.Format("%d",i);if(ss == str.Right(1)){backNum = i + 30;return backNum;}}}return backNum;}最后写一下程序更换皮肤的一段代码,本来觉得不算很难的,不过还是介绍一下吧,对了我用的是Skinmagic做的皮肤,不过这个软件你可以通过网上的说明进行注册,也可以自己把它破解,其实很简单,大家可以试试:void CSnakeDlg::OnChangSkin(){// TODO:在此添加命令处理程序代码if(game.m_run)KillTimer(1);CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Skin Files(*.smf)|*.smf||",AfxGetMainWnd());CString strPath,strText="";if(dlg.DoModal() == IDOK){strPath = dlg.GetPathName();VERIFY(1 == LoadSkinFile(strPath));}if(game.m_run) SetTimer(1,game.m_gameSpeed,NULL);}还有很多小函数,由于都是比较简单的,就不多写了,程序介绍就到这里,呵呵,希望我能够帮你解决你写程序遇到的问题,如果大家想知道如何做程序的皮肤的话,网上有很多这样的博客,我就是在那样的博客里学到的,如果还是想我来介绍的话,那给我留言说下哦,呵呵,谢了,有问题请在下面留言......。