贪吃蛇游戏:是一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。

package game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList; import javax.swing.*; public class Snake extends JFrame
{ //食物
private Point point=new Point();
//蛇
private LinkedList<Point> list=new LinkedList<Point>(); private int key =37;
//为食物和蛇的坐标进行初始化
public void init() {
//默认食物输出化的位置
point.setLocation(100, 100);
list.add(new Point(300,300));
list.add(new Point(310,300));
list.add(new Point(320,300));
list.add(new Point(330,300));
list.add(new Point(340,300));
list.add(new Point(350,300));
list.add(new Point(360,300));
//开始启用这个线程
new Thread(new MoveThread()).start();
} public void paint(Graphics g) { Image img=createImage(500,500);
//用Graphics画笔类创建一个画笔来画出这个白布
Graphics g2=img.getGraphics();
//把游戏背景填充成白色
g2.setColor(Color.WHITE);
//设置填充范围
g2.fillRect(0, 0, 500, 500);
//把画笔移动到的位置
g2.translate(50, 50);
//设置边框为红色(边框内为蛇能活动的范围)
g2.setColor(Color.RED);
g2.drawRect(0,0,400,400); //下面实现小蛇
g2.setColor(Color.GREEN);
//蛇 获取List中的每一个点
for(int i=0;i<list.size();i++) {
//下面来得到蛇的那些小点,后面两个参数是表示小方框的大小
//能在指定的位置画出蛇的位置
g2.fillRect(list.get(i).x,list.get(i).y, 10, 10);
} //画食物
g2.setColor(Color.RED);
g2.fillRect(point.x, point.y, 10, 10); g.drawImage(img, 0, 0, 500, 500, this);
} public Snake() {
//给游戏外边框添加标题(this就表示当前对象)
this.setTitle("贪吃蛇");
//不能改变边框的大小
this.setResizable(false);
//设施边框的大小
this.setSize(500, 500);
//居中显示
this.setLocationRelativeTo(null);
//当点击关闭时候程序停止
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置可见
this.setVisible(true);
this.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
//键盘的上下左右
if(e.getKeyCode()>=37&&e.getKeyCode()<=40) {
if(Math.abs(key-e.getKeyCode())!=2) {
key=e.getKeyCode();
}
}
}
});
this.init();
} //内部类 实现线程
//写内部类是因为用线程的时候都都需要获取点的值来改变点的属性
class MoveThread implements Runnable{
@Override
public void run()
{
// TODO Auto-generated method stub
while(true) {
try {
Thread.sleep(150);
}catch(InterruptedException e) {
e.printStackTrace();
}
//获取蛇的第一个点
Point p=list.getFirst().getLocation();
switch(key) {//37表示前行
case 37:
p.x=p.x-10;
break;
case 38:
p.y=p.y-10;
break;
case 39:
p.x=p.x+10;
break;
case 40:
p.y=p.y+10;
break; }
//判断游戏结束的两种方法
//1.蛇超出了边界 2.蛇头碰到蛇的身体
if(p.x<0||p.x>390||p.y<0||p.y>390||list.contains(p)) {//在上面的时候点就已经定位到50,50
JOptionPane.showMessageDialog(null, "游戏结束");
break;
}
list.addFirst(p);
//当蛇吃掉食物后 马上生成新的食物 自身变长
if(p.equals(point)) {
int x=(int)(Math.random()*40)*10;
int y=(int)(Math.random()*40)*10;
point.setLocation(x, y);
}else {
//删除最后一个点
list.removeLast();
}
//调用画的方法
Snake.this.repaint();
}
} }
public static void main(String[] args)
{
// TODO Auto-generated method stub
new Snake();
} }

Snake.class

一、首先给蛇添加一个界面

二、对蛇和食物的初始化

三、实现判断游戏结束的方法以及键盘对蛇的运动

 实现过程:

一、首先给蛇添加一个界面

    public Snake() {
//给游戏外边框添加标题(this就表示当前对象)
this.setTitle("贪吃蛇");
//不能改变边框的大小
this.setResizable(false);
//设施边框的大小
this.setSize(500, 500);
//居中显示
this.setLocationRelativeTo(null);
//当点击关闭时候程序停止
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置可见
this.setVisible(true);
}

