Java实现贪吃蛇游戏

最近JAVA和JSwing上手练习了一下贪吃蛇,供大家参考,具体内容如下

欢迎交流和加入新的内容

用到了JSwing,下面是一些具体的思路

实现

 * 蛇:

采用单链表记录首尾,整个蛇被分为lattice格子,放在map里

 * 移动:

我在实现的过程中发现最难得反而是蛇的定义和实现。一直想着怎么样用单独的方法表示出蛇来,但是如果将蛇单独实现,总有些细节实现起来特别麻烦

其实蛇移动并非牵一发而动全身,其实身子是没有发生变化的,关键是两点:

a.头的移动
b.尾巴的移动

实现:

直接把蛇实现在地图的小格子里,不再单独设置子类或者ArrayList等,Map里加上蛇头的坐标,从而使得Map可以根据蛇头改变蛇的坐标(类似于变量交换)。为头部单独设置x,y,作为移动的方向(也可以作为静态变量x和y,不过没什么区别),为身子设置next指针,只要next.next不是尾巴,那么保持不变。如果next是尾巴,就把自己的设置为尾巴,并且改变next,使之成为普通地图块。(refresh方法)

 * 控制方向:

使用键盘事件,目前仅设置了wasd四个

 * 窗口设计:

view extends JPanel,控制显示,然后在Lattice里调用Graphics.draw(...)实现对每个格子的显示

下面是核心的map部分代码(包括自动移动,检测食物,增加长度等等)

import codes.myGame.snake.cell.Lattice;

import java.util.Random;

public class Smap {
 private boolean getFood = false;//如果得到食物,该指针设为true,并且在随后的autoChange里增加蛇的长度
 private boolean gameOver = false;
 private boolean directionChange = false;//这里标志的作用是保证在一次运动期间只会进行一次转向,使游戏更流畅
 private int MAP_SIZE;
 private Lattice[][] map;
 private int directionX = 0;//下一次头在当前位置的哪个方向上
 private int directionY = 1;//下一次头在当前位置的哪个方向上
 private int[] head = new int[2];//记录当前头的位置
 private int[] food = new int[2];//记录当前食物的位置

 public Smap(int size) {
 MAP_SIZE = size;
 map = new Lattice[MAP_SIZE][MAP_SIZE];
 for(int i=0;i<size;i++){
 for (int j = 0 ;j<size;j++){
 map[i][j] = new Lattice();
 }
 }
 map[MAP_SIZE/2][MAP_SIZE/2].setHead(true,map[MAP_SIZE/2][MAP_SIZE/2-1]);//初始化设置一个头结点,以及他的尾节点
 head[0] = MAP_SIZE/2;
 head[1] = MAP_SIZE/2;
 map[MAP_SIZE/2][MAP_SIZE/2-1].setRear(true,null);
 this.randFood();
 }

 //模拟蛇的自动移动
 public void autoChange(){
 this.setHead();
 if(food[0]==head[0] && food[1]==head[1]){//如果新的头部碰触到了食物,那么尾部增长
 getFood = true;
 }
 if(!gameOver)this.setRear();
 if(getFood)this.randFood();
 directionChange = false;
 }

 //根据键盘事件,改变头的下一次移动方向,注意 该移动方向是仅针对头部的
 //setDirection和setHead两个方法需要互斥进行,这里单线程,用synchronized即可
 //(否则,如果当前头部在边界位置,连续变幻方向可能导致在setHead里发生溢出)
 public synchronized void setDirection(int x,int y){
 if(directionY!=y && directionX!=x &&!directionChange){
 directionX = x;
 directionY = y;
 directionChange = true;
 }
 }

 public boolean gameOver(){
 return gameOver;//头碰到身子,证明gameOver
 }
 private synchronized void setHead(){
 int i = head[0];
 int j = head[1];
 head[0] = ( head[0] + directionX + MAP_SIZE)%MAP_SIZE;
 head[1] = ( head[1] + directionY + MAP_SIZE )%MAP_SIZE;
 if(map[head[0]][head[1]].isBody())gameOver = true;
 map[head[0]][head[1]].setHead(true,map[i][j]);
 map[i][j].setBody(true,null);
 map[i][j].setHead(false,null); //传入null表示不改变当前指向
 }

