接昨天的内容
一、放置的图片可以先ps一下。因为懒,所以把所有的头都用了right.png
目录/statics要记得刷新,否则会不能出现界面。
package game;
import java.net.URL;
import javax.swing.ImageIcon;
public class Data
{
//head photo
public static URL headerUrl=Data.class.getResource("/statics/header.png");
public static ImageIcon header= new ImageIcon(headerUrl);
//body
public static URL upUrl=Data.class.getResource("/statics/right.png");
public static URL downUrl=Data.class.getResource("/statics/right.png");
public static URL leftUrl=Data.class.getResource("/statics/right.png");
public static URL rightUrl=Data.class.getResource("/statics/right.png");
public static ImageIcon up= new ImageIcon(upUrl);
public static ImageIcon down= new ImageIcon(downUrl);
public static ImageIcon left= new ImageIcon(leftUrl);
public static ImageIcon right= new ImageIcon(rightUrl);
public static URL bodyUrl=Data.class.getResource("/statics/body1.png");
public static ImageIcon body= new ImageIcon(bodyUrl);
//food
public static URL foodUrl=Data.class.getResource("/statics/food.png");
public static ImageIcon food= new ImageIcon(foodUrl);
}
二、主程序
package game;
import java.awt.Color;
import javax.swing.JFrame;
public class StartGame {
public static void main(String[] args)
{
// 新建一个窗口
JFrame jframe=new JFrame("java-贪吃蛇");
jframe.setBounds(10,10,900,720);
jframe.setBackground(Color.pink);
jframe.setResizable(false);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//添加自定义画板
jframe.add(new GamePanel());
}
}
三、核心
package game;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GamePanel extends JPanel implements KeyListener,ActionListener
{
/**
*核心代码
*/
private static final long serialVersionUID = 1L;//默认选择第一个值
//蛇的长度
int length;
int [] snakeX=new int [600];
int [] snakeY=new int [500];
//蛇的方向
String fx="R";
//start?
boolean isStart =false;
boolean isFail=false;
Timer timer =new Timer(200,this);
//food
int foodX;
int foodY;
Random random =new Random();//随机位置
//score
int score;
public GamePanel()
{
init();
this.setFocusable(true);//必须设置一个焦点,要不然键盘捕获不到
this.addKeyListener(this);
timer.start();
}
private void init()
{
//初始时,蛇有三节
length=3;
snakeX[0]=100;snakeY[0]=100;//间隔是25,小蛇显示才正常,要不然会有间隔
snakeX[1]=75;snakeY[1]=100;//以X轴来控制的
snakeX[2]=50;snakeY[2]=100;
//食物初始化
foodX=25+25*random.nextInt(34);
foodY=75+25*random.nextInt(24);
//初始化分数
score=0;
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
//super.paintComponent(g)这个方法如果出错,会导致画布出不来
this.setBackground(Color.WHITE);
Data.header.paintIcon(this, g, 10, 10);
g.fillRect(25, 75, 850, 600);
//画蛇
if (fx.equals("R")) Data.right.paintIcon(this , g, snakeX[0],snakeY[0]);
else if (fx.equals("L")) Data.left.paintIcon(this , g, snakeX[0],snakeY[0]);
else if (fx.equals("U")) Data.up.paintIcon(this , g, snakeX[0],snakeY[0]);
else if (fx.equals("D")) Data.down.paintIcon(this , g, snakeX[0],snakeY[0]);
for(int i=1;i<length;i++)
Data.body.paintIcon(this, g, snakeX[i],snakeY[i]);
Data.food.paintIcon(this, g, foodX, foodY);
g.setColor(Color.BLACK);
g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString("长度:"+length, 750, 30);
g.drawString("分数:"+score, 750, 50);
if (isStart==false)
{
g.setColor(Color.WHITE);
g.setFont(new Font("宋体",Font.BOLD,50));
g.drawString("按下空格开始游戏!", 300,400);
}
if (isFail)
{
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,50));
g.drawString("失败,按下空格开始游戏!", 300,400);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (isStart&&isFail==false) //游戏开始,蛇可以移动
{
for(int i=length-1;i>0;i--)//右移,除了脑袋都往前移动
{
snakeX[i]=snakeX[i-1];
snakeY[i]=snakeY[i-1];
}
//通过方向控制移动
if (fx.equals("R"))
{
snakeX[0]=snakeX[0]+25; //移动一个图标的位置是25大小
if (snakeX[0]>850) snakeX[0]=25;//出界限,回起点
}
else if (fx.equals("L"))
{
snakeX[0]=snakeX[0]-25;
if (snakeX[0]<25) snakeX[0]=850;//出界限,回边界点
}
else if (fx.equals("U"))
{
snakeY[0]=snakeY[0]-25;
if (snakeY[0]<75) snakeY[0]=650;//出界限,回边界点
}
else if (fx.equals("D"))
{
snakeY[0]=snakeY[0]+25;
if (snakeY[0]>650) snakeY[0]=75;//出界限,回起点
}
//吃食物
if (snakeX[0]==foodX&&snakeY[0]==foodY)
{
length++;
score=score+10;
foodX=25+25*random.nextInt(34);//游戏区域范围内 随机数(0-33)*25即 小于850
foodY=75+25*random.nextInt(24);//游戏区域范围内 随机数(0-23)*25即小于600
}
//结束前,头撞到身体则失败
for(int i=1;i<length;i++)
{
if (snakeX[i]==snakeX[0]&&snakeY[i]==snakeY[0])
{
isFail=true;
}
}
repaint();//需要不断更新界面
}
timer.start();
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e)
{
int keycode=e.getKeyCode();
//如果是空格
if (keycode== KeyEvent.VK_SPACE)
{
if (isFail)//失败,重新初始化
{
isFail=false;
init();
} else isStart=!isStart;//否则暂停游戏
}
//键盘控制走向
if (keycode== KeyEvent.VK_LEFT) fx="L";
else if (keycode== KeyEvent.VK_RIGHT) fx="R";
else if (keycode== KeyEvent.VK_UP) fx="U";
else if (keycode== KeyEvent.VK_DOWN) fx="D";
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
运行结果: