花了两个下午写了一个贪吃蛇小游戏,本人想写这游戏很长时间了。作为以前诺基亚手机上的经典游戏,贪吃蛇和俄罗斯方块一样,都曾经在我们的童年给我们带来了很多乐趣。世间万物斗转星移,诺基亚曾经作为手机业的龙头老大,现如今也一步步走向衰落,被收购,再过不久估计就要退出手机业务了,而贪吃蛇这款游戏也基本上没人玩了,甚至在新一代人的印象中都已毫无记忆了。。。但是,这款游戏在它基础上经过改造其实可以弄出很多花样,也确实可以在一定程度上锻炼自己的编程能力。前不久十分火热的贪吃蛇大作战其实就可以看做是在这款游戏的基础上进行的改造。所以,我也希望自己可以尝试以下,做个有意思的版本。

目前这个版本只是为了后期版本的一个测试版本,所以只有一些基本功能,本来是打算这个版本实现了移动,吃食物增长,判断撞墙和撞自己的身体就行了,无奈觉得有点单调,于是在此基础上加上了一个计时器,记分功能,重新开始,开始暂停以及音效。白白又多了几百行代码。原来的基本代码也就300行。

游戏界面图如下:

注意运行时请附带以下文件:

http://files.cnblogs.com/files/journal-of-xjx/SnakeDemo.rar

以后版本更新都将放到 Github:

https://github.com/JiaxinTse/Snake

另外,第四版的游戏截图请看下一篇文章,比此处的Demo版丰富了很多:

http://www.cnblogs.com/journal-of-xjx/p/7217799.html

 import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.sound.sampled.*;