把这些放到Snake构造函数里面的好处:可以在创建这个对象的自动调用这个里面的代码

下面来设置游戏背景和贪吃蛇在红线里面能活动的范围

(Graphics是Java Gui里面的一个画笔类)

public void paint(Graphics g) {

        Image img=createImage(500,500);
//用Graphics画笔类创建一个画笔来画出这个白布
Graphics g2=img.getGraphics();
//把游戏背景填充成白色
g2.setColor(Color.WHITE);
//设置填充范围
g2.fillRect(0, 0, 500, 500);
//把画笔移动到的位置
g2.translate(50, 50);
//设置边框为红色(边框内为蛇能活动的范围)
g2.setColor(Color.RED);
g2.drawRect(0,0,400,400); }

贪吃蛇的食物可以一个红色的小方块来实现,这个食物目前是固定的,下面会实现食物的随机生成

        g2.setColor(Color.RED);
g2.fillRect(100, 100, 10, 10);

运行Eclipse可以看到

二、对蛇和食物的初始化

为了可以让蛇不断的向四周移动,我们用多个小正方形来组成,而用LinkList正好可以来组成贪吃蛇,而食物就比较简单,用一个随机生成红点就可以用来表示食物的生成

游戏开始的时候蛇本身就已经存在,所以在游戏开始的时候蛇和食物就已经产生了

蛇:

public class Snake extends    JFrame
{ //食物
private Point point=new Point();
//蛇
private LinkedList<Point> list=new LinkedList<Point>(); //为食物和蛇的坐标进行初始化
public void init() {
//默认食物输出化的位置
point.setLocation(100, 100);
list.add(new Point(300,300));
list.add(new Point(310,300));
list.add(new Point(320,300));
list.add(new Point(330,300));
list.add(new Point(340,300));
list.add(new Point(350,300));
list.add(new Point(360,300));
new Thread(new MoveThread()).start();
} for(int i=0;i<list.size();i++) {
//下面来得到蛇的那些小点,后面两个参数是表示小方框的大小
//能在指定的位置画出蛇的位置
g2.fillRect(list.get(i).x,list.get(i).y, 10, 10);
}

食物:

先前上面食物点是写死了的,游戏中的食物是需要随机生成的,而我们知道了实际上这个食物的点是point,所以上面画食物的代码就可以改为

        g2.setColor(Color.RED);
g2.fillRect(point.x, point.y, 10, 10);

红点的随机生成可以用到Math中的random方法