 //设置尾巴由于没法像头部那样直接设置,这里只能采用链表遍历的方式获取尾巴
 private void setRear(){
 if(!getFood){
 Lattice temp = map[head[0]][head[1]];
 while (!temp.next.isRear())temp = temp.next;
 temp.next().setRear(false,null);
 temp.setRear(true,null);
 temp.setBody(false,null);
 }
 }

 private void randFood(){
 getFood = false;
 map[food[0]][food[1]].setFood(false);//先把当前的食物取消掉
 boolean flag = false;//设置下一个食物
 Random random = new Random();
 int x = random.nextInt(MAP_SIZE);
 int y = random.nextInt(MAP_SIZE);
 while (!flag){
 x = random.nextInt(MAP_SIZE);
 y = random.nextInt(MAP_SIZE);
 if(!map[x][y].isHead() && !map[x][y].isRear() &&!map[x][y].isBody())flag = true;
 }
 map[x][y].setFood(true);
 food[0] = x;
 food[1] = y;
 }

 public Lattice get(int row, int col){
 return map[row][col];
 }

 public int getMAP_SIZE() {
 return MAP_SIZE;
 }
}

下面是显示部分的代码

显示分为两部分,一块是利用Graphics.draw()方法实现单个单元格的绘制,另一块设置view类继承自JPanel。负责绘制图画显示

public class Lattice {
 private boolean isBody = false;
 private boolean isHead = false;
 private boolean isFood = false;
 private boolean isRear = false;
 public Lattice next = null;

 public void setHead(boolean bool,Lattice next){
 isHead = bool;
 if(next!=null)this.next = next;
 }
 public void setBody(boolean bool,Lattice next){
 isBody = bool;
 if(next!=null)this.next = next; //传入参数为null时,不改变当前的next
 }
 public void setRear(boolean bool,Lattice next){
 isRear = bool;
 this.next = next;
 }
 public void setFood(boolean bool){
 isFood = bool;
 }

 public Lattice next(){
 return next;
 }

 public boolean isHead(){
 return isHead;
 }
 public boolean isFood(){
 return isFood;
 }
 public boolean isRear(){
 return isRear;
 }
 public boolean isBody(){
 return isBody;
 }

 public void refresh(){
 if(isHead){
 isBody = true;
 isHead = false;
// 怎么设置下一个头呢?(考虑把DirectionX,Y放到Smap里,而不是这里)
 }else if(isBody){
 if(next.isRear){
 next.isRear = false;
 isRear = true;
 isBody = false;
 }
 }
 }
// 在这里设置细胞可见
 public void draw(Graphics g, int x, int y, int size) {
 g.setColor(black);
 g.drawRect(x, y, size, size);
 if ( isHead ) {
 g.setColor( red);
 g.fillRect(x, y, size, size);
 }else if ( isBody || isRear) {
 g.setColor(black);
 g.fillRect(x, y, size, size);
 }else if(isFood){
 g.setColor( blue);
 g.fillRect(x, y, size, size);
 }
 }
}

view部分:

import codes.myGame.snake.cell.Lattice;
import javax.swing.*;
import java.awt.*;

public class View extends JPanel {
 private static final long serialVersionUID = -5258995676212660595L;
 private static final int GRID_SIZE = 32; //填充的像素数量
 private Smap thisMap;

 public View(Smap map) {
 thisMap = map;
 }

 @Override
 public void paint(Graphics g) {
 super.paint(g);
 int size = thisMap.getMAP_SIZE();
 for (int row = 0; row< size; row++ ) {
 for (int col = 0; col< size; col++ ) {
 Lattice lattice = thisMap.get(row, col);
 if ( lattice != null ) {
 lattice.draw(g, col*GRID_SIZE, row*GRID_SIZE, GRID_SIZE);//对应的格子的显示
 }
 }
 }
 }
 @Override
 public Dimension getPreferredSize() {//创建该div大小
 return new Dimension(thisMap.getMAP_SIZE()*GRID_SIZE+1, thisMap.getMAP_SIZE()*GRID_SIZE+1);
 }
}

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

