双人版的贪吃蛇

来源:互联网 发布:js获取ip和端口号 编辑:程序博客网 时间:2024/04/30 12:30

难道我只会做贪吃蛇了?!

好吧我这里说明一下 贪吃蛇是最容易实现的游戏之一,初学者实现起来很容易。还可以复习链表的知识。

其实在练习时,重要的不是学习别人的逻辑结构 是学习别人的写法

逻辑算法这个东西要自己去想,才能深刻理解

不过废话了,简要说一下这个双人版贪吃蛇的规则

1.两条蛇抢一个苹果 没吃一个苹果得10分

2.两条蛇可以互相咬断对方,分数会加上咬断的节数*10,被咬的不扣分

3.两个蛇头撞在一起或者苹果投放大于20个的时候游戏结束

4.谁的分数高谁就胜利

5.这个规则不是我想出来的 好像还有问题,请指教

/* * 贪吃蛇 * 2011/10/05 * LSN */package com.lsn.Snake;/** * JDK 1.6 Eclipse 3.6编译通过 * 操作方法:1.上下左右 移动蛇头  * 2. 回车暂停恢复游戏 *  * 待解决问题 :程序以applet方式运行时 不能自动设置焦点到applet */import java.awt.Color;import java.awt.Event;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Iterator;import java.util.LinkedList;import javax.imageio.ImageIO;import javax.swing.JApplet;import javax.swing.JFrame;import javax.swing.JOptionPane;public class SnakeDouble extends JApplet implements Runnable, KeyListener {// 方向常量private static final int[] DIR_UP = { 0, -1 };private static final int[] DIR_DOWN = { 0, 1 };private static final int[] DIR_LEFT = { -1, 0 };private static final int[] DIR_RIGHT = { 1, 0 };// 屏幕的宽度和高度private static final int XBC = 31;private static final int YBC = 31;private static final int SCR_W = 16 * XBC + 32;private static final int SCR_H = 16 * YBC + 32;// 游戏运行状态private static final int GS_RUNNING = 1;private static final int GS_PAUSED = -1;class Snake {LinkedList<int[]> snake = new LinkedList<int[]>(); // 蛇体 用链表来存// 蛇头位置和运动方向int snakeHeadPositionX;int snakeHeadPositionY;int[] snakeHeading;int score = 0;}private Snake[] sn = new Snake[2];private BufferedImage ofs; // 图像缓冲 Off Screen Bufferprivate Image bg;// 果子的位置private int appleX;private int appleY;private boolean gameOver = false; // 游戏结束的标志private int hiscore = 0; // 最高得分private int gameStatus =GS_PAUSED; // 游戏状态private int appleCnt=0;@Overridepublic void init() {for (int j = 0; j <= 1; j++) {// 初始化 蛇sn[j] = new Snake();for (int i = 0; i < 4; i++) {sn[j].snake.addFirst(DIR_UP);}// 初始化蛇头sn[j].snakeHeading = DIR_UP;sn[j].snakeHeadPositionY = YBC / 2;}sn[0].snakeHeadPositionX = XBC / 2 - 3;sn[1].snakeHeadPositionX = XBC / 2 + 3;// 初始化游戏状态gameOver = false;ofs = new BufferedImage(SCR_W, SCR_H, BufferedImage.TYPE_4BYTE_ABGR);//背景try {bg=ImageIO.read((getClass().getResourceAsStream("/BG.png")));} catch (IOException e) {e.printStackTrace();}// 随机产生一个果子O(∩_∩)O~randomApple();}// 随机产生果子private void randomApple() {appleX = (int) (Math.random() * XBC);appleY = (int) (Math.random() * YBC);for (int j = 0; j <= 1; j++) {if (appleX == sn[j].snakeHeadPositionX&& appleY == sn[j].snakeHeadPositionY)randomApple();if (onSnake(appleX, appleY, sn[j]) != 0)randomApple();}if (appleX == 0 || appleY == 0 || appleX == XBC + 1|| appleY == YBC + 1)randomApple();appleCnt++;if(appleCnt==20) gameOver=true;}// 判断指定坐标是否在蛇身上private int onSnake(int x, int y, Snake s) {Iterator<int[]> it = s.snake.iterator();int sx = s.snakeHeadPositionX;int sy = s.snakeHeadPositionY;int sc = 0;while (it.hasNext()) {sc++;int[] d = it.next();sx += d[0] * -1;sy += d[1] * -1;if (x == sx && y == sy)return sc;}return 0;}// 构造方法中加入键盘监听器设置焦点public SnakeDouble() {addKeyListener(this);this.requestFocus();}@Overridepublic void start() {new Thread(this).start();}// 主线程@Overridepublic void run() {while (true) {while (!gameOver) {if (gameStatus == SnakeDouble.GS_RUNNING) {// 判断游戏是否运行中gameProcess();}this.repaint();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}// 游戏结束处理JOptionPane.showMessageDialog(this, "游戏结束\n蓝色得分:" + sn[0].score+ "\n绿色得分:" + sn[1].score + "\n最高得分:" + hiscore, "贪吃蛇",JOptionPane.INFORMATION_MESSAGE);this.init();}}// 游戏主处理private void gameProcess() {for (int j = 0; j <= 1; j++) {// 修正:蛇头运动和蛇运动不能分开// 蛇头运动sn[j].snakeHeadPositionX += sn[j].snakeHeading[0];sn[j].snakeHeadPositionY += sn[j].snakeHeading[1];// 蛇运动sn[j].snake.addFirst(sn[j].snakeHeading);sn[j].snake.removeLast();// 检查蛇头check(sn[j]);}int k = onSnake(sn[0].snakeHeadPositionX, sn[0].snakeHeadPositionY,sn[1]);if (k != 0) {eatSnake(sn[1], k);sn[0].score += (sn[1].snake.size() - k) * 10;}k = onSnake(sn[1].snakeHeadPositionX, sn[1].snakeHeadPositionY, sn[0]);if (k != 0) {eatSnake(sn[0], k);sn[1].score += (sn[0].snake.size() - k) * 10;}if (sn[0].snakeHeadPositionX == sn[1].snakeHeadPositionX&& sn[0].snakeHeadPositionY == sn[1].snakeHeadPositionY) {gameOver=true;}}private void eatSnake(Snake snake, int k) {for (int i = 0; i < snake.snake.size() - k; i++) {snake.snake.removeLast();}}// 检查蛇头private void check(Snake s) {int x = s.snakeHeadPositionX;int y = s.snakeHeadPositionY;if (x == 0 || y == 0 || x == XBC + 1 || y == YBC + 1|| onSnake(x, y, s) != 0) {gameOver = true;}if (appleX == x && appleY == y) {s.score += 10;if (hiscore < s.score) {hiscore = s.score;}s.snake.addFirst(s.snakeHeading);randomApple();}}// 绘制图形@Overridepublic void update(Graphics g) {paint(g);}@Overridepublic void paint(Graphics g) {drawMap(ofs);g.drawImage(ofs, 0, 0, this);}private void drawMap(BufferedImage ofs2) {Graphics2D pen = ofs2.createGraphics();pen.setColor(Color.green);pen.clearRect(0, 0, SCR_W, SCR_H);pen.drawImage(bg, 64, 64, this);pen.setColor(Color.LIGHT_GRAY);for (int i = 0; i < XBC + 2; i++) {pen.fillRoundRect(i * 16, 0, 13, 13, 3, 3);pen.fillRoundRect(i * 16, SCR_H - 16, 13, 13, 3, 3);pen.fillRoundRect(0, i * 16, 13, 13, 3, 3);pen.fillRoundRect(SCR_W - 16, i * 16, 13, 13, 3, 3);}for (int j = 0; j <= 1; j++) {Iterator<int[]> it = sn[j].snake.iterator();// 画蛇头pen.setColor(Color.red);pen.fillRoundRect(sn[j].snakeHeadPositionX * 16,sn[j].snakeHeadPositionY * 16, 13, 13, 3, 3);int dx = sn[j].snakeHeadPositionX;int dy = sn[j].snakeHeadPositionY;// 画蛇身if (j == 1) {pen.setColor(Color.green);} else {pen.setColor(Color.blue);}while (it.hasNext()) {int[] d = it.next();dx += d[0] * -1;dy += d[1] * -1;pen.fillRoundRect(dx * 16, dy * 16, 13, 13, 3, 3);}}// 画苹果pen.setColor(Color.orange);pen.fillRoundRect(appleX * 16, appleY * 16, 13, 13, 3, 3);if(gameStatus==GS_PAUSED){pen.setColor(Color.pink);pen.setFont(new Font("黑体",0, 30));pen.drawString("游戏暂停,按任意键开始", 100,279);}}@Overridepublic void keyTyped(KeyEvent e) {}// 处理键盘事件@Overridepublic void keyPressed(KeyEvent e) {Snake n = sn[0];Snake s = sn[1];switch (e.getKeyCode()) {case KeyEvent.VK_UP:if (s.snakeHeading == DIR_UP || s.snakeHeading == DIR_DOWN) {break;} else {s.snakeHeading = DIR_UP;}break;case KeyEvent.VK_DOWN:s.snakeHeading = s.snake.getFirst();if (s.snakeHeading == DIR_UP || s.snakeHeading == DIR_DOWN) {break;} else {s.snakeHeading = DIR_DOWN;}break;case KeyEvent.VK_LEFT:s.snakeHeading = s.snake.getFirst();if (s.snakeHeading == DIR_LEFT || s.snakeHeading == DIR_RIGHT) {break;} else {s.snakeHeading = DIR_LEFT;}break;case KeyEvent.VK_RIGHT:s.snakeHeading = s.snake.getFirst();if (s.snakeHeading == DIR_LEFT || s.snakeHeading == DIR_RIGHT) {break;} else {s.snakeHeading = DIR_RIGHT;}break;case KeyEvent.VK_W:if (n.snakeHeading == DIR_UP || n.snakeHeading == DIR_DOWN) {break;} else {n.snakeHeading = DIR_UP;}break;case KeyEvent.VK_S:n.snakeHeading = n.snake.getFirst();if (n.snakeHeading == DIR_UP || n.snakeHeading == DIR_DOWN) {break;} else {n.snakeHeading = DIR_DOWN;}break;case KeyEvent.VK_A:n.snakeHeading = n.snake.getFirst();if (n.snakeHeading == DIR_LEFT || n.snakeHeading == DIR_RIGHT) {break;} else {n.snakeHeading = DIR_LEFT;}break;case KeyEvent.VK_D:n.snakeHeading = n.snake.getFirst();if (n.snakeHeading == DIR_LEFT || n.snakeHeading == DIR_RIGHT) {break;} else {n.snakeHeading = DIR_RIGHT;}break;case KeyEvent.VK_ESCAPE:System.exit(0);break;case KeyEvent.VK_ENTER:gameStatus = -gameStatus;break;}}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub}// 主方法 处理application方式运行public static void main(String[] args) {new JFrame("贪吃蛇双人版") {private void init() {this.setBounds(100, 100, SCR_W + 5, SCR_H + 25);SnakeDouble game = new SnakeDouble();game.init();game.start();this.add("Center", game);this.setVisible(true);game.requestFocus();}protected void processEvent(java.awt.AWTEvent e) {if (e.getID() == Event.WINDOW_DESTROY) {System.exit(0);}}}.init();}}



原创粉丝点击