    int x=(int)(Math.random()*40)*10;
int y=(int)(Math.random()*40)*10;
point.setLocation(x, y);

接下来就是在构造函数中调用这个Init()初始化方法

public Snake() {
//给游戏外边框添加标题(this就表示当前对象)
this.setTitle("贪吃蛇");
//不能改变边框的大小
this.setResizable(false);
//设施边框的大小
this.setSize(500, 500);
//居中显示
this.setLocationRelativeTo(null);
//当点击关闭时候程序停止
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置可见
this.setVisible(true);
//调用init
this.init();
}

运行Eclipse可以看到

上面游戏的初始化就完成了,目前游戏是静止不动的,接下来我们要用上下左右四个按键来让蛇移动起来,一开始我们让蛇不断的想左移动,直到我们按下键盘上下左右才让蛇改变移动的方向,蛇移动的时候原理也很简单,可以不断的让右边的点去掉,然后让左边生成一个新的点,这时候我们就可以用到线程,用线程的好处:贪吃蛇游戏一直在往前动,我们可以通过死循环,用线程一直让贪吃蛇进行移动,我们在这里是实现一个接口,在里面重写它的Run方法,start方法已经封装好了,这个线程是一个死循环,只要游戏没有Over,线程是不断运行的

//内部类 实现线程
//写内部类是因为用线程的时候都都需要获取点的值来改变点的属性
class MoveThread implements Runnable{
@Override
public void run()
{
// TODO Auto-generated method stub
while(true) {
try {
Thread.sleep(150); //每隔150毫秒对线程实行一次监控
}catch(InterruptedException e) {
e.printStackTrace();
}
//获取蛇的第一个点
Point p=list.getFirst().getLocation();
switch(37) {//37在ASCII中表示左的意思
case 37:
p.x=p.x-10;
break; }
list.addFirst(p); //删除最后一个点
list.removeLast(); //调用画的方法
Snake.this.repaint();
}
}

内部类实现的好处:因为在线程里面还得不断用到上面的属性,我们得改变这些点的值,如果在外面写的话还要不断去写方法得到这些点的值

在初始化小蛇的时候开启这个线程,执行线程里面的内容

public void init() {
//默认食物输出化的位置
point.setLocation(100, 100);
list.add(new Point(300,300));
list.add(new Point(310,300));
list.add(new Point(320,300));
list.add(new Point(330,300));
list.add(new Point(340,300));
list.add(new Point(350,300));
list.add(new Point(360,300));
//开始启用这个线程
new Thread(new MoveThread()).start();
}

这时候蛇就一直向左动起来了,注意这里没有实现当蛇吃掉食物变长的方法,也没有判断蛇能移动范围,这时候运行Eclipse可以看到程序运行如下

三、实现判断游戏结束的方法以及键盘对蛇的运动

(list.contains(o),系统会对list中的每个元素e调用o.equals(e),方法,加入list中有n个元素,那么会调用n次o.equals(e),只要有一次o.equals(e)返回了true,那么list.contains(o)返回true,否则返回false。)

//判断游戏结束的两种方法
//1.蛇超出了边界 2.蛇头碰到蛇的身体
if(p.x<0||p.x>390||p.y<0||p.y>390||list.contains(p)) {//在上面的时候点就已经定位到50,50
JOptionPane.showMessageDialog(null, "游戏结束");
break;
}

在判断游戏结束下面实现游戏的一些基本逻辑

    list.addFirst(p);
//当蛇吃掉食物后 马上生成新的食物 自身变长
if(p.equals(point)) {
int x=(int)(Math.random()*40)*10;
int y=(int)(Math.random()*40)*10;
point.setLocation(x, y);
}else {
//删除最后一个点
list.removeLast();
}
//调用画的方法
Snake.this.repaint();

接下来是要实现用上下左右来控制蛇的移动,这里就需要用线程不断的去监听

定义一个变量key

private int key =37;

下面就是实现蛇的监听

public Snake() {
//给游戏外边框添加标题(this就表示当前对象)
this.setTitle("贪吃蛇");
//不能改变边框的大小
this.setResizable(false);
//设施边框的大小
this.setSize(500, 500);
//居中显示
this.setLocationRelativeTo(null);
//当点击关闭时候程序停止
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置可见
this.setVisible(true);
this.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
//键盘的上下左右
if(e.getKeyCode()>=37&&e.getKeyCode()<=40) {
if(Math.abs(key-e.getKeyCode())!=2) {
key=e.getKeyCode();
}
}
}
});
this.init();
}

重写在线程中run方法实现的逻辑:

