用java的GUI写简易的贪吃蛇
大概思路
1、贪吃蛇界面绘制
2、绘制静态小蛇
3、让小蛇简单能动
4、让小蛇能够根据键盘来动
5、小蛇能够长大
6、关于失败以及积分的判定
在写代码之前,应该明白,游戏的界面都应该放在面板上,游戏的主要内容也都是写在面板的那个类上的。而面板上,我们写这个游戏核心几个点就是 paintComponent 和 keyPressed 以及 actionPerformed
第一段代码,new一个窗口,添加面板
第二段代码 面板的代码
第三段代码 获取小蛇和食物所需的素材
在这里插入public class StartGame {
public static void main(String[] args) {
//在这里调用窗口
StartGame startGame=new StartGame();
startGame.fram();
}
public void fram(){
//先new一个窗口
JFrame jFrame=new JFrame();
//设定窗口不可动
jFrame.setResizable(false);
//设置尺寸,尺寸需要计算
jFrame.setBounds(100,100,900,670);
//添加面板
Container container= jFrame.getContentPane();
jFrame.add(new GamePnal());
//这个一定要放在添加面板后,否则会键盘监听失效
jFrame.setVisible(true);
}
}
Data类用于获取小蛇的素材
public class Data {
//用URL获取地址
public static URL header=Data.class.getResource("header.png");
public static URL food=Data.class.getResource("food.png");
public static URL body=Data.class.getResource("body.png");
public static URL up=Data.class.getResource("up.png");
public static URL down=Data.class.getResource("down.png");
public static URL left=Data.class.getResource("left.png");
public static URL right=Data.class.getResource("right.png");
public static ImageIcon header1=new ImageIcon(header);
//将一个个地址放入图片图标中
public static ImageIcon food1=new ImageIcon(food);
public static ImageIcon body1=new ImageIcon(body);
public static ImageIcon up1=new ImageIcon(up);
public static ImageIcon down1=new ImageIcon(down);
public static ImageIcon left1=new ImageIcon(left);
public static ImageIcon right1=new ImageIcon(right);
}
//面板类
public class GamePnal extends JPanel implements KeyListener ,ActionListener{
//我们要写面板以及键盘监听器和动作监听器,就直接继承和实现接口,会更省我们的时间
int length=3;
//这里放小蛇的x和y坐标,用数组放
int[] snakex=new int[100];
int[] snakey=new int[100];
//写一个小蛇的方向
String fangxiang;
//start用于判断是否处于游戏开始状态
public static boolean start=false;
//fail用于判断小蛇是否处于失败状态
public static boolean fail=false;
//Timer用于刷新小蛇,这里的100是毫秒值
Timer timer=new Timer(100,this);//调用的前提是事件监听器
int foodx;//食物的x和y
int foody;
Random random=new Random();//用一个随机数,用于改变食物的位置
int socre;
//构造器 用于调用焦点以及键盘监听器
public GamePnal()
{
ui();
this.setFocusable(true);
this.addKeyListener(this);
//用于刷新
timer.start();
socre=0;
}
//ui是初始化数据的地方
public void ui(){
foodx=25+25*random.nextInt(30);
foody=75+25*random.nextInt(20);
//2对应的是尾巴。1是第一节身体,0是头的位置
snakex[0]=100; snakex[1]=75; snakex[2]=50;
snakey[0]=150; snakey[1]=150;snakey[2]=150;
fangxiang="right";//默认初始时,头向右
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//将header1素材写进来
setBackground(Color.CYAN);
Data.header1.paintIcon(this,g,25,61);
g.fillRect(25,125,850,500);
//添加自己想要添加的元素
g.setColor(Color.red);
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.drawString("追风的皮卡",300,45);
g.setColor(Color.green);
g.setFont(new Font("微软雅黑",Font.BOLD,20));
//把积分、长度写进来
g.drawString("长度"+length,750,85);
g.drawString("分数"+socre,750,105);
Data.food1.paintIcon(this,g,foodx,foody);
//根据字符串来把小蛇的头的方向画出来
if (fangxiang.equals("right")){
Data.right1.paintIcon(this,g,snakex[0],snakey[0]);
}else if (fangxiang.equals("left")){
Data.left1.paintIcon(this,g,snakex[0],snakey[0]);
}else if (fangxiang.equals("down")){
Data.down1.paintIcon(this,g,snakex[0],snakey[0]);
}else if (fangxiang.equals("up")){
Data.up1.paintIcon(this,g,snakex[0],snakey[0]);
}
//用一个循环画出小蛇身体,记得用循环,方便后期小蛇开始长大,可以循环画身体
for (int i = 1; i < length; i++) {
Data.body1.paintIcon(this,g,snakex[i],snakey[i]);
}
if(start==false){
g.setColor(Color.cyan);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("按下空格开始游戏",300,250);
}
if (fail){
g.setColor(Color.blue);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("菜狗,按空格再重新开始吧",300,250);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int key=e.getKeyCode();
if (key==KeyEvent.VK_SPACE){
//如果蛇死了,就会调用初始化
if(fail){ui();}
//当游戏开始后,需要改变start状态
else { start=!start;
// repaint();非常关键,可以重画,没有这个代码的话,按空格键,会没有效果
repaint();}
}
//根据键盘,来改变字符串
if (key==KeyEvent.VK_UP){
fangxiang="up";
}
else if (key==KeyEvent.VK_DOWN){
fangxiang="down";
}
else if (key==KeyEvent.VK_RIGHT){
fangxiang="right";
}
else if (key==KeyEvent.VK_LEFT){
fangxiang="left";
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void actionPerformed(ActionEvent e) {
//判断小蛇吃食物
if (snakex[0]==foodx&&snakey[0]==foody){
length++;
socre=socre+5;
foodx=25+25*random.nextInt(30);
foody=75+25*random.nextInt(20);
}
//判断游戏是开始后状态
if (start&&fail==false) {
//第一个循环是让小蛇的身体能够动起来,根据位置的赋值
for (int i = length - 1; i > 0; i--) {
snakex[i] = snakex[i - 1];
snakey[i] = snakey[i - 1];
}
if (fangxiang.equals("right")) {
//让头部加25,上面的循环才起作用
snakex[0] = snakex[0] + 25;
//用于边界判断
if (snakex[0] > 850) {
snakex[0] = 25;
}
} else if (fangxiang.equals("up")) {
snakey[0]=snakey[0]-25;
if (snakey[0]<135){snakey[0]=645;}
} else if (fangxiang.equals("down")) {
snakey[0]=snakey[0]+25;
if (snakey[0]>620){snakey[0]=125;}
} else if (fangxiang.equals("left")) {
snakex[0] = snakex[0] - 25;
if (snakex[0] < 25) {snakex[0]=850;}}
for (int i = 1; i < length; i++) {
if(snakex[0]==snakex[i]&&snakey[0]==snakey[i]){
fail=true;
}
}
repaint();//极其关键
}
}
}
最后,提醒几点自己本人写这个代码犯过的错
repaint();这行代码一定记得使用
jFrame.setVisible(true); 这行代码在窗口的类中一定记得放在最后,不要放在添加面板代码的前面,否则你的键盘监听器会失效
这是写好后的窗口