//主面板
MinPane.java
import javax.swing.JFrame;
public class MinPane extends JFrame{
public static void main(String[] args) {
JFrame mainFrame=new JFrame();
mainFrame.setSize(400, 400);
mainFrame.setVisible(true);
mainFrame.setResizable(false);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SnakePane sp=new SnakePane();
mainFrame.add(sp);
}
}
游戏实现
SnakePane.java
import java.awt.Color;
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.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SnakePane extends JPanel implements KeyListener,ActionListener{
//蛇头图片元素
ImageIcon headR=new ImageIcon("ico/Right.png");
ImageIcon headL=new ImageIcon("ico/Left.png");
ImageIcon headU=new ImageIcon("ico/Up.png");
ImageIcon headD=new ImageIcon("ico/Down.png");
//蛇身体图片元素
ImageIcon snakeBody=new ImageIcon("ico/Body.png");
//食物图片
ImageIcon food=new ImageIcon("ico/Food.png");
//初始化蛇的长度
int len=3;
//400表示蛇的移动范围xy方向最大400个坐标
int[] snakex=new int[400];
int[] snakey=new int[400];
/***初始化蛇时配置***/
//蛇头
ImageIcon head=headR;
//是否处于运行状态
boolean run=false;
//游戏失败
boolean isfailed=false;
//判断运动方向
String direction="Right";
/***初始化蛇头和蛇身体位置*/
void birthSnake(){
head=headR;
run=false;
isfailed=false;
direction="Right";
len=3;
//蛇头的位置
snakex[0]=40;
snakey[0]=40;
//蛇身体的位置
snakex[1]=30;
snakey[1]=40;
snakex[2]=20;
snakey[2]=40;
}
//食物坐标
Random r=new Random();
int foodx=r.nextInt(36)*10+10;
int foody=r.nextInt(36)*10+10;
Timer timer=new Timer(100, this);//每隔100毫秒会执行一次监听器actionPerformed()方法用来监听这个面板对象
public SnakePane() {
this.setFocusable(true);//设置为可以获取焦点这样才能获取键盘监听事件
addKeyListener(this);//注册键盘监听器
birthSnake();
timer.start();
}
//重写画笔,再actionPerformed里使用
public void paint(Graphics g) {
//g.setColor(Color.blue);
g.fillRect(0, 0, 400, 400);//必须画个矩形,没有这个会这个图形会变成一条线,原先的图形会显示,奇怪得很
//如果游戏在运行且游戏没有失败
if(!isfailed){
//画蛇头,蛇头根据蛇头的坐标来画
head.paintIcon(this, g, snakex[0], snakey[0]);
//画蛇身体
for(int i=1;i<len;i++){
snakeBody.paintIcon(this, g, snakex[i], snakey[i]);
}
//画食物
food.paintIcon(this, g, foodx, foody);
}else{
g.setColor(Color.RED);
g.drawString("游戏结束! 得分:"+(len-3), 40, 40);
}
};
//500毫秒画一次面板
public void actionPerformed(ActionEvent arg0) {
if(run==true&&!isfailed){
//下一节身体获取上一节身体坐标,应该从蛇尾开始才能操作,如果从蛇头操作最后获得的都是蛇头坐标
for(int i=len-1;i>0;i--){
snakex[i]=snakex[i-1];
snakey[i]=snakey[i-1];
}
if(direction.equals("Right")){
snakex[0]=snakex[0]+10;
head=headR;
if(snakex[0]>400) snakex[0]=0;
}else if(direction.equals("Left")){
head=headL;
snakex[0]=snakex[0]-10;
if(snakex[0]<0) snakex[0]=400;
}else if(direction.equals("Up")){
head=headU;
snakey[0]=snakey[0]-10;
if(snakey[0]<0) snakey[0]=400;
}else if(direction.equals("Down")){
head=headD;
snakey[0]=snakey[0]+10;
if(snakey[0]>400) snakey[0]=0;
}
if(snakex[0]==foodx&&snakey[0]==foody){
len++;
foodx=r.nextInt(36)*10+10;
foody=r.nextInt(36)*10+10;
}
for(int i=1;i<len;i++){
if(snakex[0]==snakex[i]&&snakey[0]==snakey[i]){
isfailed=true;
}
}
repaint();
}
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode=e.getKeyCode();
if(keyCode==KeyEvent.VK_SPACE && isfailed==true){//如果游戏失败按下空格则初始化,同时游戏开始运行
birthSnake();
run=true;
}else{
if(keyCode==KeyEvent.VK_SPACE && run==false){
run=true;
}else if(keyCode==KeyEvent.VK_SPACE && run==true){
run=false;
}else if(keyCode==KeyEvent.VK_UP &&direction!="Down"){
direction="Up";
}else if(keyCode==KeyEvent.VK_LEFT&&direction!="Right"){
direction="Left";
}else if(keyCode==KeyEvent.VK_RIGHT&&direction!="Left"){
direction="Right";
}else if(keyCode==KeyEvent.VK_DOWN&&direction!="Up"){
direction="Down";
}
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}