效果预览图:
代码:
package demo01;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Snake008 extends JFrame implements KeyListener, ActionListener, MouseListener {
// 定义一个内部类用来创建坐标
class Point{
public int x;
public int y;
public Point (int x,int y){
this.x=x;
this.y=y;
}
}
// 窗口的宽
int width=800;
// 窗口的高
int height=900;
// 设置分数
int fenshu=0;
// 0表示上 1表示下 2表示左 3表示右
int fangxiang=3;
// 游戏状态 0表示正常 1表示暂停 2表示游戏结束
int zhuangtai=0;
// 设置图片
private Image image=null;
Graphics gf=null;
// 画蛇(蛇的初始顶点坐标)
Point points[]= {new Point(6,3),new Point(5,3),new Point(4,3),new Point(3,3)};
// 食物
Point food=getfood();
// 设置计时器
Timer timer=new Timer(500,this);
public void Tian(){
//设置宽为800,高为900
this.setSize(width,height);
//设置窗口能看见
this.setVisible(true);
//定时器的开关
timer.start();
//设置键盘监听事件(也就是当键盘有什么反应都会调用此函数)
this.addKeyListener(this);
}
// 绘制图形
public void paint(Graphics g){
//初始化临时图片//解决闪烁问题
if(image==null){
image=this.createImage(width,height);
}
if(this.gf ==null){
this.gf =image.getGraphics();
}
// 擦除背景
gf.setColor(Color.white);
//绘制白色背景
gf.fill3DRect(0,0,width,height,true);
// 绘制棋盘网格
// 网格颜色
gf.setColor(Color.darkGray);
// 画竖线
for (int j = 0; j <=width ; j+=50) {
gf.drawLine(j,0,j,height);
}
// 画横线
for (int i = 0; i <=height ; i+=50) {
gf.drawLine(0,i,width,i);
}
// 画蛇
gf.setColor(Color.green);
for (int i = 0; i < points.length; i++) {
gf.fill3DRect(points[i].x*50,points[i].y*50,50,50,true);
}
// 食物
gf.setColor(Color.yellow);
gf.fill3DRect(food.x*50,food.y*50,50,50,true);
// 重画蛇头
gf.setColor(Color.RED);
gf.fill3DRect(points[0].x*50,points[0].y*50,50,50,true);
// 分数
if (zhuangtai==0||zhuangtai==1){
gf.setColor(Color.GRAY);
gf.fill3DRect(0,0,width,height-800,true);
gf.setColor(Color.black);
gf.setFont(new Font("微软雅黑", 10, 25)); //设置字体
gf.drawString("得分:"+fenshu+"分",300,75);
}else if(zhuangtai==2){
gf.setColor(Color.GRAY);
gf.fill3DRect(0,0,width,height-800,true);
gf.setColor(Color.black);
gf.setFont(new Font("微软雅黑", 10, 25)); //设置字体
gf.drawString("游戏结束 最终得分:"+fenshu+"分",250,75);
}
g.drawImage(image,0,0,null);
}
// 按钮单击方法
public void actionPerformed(ActionEvent e) {
// 保留蛇的最后一步
Point end=new Point(points[points.length-1].x,points[points.length-1].y);
// 向上
if(fangxiang==0){
for (int i = 0,j=points.length-1; i < points.length; i++) {
if(j-i>0){
points[j-i].x=points[j-i-1].x;
points[j-i].y=points[j-i-1].y;
}else if(j-i==0){
points[j-i].x=points[j-i].x;
points[j-i].y=--points[j-i].y;
}
repaint();
}
// 向下
}else if(fangxiang==1){
for (int i = 0,j=points.length-1; i < points.length; i++) {
if(j-i>0){
points[j-i].x=points[j-i-1].x;
points[j-i].y=points[j-i-1].y;
}else if(j-i==0){
points[j-i].x=points[j-i].x;
points[j-i].y=++points[j-i].y;
}
repaint();
}
// 向左
}else if(fangxiang==2){
for (int i = 0,j=points.length-1; i < points.length; i++) {
if(j-i>0){
points[j-i].x=points[j-i-1].x;
points[j-i].y=points[j-i-1].y;
}else if(j-i==0){
points[j-i].x=--points[j-i].x;
points[j-i].y=points[j-i].y;
}
repaint();
}
// 向右
}else if(fangxiang==3){
for (int i = 0,j=points.length-1; i < points.length; i++) {
if(j-i>0){
points[j-i].x=points[j-i-1].x;
points[j-i].y=points[j-i-1].y;
}else if(j-i==0){
points[j-i].x=++points[j-i].x;
points[j-i].y=points[j-i].y;
}
repaint();
}
}
//蛇吃食物的处理
if(food.x==points[0].x&&food.y==points[0].y){
Point newpoints[]=new Point[points.length+1];
for (int i = 0; i < points.length; i++) {
newpoints[i]=points[i];
}
newpoints[newpoints.length-1]=end;
points=newpoints;
// 当食物被蛇吃后重新生成新的食物
food=getfood();
fenshu=points.length-4;
}
// 检测撞墙
if(points[0].x<0||points[0].x>15){
zhuangtai=2;
timer.stop();
}
if(points[0].y<2||points[0].y>17){
zhuangtai=2;
timer.stop();
}
// 检测是否撞到自己
for (int i = 1; i <points.length ; i++) {
if(points[0].x==points[i].x&&points[0].y==points[i].y){
zhuangtai=2;
timer.stop();
}
}
}
public void keyTyped(KeyEvent e) {
}
// 按下键盘--控制游戏的开始以及蛇的移动方向
public void keyPressed(KeyEvent e) {
// 获取从键盘输入的键
int key = e.getKeyCode();
if(key == KeyEvent.VK_SPACE) {//空格键
// 0表示正常 1表示暂停 2表示结束
if(zhuangtai==0){
// 从正常状态变为暂停状态
zhuangtai=1;
timer.stop();
}else if(zhuangtai==1){
// 从暂停状态变为正常状态
zhuangtai=0;
timer.start();
}else if(zhuangtai==2){
zhuangtai=0;
// 启动定时器
timer.start();
// 重置分数
fenshu=0;
// 重置蛇
points=new Point[]{new Point(6,3),new Point(5,3),new Point(4,3),new Point(3,3)};
// 重置食物
food=getfood();
// 重置方向
fangxiang=3;
}
}
//判断状态
if(zhuangtai==0){
// 上
if (key == KeyEvent.VK_UP&&fangxiang!=1) {
fangxiang=0;
// 下
}else if (key == KeyEvent.VK_DOWN&&fangxiang!=0) {
fangxiang=1;
// 左
}else if(key == KeyEvent.VK_LEFT&&fangxiang!=3){
fangxiang=2;
// 右
}else if (key == KeyEvent.VK_RIGHT&&fangxiang!=2) {
fangxiang=3;
}
}
// 强制重绘页面
repaint();
}
// 产生随机食物点
Point getfood(){
Random rd=new Random();
Point newfood=new Point(rd.nextInt(16),rd.nextInt(16)+2);
for (int i = 0; i < points.length; i++) {
// 产生一个合法的食物随机点
if(newfood.x==points[i].x&&newfood.y==points[i].y){
newfood=new Point(rd.nextInt(16),rd.nextInt(16)+2);
i=0;
}
}
return newfood;
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args) {
Snake008 snake=new Snake008();
snake.Tian();
}
}