import javax.swing.*; class Tile{
int x;
int y; public Tile(int x0,int y0){
x = x0;
y = y0;
}
} public class SnakeDemo extends JComponent{
/**
*
*/
private static final long serialVersionUID = 3794762291171148906L;
private final int MAX_SIZE = 400;//蛇身体最长为400节
private Tile temp = new Tile(0,0);
private Tile temp2 = new Tile(0,0);
private Tile head = new Tile(227,100);//头部的位置初始化为(227,100)
private Tile[] body = new Tile[MAX_SIZE];
private String direction = "R";//默认向右走
private String current_direction = "R";//当前方向
private boolean first_launch = false;
private boolean iseaten = false;
private boolean isrun = true;
private int randomx,randomy;
private int body_length = 5;//身体长度初始化为5
private Thread run;
private JLabel label = new JLabel("当前长度:");
private JLabel label2 = new JLabel("所花时间:");
private JLabel label3 = new JLabel("说 明:");
private JTextArea explain = new JTextArea("此游戏是一个贪吃蛇Demo版本,实现简单地移动,得分,判断撞墙和撞自己的功能,"
+ "初始长度为6,头部为红色,身体的颜色渐变。游戏本身代码只有300行,加上一些显示,计时和音效后多了几百行。\n"
+ "游戏界面按上下左右键实现移动,按ESC重新开始,按空格键可以实现暂停和开始");
private JLabel Score = new JLabel("6");
private JLabel Time = new JLabel("");
private Font f = new Font("微软雅黑",Font.PLAIN,15);
private Font f2 = new Font("微软雅黑",Font.PLAIN,13);
private JPanel p = new JPanel();
private int hour =0;
private int min =0;
private int sec =0 ;
private boolean pause = false; public SnakeDemo(){
String lookAndFeel =UIManager.getSystemLookAndFeelClassName();
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (ClassNotFoundException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
} catch (InstantiationException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
} catch (UnsupportedLookAndFeelException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
} //布局
add(label);
label.setBounds(500, 10, 80, 20);
label.setFont(f);
add(Score);
Score.setBounds(500, 35, 80, 20);
Score.setFont(f);
add(label2);
label2.setBounds(500, 60, 80, 20);
label2.setFont(f);
add(Time);
Time.setBounds(500, 85, 80, 20);
Time.setFont(f);
add(p);
p.setBounds(498, 110, 93, 1);
p.setBorder(BorderFactory.createLineBorder(Color.black)); add(label3);
label3.setBounds(500, 115, 80, 20);
label3.setFont(f);
add(explain);
explain.setBounds(498, 138, 100, 350);
explain.setFont(f2);
explain.setLineWrap(true);
explain.setOpaque(false); for(int i = 0; i < MAX_SIZE;i++)
{
body[i] = new Tile(0,0);
} addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
if(e.getKeyCode() == KeyEvent.VK_RIGHT)
{
if(isrun && current_direction != "L")
{
direction = "R";
}
}
if(e.getKeyCode() == KeyEvent.VK_LEFT)
{
if(isrun && current_direction != "R")
{
direction = "L";
}
}
if(e.getKeyCode() == KeyEvent.VK_UP)
{
if(isrun && current_direction != "D")
{
direction = "U";
}
}
if(e.getKeyCode() == KeyEvent.VK_DOWN)
{
if(isrun && current_direction != "U")
{
direction = "D";
}
}
if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
direction = "R";//默认向右走
current_direction = "R";//当前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
Score.setText("6");
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
} run = new Thread();
run.start();
System.out.println("Start again");
}
if(e.getKeyCode() == KeyEvent.VK_SPACE)//按空格键开始和暂停暂时没做,还在思考中
{
if(!pause)//暂停
{
pause = true;
isrun = false;
}
else//开始
{
pause = false;
isrun = true;
}
}
}
}); new Timer(); setFocusable(true);
} public void paintComponent(Graphics g1){
super.paintComponent(g1);
Graphics2D g = (Graphics2D) g1;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_NORMALIZE); //画头部
g.setColor(Color.red);
g.fillRoundRect(head.x, head.y, 20, 20, 10, 10); g.setPaint(new GradientPaint(115,135,Color.CYAN,230,135,Color.MAGENTA,true));
if(!first_launch)
{
//初始化身体
int x = head.x;
for(int i = 0;i < body_length;i++)
{
x -= 22;//相邻两个方块的间距为2个像素,方块宽度都为20像素
body[i].x = x;
body[i].y = head.y;
g.fillRoundRect(body[i].x, body[i].y, 20, 20, 10, 10);
}
//初始化食物位置
ProduceRandom();
g.fillOval(randomx, randomy, 19, 19);
}
else
{
//每次刷新身体
for(int i = 0;i < body_length;i++)
{
g.fillRoundRect(body[i].x, body[i].y, 20, 20, 10, 10);
} if(EatFood())//被吃了重新产生食物
{
ProduceRandom();
g.fillOval(randomx, randomy, 19, 19);
iseaten = false;
}
else
{
g.fillOval(randomx, randomy, 19, 19);
}
}
first_launch = true;
//墙
g.setStroke( new BasicStroke(4,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
g.setBackground(Color.black);
g.drawRect(2, 7, 491, 469); //网格线
for(int i = 1;i < 22;i++)
{
g.setStroke( new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
g.setColor(Color.black);
g.drawLine(5+i*22,9,5+i*22,472);
if(i <= 20)
{
g.drawLine(4,10+i*22,491,10+i*22);
}
}
} public void ProduceRandom(){
boolean flag = true;
Random rand = new Random();
randomx = (rand.nextInt(21) + 1) * 22 + 7;
randomy = (rand.nextInt(20) + 1) *22 + 12;
while(flag)
{
for(int i = 0;i < body_length; i++)
{
if(body[i].x == randomx && body[i].y == randomy)
{
randomx = (rand.nextInt(21) + 1) * 22 + 7;
randomy = (rand.nextInt(20) + 1) *22 + 12;
flag = true;
break;
}
else
{
if(i == body_length - 1)
{
flag = false;
}
}
}
}
} public void HitWall(){//判断是否撞墙
if(current_direction == "L")
{
if(head.x < 7)
{
new AePlayWave("over.wav").start();
isrun = false;
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默认向右走
current_direction = "R";//当前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
Score.setText("6");
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
} run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
if(current_direction == "R")
{
if(head.x > 489)
{
new AePlayWave("over.wav").start();
isrun = false;
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默认向右走
current_direction = "R";//当前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
Score.setText("6");
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
} run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
if(current_direction == "U")
{
if(head.y < 12)
{
new AePlayWave("over.wav").start();
isrun = false;
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默认向右走
current_direction = "R";//当前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
Score.setText("6");
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
} run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
if(current_direction == "D")
{
if(head.y > 472)
{
new AePlayWave("over.wav").start();
isrun = false;
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默认向右走
current_direction = "R";//当前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
Score.setText("6");
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
} run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
} public void HitSelf(){//判断是否撞到自己身上
for(int i = 0;i < body_length; i++)
{
if(body[i].x == head.x && body[i].y == head.y)
{
new AePlayWave("over.wav").start();
isrun = false;
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默认向右走
current_direction = "R";//当前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
Score.setText("6");
hour =0;
min =0;
sec =0 ;
for(int j = 0; j < MAX_SIZE;j++)
{
body[j].x = 0;
body[j].y = 0;
} run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
break;
}
}
} public boolean EatFood(){
if(head.x == randomx && head.y == randomy)
{
iseaten = true;
return true;
}
else
{
return false;
}
} public void Thread(){
long millis = 300;//每隔300毫秒刷新一次
run = new Thread() {
public void run() {
while (true)
{
try {
Thread.sleep(millis);
} catch (InterruptedException ex) {
ex.printStackTrace();
} if(!pause)
{
temp.x = head.x;
temp.y = head.y;
//头部移动
if(direction == "L")
{
head.x -= 22;
}
if(direction == "R")
{
head.x += 22;
}
if(direction == "U")
{
head.y -= 22;
}
if(direction == "D")
{
head.y += 22;
}
current_direction = direction;//刷新当前前进方向
//身体移动
for(int i = 0;i < body_length;i++)
{
temp2.x = body[i].x;
temp2.y = body[i].y;
body[i].x = temp.x;
body[i].y = temp.y;
temp.x = temp2.x;
temp.y = temp2.y;
} if(EatFood())
{
body_length ++;
body[body_length-1].x = temp2.x;
body[body_length-1].y = temp2.y;
Score.setText("" + (body_length+1) );
new AePlayWave("eat.wav").start();
} repaint(); HitWall();
HitSelf();
}
}
}
}; run.start();
} public static void main(String[] args) {
SnakeDemo t = new SnakeDemo();
t.Thread(); JFrame game = new JFrame();
Image img=Toolkit.getDefaultToolkit().getImage("title.png");//窗口图标
game.setIconImage(img);
game.setTitle("Snake By XJX");
game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// game.setSize(502, 507);
game.setSize(602, 507);
game.setResizable(false);
game.setLocationRelativeTo(null); game.add(t);
game.setVisible(true);
} //计时器类
class Timer extends Thread{
public Timer(){
this.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(isrun){
sec +=1 ;
if(sec >= 60){
sec = 0;
min +=1 ;
}
if(min>=60){
min=0;
hour+=1;
}
showTime();
} try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} private void showTime(){
String strTime ="" ;
if(hour < 10)
strTime = "0"+hour+":";
else
strTime = ""+hour+":"; if(min < 10)
strTime = strTime+"0"+min+":";
else
strTime =strTime+ ""+min+":"; if(sec < 10)
strTime = strTime+"0"+sec;
else
strTime = strTime+""+sec; //在窗体上设置显示时间
Time.setText(strTime);
}
}
} class AePlayWave extends Thread {
private String filename;
private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb public AePlayWave(String wavfile) {
filename = wavfile;
} public void run() {
File soundFile = new File(filename);
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
} catch (UnsupportedAudioFileException e1) {
e1.printStackTrace();
return;
} catch (IOException e1) {
e1.printStackTrace();
return;
} AudioFormat format = audioInputStream.getFormat();
SourceDataLine auline = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); try {
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
} catch (Exception e) {
e.printStackTrace();
return;
} auline.start();
int nBytesRead = 0;
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; try {
while (nBytesRead != -1) {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
if (nBytesRead >= 0)
auline.write(abData, 0, nBytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
auline.drain();
auline.close();
}
}
}

Java实现贪吃蛇游戏【代码】的更多相关文章

  1. 用Java开发贪吃蛇游戏

    贪吃蛇游戏的设计步骤: Part 1: 设计游戏图纸 画出900*700的白色窗口 在窗口上添加画布 在画布上添加标题 在画布上添加黑色游戏区 Part 2: 放置静态的蛇:一个头.两个身体 加上开始 ...

  2. Java实现贪吃蛇游戏(含账号注册登录,排行榜功能)

    这是我第一次工程实践的作业,选题很多,但我只对其中的游戏开发感兴趣,可游戏就两三个类型,最终还是选择了贪吃蛇.其实就贪吃蛇本身的代码实现还算是比较简单的,可是实践要求代码行达到一定数量,所以我就额外给 ...

  3. java实现贪吃蛇游戏

    最简单的4个java类就可以实现贪吃蛇: main函数: package tcs; public class GreedSnake { public static void main(String[] ...

  4. python学习笔记05:贪吃蛇游戏代码

    贪吃蛇游戏截图: 首先安装pygame,可以使用pip安装pygame: pip install pygame 运行以下代码即可: #!/usr/bin/env python import pygam ...

  5. 用OpenGL简单编写的一个最简单贪吃蛇游戏

    刚学OpenGL的时候,写的一个最简单的贪吃蛇游戏代码 如下: //贪吃蛇游戏 #include<stdio.h> #include<stdlib.h> #include< ...

  6. Love2D游戏引擎制作贪吃蛇游戏

    代码地址如下:http://www.demodashi.com/demo/15051.html Love2D游戏引擎制作贪吃蛇游戏 内附有linux下的makefile,windows下的生成方法请查 ...

  7. Java贪吃蛇游戏

    package snake.game; import java.awt.CardLayout; import java.awt.Color; import java.awt.Graphics;   i ...

  8. 使用Java的GUI技术实现 “ 贪吃蛇 ” 游戏

    详细教程: 使用Java的GUI技术实现 " 贪吃蛇 " 游戏_IT打工酱的博客-CSDN博客

  9. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

随机推荐

  1. wkhtmltopdf

    最近要做一个html转pdf的功能,在网上找了很多内容,itext什么的,都不太满意,最后找到一个wkhtmltopdf,用起来真的很不错,还找到了一篇好文章,我就直接抄过来了,等有时间我再自己理一遍 ...

  2. .NET版支付宝商户会员卡接入

    最近公司计划对接支付宝会员卡功能,而任务恰巧由领导安排给我这边,小弟之前也未做过支付宝接口,研究了三天,终于将支付宝会员卡API接口大体上调通了,现将其整理下,以供参考. 蚂蚁金服开发平台-商户会员卡 ...

  3. VSCode插件及用户设置

    第一部分:插件 VSCode内置"emmet"插件,"convert to utf-8"等插件效果!十分强大!代码提示功能特别强悍! 插件地址:点击此处! 推荐 ...

  4. 技术债务管理以及Firefox/Chromium的债务评价

    如今的软件开发是在遍地敏捷,人人讲唯快不破的时代,哪有人有时间思考代码质量,设计的质量? 哪个又不是从一堆代码中杀出血路来实现还有一个功能?一个产品都存活不了几年,何必考虑什么可维护性? 我们追求进度 ...

  5. 利用Photoshop减小照片景深

    有时我们想拍出景深较小的照片,可是因为拍摄设备不支持,或者拍摄时没有调好參数,效果不理想. 这时能够借助Photoshop进行后期调整.一定程度上弥补缺陷.用到的主要是PS中的滤镜-->模糊-- ...

  6. DirectX:在graph自己主动连线中增加自己定义filter(graph中遍历filter)

    为客户提供的视频播放的filter的測试程序中,採用正向手动连接的方式(http://blog.csdn.net/mao0514/article/details/40535791).因为不同的视频压缩 ...

  7. .NET作品集:linux下的.net mvc cms

    cms程序架构 本程序是主要是用于企业网站开发的,也可以做博客程序,程序是从之前上一篇的.net 博客程序改进过来的,主要技术由webform转成.net mvc了,由于是很早之前的项目,12年还是m ...

  8. python 列表解析

    列表解析,主要用于动态创建列表 本篇主要说一下,lambda.map().和filter()同列表解析语句之间结合的用法 列表解析的基本语法为:[expr for iter_var in iterab ...

  9. Selenium Python 安装指导

    最近无聊.又重新装了个selenium 果然时代变了.安装的时候的方法和以前不太一样了.因此觉得有必要单列出来加以说明 另外备注:测试小伙伴们.安装此类工具报错.尝试以下两个方案之一: 1.请转sta ...

  10. Handlebars 新手使用

    昨天抽空看了一下关于Handlebars的 基础使用, 从开始写asp.net 用视图引擎,到写web 的时候 ,都是 用AJAx  来接受并分析数据,然后用 拼接的方式,或者追加的方式来实现在  页 ...