javascript经典小游戏汇总

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java贪吃蛇游戏编写代码

    本文实例为大家分享了java贪吃蛇游戏展示的具体代码,供大家参考,具体内容如下 1.采用MVC(model.view.control)框架模式 2.包和类的关系树形图为: 3.源码: package com.huai; import Java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.HashSet; import java.util.LinkedList; import java.u

  • java实现贪吃蛇小游戏

    本文实例为大家分享了java实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 这是MVC模式的完整Java项目,编译运行SnakeApp.java即可开始游戏. 可扩展功能: 1.积分功能:可以创建得分规则的类(模型类的一部分), 在GameController的run()方法中计算得分 2.变速功能:比如加速功能,减速功能,可以在GameController的keyPressed()方法中针对特定的按键设置每一次移动之间的时间间隔,将Thread.sleep(Settings.DEFAUL

  • Java实现贪吃蛇游戏(1小时学会)

    今天就来拿贪吃蛇小游戏来练练手吧! 贪吃蛇游戏规则: 1.按下空格键(游戏未结束)则游戏暂停或开始: 2.按下空格键(游戏结束后)则游戏重新开始: 3.当贪吃蛇的头部撞到身体时则贪吃蛇死亡(游戏结束): 4.当贪吃蛇的头部撞到墙时贪吃蛇死亡(游戏结束): 游戏界面效果: 我们可以看到自己的贪吃蛇吃了多少食物,以及游戏得分.下面是游戏效果图: 源码(注释超详细,注意ImageDate类中的material是一个包名,里面存放的是游戏素材图片): package program_code; impo

  • Java贪吃蛇游戏完善版

    很认真的写的一个java版的贪吃蛇游戏,图形界面,支持菜单操作,键盘监听,可加速,减速,统计得分,设定运动速度,设定游戏背景颜色等!应该没有Bug了,因为全被我修改没了. 下面是项目各包及类的层次关系: 游戏的主要运行界面截图如下: 下面是部分代码,详细源码见此链接:贪吃蛇源码下载 Snake类: package com.huowolf.entities; import java.awt.Color; import java.awt.Graphics; import java.awt.Point

  • Java swing框架实现的贪吃蛇游戏完整示例

    本文实例讲述了Java swing框架实现的贪吃蛇游戏.分享给大家供大家参考,具体如下: java是门高级语言,做游戏时适合做后台,但是用它也可以做游戏.闲来无事做的时候可以用来写点小游戏,练习练习预防早衰哈哈! 闲话不说了 下面是以前练习的作品,不怕大家笑话,那个时候用了一个礼拜才做出来的. 源码如下供大家学习. 使用的是java的 swing  Jframe Jpanel JButton   当然你也可以使用awt 先来看看运行效果: 具体代码: package Tcs; /** * * *

  • java编写简易贪吃蛇游戏

    本文实例为大家分享了java编写的贪吃蛇源码,供大家参考,具体内容如下 程序共包含以下两个文件: 文件:ShellWin.java import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.event.*; import javax.swing.Box; import javax.swing.JButton; imp

  • 用GUI实现java版贪吃蛇小游戏

    本文实例为大家分享了java版贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public static void main(String[] args) { JFrame jFrame = new JFrame(); jFrame.setBounds(100,100,900,720); jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON

  • Java GUI编程之贪吃蛇游戏简单实现方法【附demo源码下载】

    本文实例讲述了Java GUI编程之贪吃蛇游戏简单实现方法.分享给大家供大家参考,具体如下: 例子简单,界面简陋 请见谅 项目结构如下 Constant.jvava 代码如下: package snake; /** * * @author hjn * */ public class Constant { /** * 蛇方移动方向:左边 */ public static final int LEFT = 0; /** * 蛇方移动方向:右边 */ public static final int R

  • java贪吃蛇极速版

    本文为大家推荐了一款由java实现经典小游戏:贪吃蛇,相信大家都玩过,如何实现的呐? 效果图: 废话不多说,直接奉上代码: 1. public class GreedSnake { public static void main(String[] args) { SnakeModel model = new SnakeModel(20,30); SnakeControl control = new SnakeControl(model); SnakeView view = new SnakeVi

  • java编写贪吃蛇小游戏

    废话不多说,直接奉上代码: Frame.java package snake; import java.awt.Graphics; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import

随机推荐