【Java】【MySnake】仿贪吃蛇小游戏开源代码(持续更新)
宣传视频在这里:https://www.bilibili.com/video/av62633283#reply1843437215
仿贪吃蛇小游戏,可以穿过边缘,吃到蛋可以变色。
这个是暑假学了一个月java做的。java很多知识点太枯燥,很难有学下去的动力,因此决定从一个小项目开始用实例了解知识点,更容易记住,也更容易学习。因此里面的注释有部分是比较乱的,涉及到一些基础知识点…
目前游戏有一些bug,还不知道怎么处理,不过应该不痛不痒。
跟着b站“马士兵”的视频做的,在此表示感谢0.0
将代码开源给大家,仅供学习参考,严禁用于各种商业用途,转载注明出处。
Yard
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class Yard extends Frame {public final static int ROWS = 30; //先定义院子的行和列,设置为常量,变量名大写public final static int COLS = 30;public static final int BLOCK_SIZE = 20; //每个小格的长度public static int flag = 1; //线程开关public static int speed = 50; //fpspublic static int init_size = 30; //蛇的初始长度Image offScreenImage = null; //解决缓冲闪烁问题(刷背景)public void launch() //将程序运行写在一个函数,里面的this是在调用继承的Frame,不用this也可以{this.setLocation(350, 10); //方框位置this.setSize(COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE ); //方框大小setResizable(false); //不可调整大小this.addWindowListener(new WindowAdapter() { //按钮可关闭@Overridepublic void windowClosing(WindowEvent e) {super.windowClosing(e);System.exit(0);}});this.setVisible(true); //可显示new Thread(new PaintThread()).start(); //启动线程this.addKeyListener(new KeyMonitor()); //加入键盘监听事件}Snake s = new Snake(); //生成蛇Egg e = new Egg(); //生成蛋public static void main(String[] args) {new Yard().launch(); //launch为非静态,因此需要创建实例对象Yard访问该方法(因为main是静态方法),此为匿名类}@Overridepublic void update(Graphics g) { //双缓冲if(offScreenImage == null) {offScreenImage = this.createImage(COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);}Graphics gOff = offScreenImage.getGraphics();paint(gOff);g.drawImage(offScreenImage, 0, 0, null);}private class KeyMonitor extends KeyAdapter{@Overridepublic void keyPressed(KeyEvent e) {s.keyPressed(e);}}private class PaintThread implements Runnable{@Overridepublic void run() {while(flag == 1) {repaint();try {Thread.sleep(speed); //每speed毫秒一帧} catch (InterruptedException e) {e.printStackTrace();}}}}public void paint(Graphics g) { //画面板 paint方法不需要调用,只需要重写g.setColor(Color.BLACK); //背景色g.fillRect(0, 0, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE); //填充整个矩形区域g.setColor(Color.RED); //画红线for(int i = 1;i < ROWS;i++) //画出横线{g.drawLine(0, BLOCK_SIZE*i, COLS*BLOCK_SIZE, BLOCK_SIZE*i); }for(int i = 1;i < COLS;i++) //画出竖线{g.drawLine(BLOCK_SIZE*i, 0, BLOCK_SIZE*i, ROWS*BLOCK_SIZE);}s.eat(e); //调用蛇吃蛋函数s.draw(g); //调用画出蛇的函数e.draw(g); //调用画出蛋的函数}
}
Snake
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;//蛇是由头,尾 + n个结点拼接而成,因此蛇的成员变量应该有头结点,尾结点,蛇长度,蛇移动方向。
//结点又作为一个类,是蛇的内部类。结点成员变量有x坐标,y坐标,长度,宽度(表示出结点的位置和大小), 蛇吃蛋后新增结点的方向dir, 结点尾指针(类似于链表).方向有4个,新建一个方向枚举类Dir型表示.
public class Snake {public Node head = null;Node tail = null;int size = 0; //蛇节数Color snake_color;Node color_n = head;private Node n = new Node(20, 20, Dir.L); //初始化Snakepublic Snake(Node node) { //在外部类中可以直接访问内部类,但不能直接访问内部类成员head = node;tail = node;size = 1;}public Snake() { //初始化Snakehead = n;tail = n;head.next = null;tail.next = null;size = 1;for(int i = 1;i <= Yard.init_size;i++) AddToHead(); //设置初始长度}public void AddToTail() { //双向链表实现Node node = null;switch(tail.dir) {case U:node = new Node(tail.row+1, tail.col, tail.dir);break;case D:node = new Node(tail.row-1, tail.col, tail.dir);break;case L:node = new Node(tail.row, tail.col+1, tail.dir);break;case R:node = new Node(tail.row, tail.col-1, tail.dir);break;}tail.next = node;tail = node;size++;}public void AddToHead() { //双向链表实现Node node = null;switch(head.dir) {case D:node = new Node(head.row+1, head.col, head.dir);break;case U:node = new Node(head.row-1, head.col, head.dir);break;case R:node = new Node(head.row, head.col+1, head.dir);break;case L:node = new Node(head.row, head.col-1, head.dir);break;}node.next = head;head.pre = node;head = node;size++;}public void draw(Graphics g) { //画出整条蛇if(size <= 0) return;move();ChangeColor(); //改变蛇的颜色for(Node n = head;n != null;n = n.next) //循环画出结点{n.draw(g, n);}}private void ChangeColor() { //蛇颜色变化int speed = 2; //颜色变化速度调节for(int i = 1;i <= speed;i++){if(color_n == null) return;color_n.node_color = snake_color;color_n = color_n.next;}}private void move() { //蛇移动AddToHead(); //增加头部结点checkEdge(); //检测边缘
// checkDead(); //检测是否死亡deleteFromTail(); //删除尾巴结点}public void checkEgg() { //检测鸡蛋位置是否与蛇冲突
// int limit = 5;
// if(Egg.row - limit<= 0 || Egg.row+ limit >= Yard.ROWS || Egg.col - limit <= 0 && Egg.col+ limit >= Yard.COLS)
// {// System.out.println(1);
// Egg.hush = true;
// return;
// }if(Egg.egg_color == snake_color){Egg.hush = true;return;}for(Node n = head.next;n != null;n = n.next){if(n.row == Egg.row && n.col == Egg.col){Egg.hush = true;return;}}Egg.hush = false;}private void checkDead() { //检验蛇是否死亡for(Node n = head.next;n != null;n = n.next) {if(head.row == n.row && head.col == n.col) {deleteFromHead(); AddToTail();Yard.flag = 0; //停止线程}}}private void checkEdge() { //检验边缘if(head.row > Yard.ROWS) head.row = 0;else if(head.row < 0) head.row = Yard.ROWS;else if(head.col > Yard.COLS-1) head.col = 0;else if(head.col < 0) head.col = Yard.COLS-1;}public void eat(Egg e) { //蛇吃掉鸡蛋if(this.getRect(head).intersects(e.getRect())) { //intersects判断矩形是否重合snake_color = Egg.egg_color;color_n = head;e.reAppear(); //重置鸡蛋位置checkEgg(); //检测鸡蛋位置是否位于蛇身while(Egg.hush){e.reAppear();checkEgg();}AddToHead();}}private Rectangle getRect(Node tmp) { //返回头结点的矩形对象(用于碰撞)return new Rectangle(Yard.BLOCK_SIZE * tmp.col, Yard.BLOCK_SIZE * tmp.row, tmp.w, tmp.h);}private void deleteFromTail() {if(size == 0) return;tail = tail.pre;tail.next = null;}private void deleteFromHead() {if(size == 0) return;head = head.next;}private class Node{int w = Yard.BLOCK_SIZE; //结点宽度int h = Yard.BLOCK_SIZE; //结点高度int row, col; //结点所在位置int fix_shape = 3; //画结点的修补参数,让结点有立体感Color node_color = snake_color;Dir dir = Dir.L; //默认方向Node next = null;Node pre = null;Node(int row, int col, Dir dir) { //结点构造函数(可以用Alt+Shift引用source里面选Constructor生成构造函数)this.row = row;this.col = col;this.dir = dir;}void draw(Graphics g, Node n) { //画出结点g.setColor(node_color);if(n == head){g.drawOval(Yard.BLOCK_SIZE*col, Yard.BLOCK_SIZE*row, w-2, h-2);}else{g.fillRect(Yard.BLOCK_SIZE*col+fix_shape, Yard.BLOCK_SIZE*row+fix_shape, w-2*fix_shape, h-2*fix_shape); //矩形填充结点的x,y坐标和宽度高度}}}public void keyPressed(KeyEvent e) { //响应键盘int key = e.getKeyCode();switch(key) {case KeyEvent.VK_LEFT:if(head.dir != Dir.R) head.dir = Dir.L;break;case KeyEvent.VK_UP:if(head.dir != Dir.D) head.dir = Dir.U;break;case KeyEvent.VK_DOWN:if(head.dir != Dir.U) head.dir = Dir.D;break;case KeyEvent.VK_RIGHT:if(head.dir != Dir.L) head.dir = Dir.R;break;}}
}
Egg
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;public class Egg {public static int row, col;int w = Yard.BLOCK_SIZE; //结点宽度int h = Yard.BLOCK_SIZE; //结点高度int seed = 0; //随机数种子public static Color egg_color;public static boolean hush = false;private static Random r = new Random(); //随机出生点private static Random r1 = new Random();//随机数public Egg(int row, int col, int seed) {this.row = row;this.col = col;this.seed = seed;}public Egg() { //r.nextInt(i)表示(0-i)的随机数, r1随机6个数表示6种颜色this(r.nextInt(Yard.ROWS-5) + 5, r.nextInt(Yard.COLS-5) + 5, r1.nextInt(6)); //产生1~边界-1的随机坐标,去除出生点在边界可能性}public void reAppear() { //Egg重新出现,采用随机坐标int limit = 6; //limit用于限制鸡蛋出现的范围
// this.row = row + r.nextInt(limit) - limit;
// this.col = col + r.nextInt(limit) - limit;Egg.row = r.nextInt(Yard.ROWS-1);Egg.col = r.nextInt(Yard.COLS-1);if(row < limit) row += limit;if(row > Yard.ROWS-limit) row -= limit;if(col < limit) col += limit;if(col > Yard.COLS-limit) col -= limit;this.seed = r1.nextInt(6);switch(seed) //随机颜色{case 0: egg_color = Color.green; break;case 1: egg_color = Color.BLUE;break;case 2: egg_color = Color.MAGENTA;break;case 3: egg_color = Color.ORANGE;break;case 4: egg_color = Color.PINK;break;case 5: egg_color = Color.RED;break;default: break;}}public Rectangle getRect() { //返回头结点的矩形对象(用于碰撞)return new Rectangle(Yard.BLOCK_SIZE * this.col, Yard.BLOCK_SIZE * this.row, this.w, this.h);}void draw(Graphics g) { //画出结点g.setColor(egg_color);g.fillOval(Yard.BLOCK_SIZE*col, Yard.BLOCK_SIZE*row, w, h); //椭圆填充结点的x,y坐标和宽度高度}}
【Java】【MySnake】仿贪吃蛇小游戏开源代码(持续更新)相关推荐
- java 面向对象实现贪吃蛇小游戏
业务逻辑梳理和描述 面向对象设计贪吃蛇 1.找类和对象 a.Snake类 蛇类 b.Food类 食物类 c.Ground类 障碍物类 d.GamePanel 面板类 显示蛇.食物.障碍物. 2.找类的 ...
- 基于面向对象 来写一个简单的贪吃蛇小游戏(代码可直接用)
分析一下用到的对象(这个案例的地图过于简单,可以不用创建为对象) 食物对象(food) 蛇对象(snake) 游戏对象(game) 1.food对象 属性 :x, y, ...
- 贪吃蛇小游戏(代码)
规则: 按任意键暂停, 使用方向键或wasd移动, 长按方向键可加速,方向键继续, 需要吃掉食物, 碰到自身或碰到边界就游戏结束, 速度会越来越快呦, 58.63.68.72行可以换边框,(看注释), ...
- 手把手教你做一个Java贪吃蛇小游戏
大家好,我是孙不坚1208,这篇博客给大家分享一下:如何做一个贪吃蛇小游戏(Java版)的exe应用程序,希望能给需要帮助的朋友带来方便. 手把手教你做一个Java贪吃蛇小游戏的exe应用程序 一.J ...
- Linux编程 --- 贪吃蛇小游戏
如何使用ncurse #include <curses.h>int main() {initscr();//ncurse 界面的初始化函数printw("This is curs ...
- 简易贪吃蛇小游戏java版_用GUI实现java版贪吃蛇小游戏
本文实例为大家分享了java版贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public stat ...
- 用 Java 实现贪吃蛇小游戏
程序说明 这是一个用 Java Awt 实现的贪吃蛇小游戏的完整代码 算法分析 (一)启动一个独立线程根据 direction 重绘面板实现蛇身移动效果,运行过程: 记录上次头部的坐标到 tempBo ...
- 贪吃蛇小游戏java实现代码分析
贪吃蛇小游戏java实现代码分析 贪吃蛇的小游戏,网上的代码比较多,今天周五,在教研室没啥事做,在电脑中发现了一个贪吃蛇的小游戏,于是就看了下实现的源码,发现别人写的代码确实挺好的,自己也是边加注释边 ...
- Java实现贪吃蛇小游戏(附完整源码)
今天我就从零开始来完成这个小游戏,完成的方式也是一步一步的添加功能这样的方式来实现. 第一步完成的功能:写一个界面 大家见到的贪吃蛇小游戏,界面肯定是少不了的.因此,第一步就是写一个小界面. 实现代码 ...
- JAVA版贪吃蛇小游戏
这是一篇关于JAVA的贪吃蛇游戏,源代码的部分在下面正文中介绍,图片和音频的部分都放在百度云盘,需要的自行下载. 文章目录 开发环境 一.下载方法 二.运行效果展示 三.项目结构以及主程序入口 1.项 ...
最新文章
- 编写单元测试代码遵守BCDE原则,以保证被测试模块的交付质量,那么下列说法正确的是
- DevExpress —— dxDataGrid
- HDU(1856),裸的带权并查集
- matlab求adc信号的信噪比,关于ADC的信噪比 - pengyouxiaohui的日志 - EETOP 创芯网论坛 (原名:电子顶级开发网) -...
- java jdbc连接oracle_Java使用JDBC连接Oracle 11gR2
- c++多态相关面试题
- php empty ,is_null ,isSet 对比
- 解读WPF中的Xaml
- Alex: 2018年对混合现实MR的展望
- java mvc数据库 封装_关于SpringMvc参数封装_JavaEE框架(Maven+SpringMvc+Spring+MyBatis)全程实战教程_Java视频-51CTO学院...
- Vue深入学习4—指令和生命周期
- 绑定MAC地址 局域网防arp ARP病毒
- POJ NOI MATH-7654 等差数列末项计算
- python连接数据库--查询数据
- SQL Server AlwaysOn配置两个节点加共享文件夹仲裁见证
- vbs中使用select case条件语句,case中匹配项多于一个时,提示:type mismathc/ 800A000D...
- NV16 转 NV12
- FMEA-MSR步骤五:风险分析(三)
- 看完此篇文章可以快速熟悉Spring事务
- 从小学4年级的数学课开始解释线性回归