public void run()
{
// TODO Auto-generated method stub
while(true) {
try {
Thread.sleep(150);
}catch(InterruptedException e) {
e.printStackTrace();
}
//获取蛇的第一个点
Point p=list.getFirst().getLocation();
switch(key) {//37表示前行
case 37:
p.x=p.x-10;
break;
case 38:
p.y=p.y-10;
break;
case 39:
p.x=p.x+10;
break;
case 40:
p.y=p.y+10;
break; }

这时候在主函数中创建这个蛇就可以运行游戏:

public static void main(String[] args)
{
// TODO Auto-generated method stub
new Snake();
}

运行结果如下:

这个游戏还有很多没有完善的,比如计分板,排行榜,暂停按键,背景音乐,随机生成的食物会不会出现在蛇的身体上等等,嗯这里就当分享学习啦O(∩_∩)O哈哈~

Java_GUI小游戏--贪吃蛇的更多相关文章

  1. 第一个windows 小游戏 贪吃蛇

    最近用dx尝试做了一个小的贪吃蛇游戏,代码放到github上面:https://github.com/nightwolf-chen/MyFreakout 说一下自己实现的过程: 首先,我把蛇这个抽象成 ...

  2. JavaScript面向对象编程小游戏---贪吃蛇

    1 面向对象编程思想在程序项目中有着非常明显的优势: 1- 1 代码可读性高.由于继承的存在,即使改变需求,那么维护也只是在局部模块 1- 2 维护非常方便并且成本较低. ​ 2 这个demo是采用了 ...

  3. 用Canvas制作小游戏——贪吃蛇

    今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢. 按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不 ...

  4. 使用JavaScript实现简单的小游戏-贪吃蛇

    最近初学JavaScript,在这里分享贪吃蛇小游戏的实现过程, 希望能看到的前辈们能指出这个程序的不足之处. 大致思路 首先要解决的问题 随着蛇头的前进,尾巴也要前进. 用键盘控制蛇的运动方向. 初 ...

  5. python【控制台】小游戏--贪吃蛇

    传统贪吃蛇相信大家都玩过,也是一款很老很经典的游戏,今天我们用python控制台实现 项目有很多bug没有解决,因为本人一时兴起写的一个小游戏,所以只是实现可玩部分功能,并没有花较多的时间和精力去维护 ...

  6. 手把手教学h5小游戏 - 贪吃蛇

    简单的小游戏制作,代码量只有两三百行.游戏可自行扩展延申. 源码已发布至github,喜欢的点个小星星,源码入口:game-snake 游戏已发布,游戏入口:http://snake.game.yan ...

  7. Win32小游戏--贪吃蛇

    近日里学习了关于win32编程的相关知识,利用这些知识制作了一款贪吃蛇小游戏,具体细节还是分模块来叙述 前期准备:在网上找到一些贪吃蛇的游戏素材图片,以及具体的逻辑框图 在正式写功能之前,先把一系列环 ...

  8. Java经典小游戏——贪吃蛇简单实现(附源码)

    一.使用知识 Jframe GUI 双向链表 线程 二.使用工具 IntelliJ IDEA jdk 1.8 三.开发过程 3.1素材准备 首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以 ...

  9. 用Python实现童年小游戏贪吃蛇

    贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中.

随机推荐

  1. tomcat日志报Invalid message received with signature的解决办法

    这位大神说的是正解,大家可以参考一下这个链接:https://blog.csdn.net/bugdongwenlong/article/details/84261424

  2. js创建点击事件中<a>标签onclick传递多个参数

    var rowIndex = e.rowIndex; var t = "<a href='javascript:void(0)' onclick=\"viewInfo('&q ...

  3. 单元操作和仓储模式 repository+unitOfWork

    仓储和工作单元模式是用来在数据访问层和业务逻辑层之间创建一个抽象层.应用这些模式,可以帮助用来隔离你的程序在数据存储变化. 在数据源层和业务层之间增加一个repository层进行协调,有如下作用:1 ...

  4. [转载]python with语句的用法

    https://www.cnblogs.com/DswCnblog/p/6126588.html 看这篇文章的时候看到了python的类名()用法,很好奇,上网查了下,原来这就相当于对类进行实例化了. ...

  5. centos安装配置mariadb

    CentOS7下使用yum安装MariaDB CentOS 6 或早期的版本中提供的是 MySQL 的服务器/客户端安装包,但 CentOS 7 已使用了 MariaDB 替代了默认的 MySQL.M ...

  6. python连接oracle导出数据文件

    python连接oracle,感觉table_list文件内的表名,来卸载数据文件 主脚本: import os import logging import sys import configpars ...

  7. angular实现对百度天气api跨域请求

    申请秘钥:http://lbsyun.baidu.com/apiconsole/key  ,有个百度账号就行ak=开发者秘钥 url地址  :http://api.map.baidu.com/tele ...

  8. 入坑django2

    数据模型 关于时间的字段设置 add_date = models.DateTimeField('保存日期',default = timezone.now) mod_date = models.Date ...

  9. cmake 判断操作系统平台

    转载自 cmake 判断操作系统平台 MESSAGE(STATUS "operation system is ${CMAKE_SYSTEM}") IF (CMAKE_SYSTEM_ ...

  10. HTML 做圆形头像

    Click me <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...