最近写了一个贪吃蛇的小游戏,感觉难点就在于蛇的位置控制,由于蛇的状态不定,所在你在按下键的时候要判断它前一时刻的的形状,并处理它下一步怎么移动。(今天加入了鼠标事件,起到物体提示作用)
代码:
- import java.awt.BorderLayout;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics;
- import java.awt.event.*;
- import javax.swing.AbstractAction;
- import javax.swing.Action;
- import javax.swing.JComponent;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JOptionPane;
- import javax.swing.JToolTip;
- import javax.swing.KeyStroke;
- public class Snak extends JComponent implements MouseMotionListener,Runnable{
- //背景图
- //ImageIcon image;
- //提示信息
- String message="";
- //墙的横竖的个数,蛇的最大长度
- static int N=50,M=50;
- //定义墙壁
- static int a[][]=new int[N][M];
- //定义蛇
- static int longer=5;//蛇的原始长度
- static int head=longer-1;//蛇头
- static int x[]=new int[]{4,5,6,7,8,0,0,0,0,0,0,0,0,0,0};
- static int y[]=new int[]{10,10,10,10,10,0,0,0,0,0,0,0,0,0,0};
- //定义食物
- static int food=0;
- static int eatnum=0;
- static int x1[]=new int[]{25,7,15,22,19,27,32,34,41,46,12};
- static int y1[]=new int[]{16,10,39,5,28,32,12,23,14,41,14};
- //用于显示步数和时间
- String foot="";
- String time="";
- //记下步数
- static int footnum=0;
- //时间开始与停止标志
- public boolean flag=true;
- /**
- * @贪吃蛇游戏
- */
- public Snak(){
- //image = new ImageIcon(myclass.greedsnak.Snak.class.getResource("1.png"));
- //处理键盘响应事件即上下左右键,事件的处理在对应的Action中
- this.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
- this.getActionMap().put("up",up);
- this.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
- this.getActionMap().put("down",down);
- this.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
- this.getActionMap().put("right",right);
- this.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
- this.getActionMap().put("left",left);
- //增加鼠标事件
- addMouseMotionListener(this);
- //启动计时线程
- Thread thread=new Thread(this);
- thread.start();
- }
- public void init(){
- //产生墙壁
- for(int i=0;i<N;i++){
- for(int j=0;j<M;j++){
- a[i][j]=1;
- }
- }
- for(int i=2;i<N-2;i++){
- for(int j=2;j<M-2;j++){
- a[i][j]=0;
- }
- }
- //产生蛇
- for(int i=0;i<longer;i++){
- if(i==head)
- //蛇头
- a[x[i]][y[i]]=3;
- else
- //蛇身
- a[x[i]][y[i]]=2;
- }
- //产生食物
- a[x1[food]][y1[food]]=4;
- }
- public void paintComponent(Graphics g){
- init();
- //image.paintIcon(this, g, 0, 0);
- g.setColor(Color.blue);
- g.setFont(new Font("f",Font.BOLD,15));
- g.drawString(message, 160, 250);
- for(int i=0;i<N;i++){
- for(int j=0;j<M;j++){
- if(a[i][j]==1){
- g.setColor(Color.orange);
- g.fill3DRect(i*10,j*10,10, 10,true);
- }else if(a[i][j]==2){
- g.setColor(Color.pink);
- g.fillRect(10*i, 10*j, 10, 10);
- }else if(a[i][j]==3){
- g.setColor(Color.pink);
- g.fillOval(10*i, 10*j, 10, 10);
- }else if(a[i][j]==4){
- g.setColor(Color.red);
- g.fill3DRect(i*10,j*10,10, 10,true);
- }
- }
- }
- g.setColor(Color.pink);
- g.drawString("步数:", 100, 460);
- g.drawString(foot, 150, 460);
- g.drawString("用时:", 300, 460);
- g.drawString(time, 350, 460);
- }
- //处理上下左右的键盘事件
- Action up = new AbstractAction( ) {
- public void actionPerformed(ActionEvent e) {
- message="提示:你正在往上走";
- up();
- foot=""+(++footnum);
- repaint();
- if(food==10) gameOver();
- }
- };
- Action down = new AbstractAction( ) {
- public void actionPerformed(ActionEvent e) {
- message="提示:你正在往下走";
- down();
- foot=""+(++footnum);
- repaint();
- if(food==10) gameOver();
- }
- };
- Action right = new AbstractAction( ) {
- public void actionPerformed(ActionEvent e) {
- message="提示:你正在往右走";
- right();
- foot=""+(++footnum);
- repaint();
- if(food==10) gameOver();
- }
- };
- Action left = new AbstractAction( ) {
- public void actionPerformed(ActionEvent e) {
- message="提示:你正在往左走";
- left();
- foot=""+(++footnum);
- repaint();
- if(food==10) gameOver();
- }
- };
- //处理蛇的各个动作
- public void up(){
- //处理碰壁
- if(a[x[head]][y[head]-1]==1) message="提示:你撞到墙壁了哦!";
- //处理向上碰自己
- else if(a[x[head]][y[head]-1]==2) touchself("up");
- //处理碰到食物
- else if(a[x[head]][y[head]-1]==4) eatFood("up");
- //处理移动
- else {
- moving("up");
- }
- }
- public void down(){
- //处理碰壁
- if(a[x[head]][y[head]+1]==1) message="提示:你撞到墙壁了哦!";
- //处理向上碰自己
- else if(a[x[head]][y[head]+1]==2) touchself("down");
- //处理碰到食物
- else if(a[x[head]][y[head]+1]==4) eatFood("down");
- //处理移动
- else {
- moving("down");
- }
- }
- public void right(){
- //处理碰壁
- if(a[x[head]+1][y[head]]==1) message="提示:你撞到墙壁了哦!";
- //处理向上碰自己
- else if(a[x[head]+1][y[head]]==2) touchself("right");
- //处理碰到食物
- else if(a[x[head]+1][y[head]]==4) eatFood("right");
- //处理移动
- else {
- moving("right");
- }
- }
- public void left(){
- //处理碰壁
- if(a[x[head]-1][y[head]]==1) message="提示:你撞到墙壁了哦!";
- //处理向上碰自己
- else if(a[x[head]-1][y[head]]==2) touchself("left");
- //处理碰到食物
- else if(a[x[head]-1][y[head]]==4) eatFood("left");
- //处理移动
- else {
- moving("left");
- }
- }
- public void touchself(String direction){
- if("up".equals(direction)){
- //如果向上从自己身上走过
- if(x[head]==x[head-1]&&y[head]==(y[head-1]+1)) message="提示:不能从自己身上过!";
- else message="提示:你不能碰到你自己呢!";
- }else if("down".equals(direction)){
- //如果向下从自己身上走过
- if(x[head]==x[head-1]&&y[head]==(y[head-1]-1)) message="提示:不能从自己身上过!";
- else message="提示:你不能碰到你自己呢!";
- }else if("right".equals(direction)){
- //如果向右从自己身上走过
- if((x[head]==x[head-1]-1)&&y[head]==y[head-1]) message="提示:不能从自己身上过!";
- else message="提示:你不能碰到你自己呢!";
- }else if("left".equals(direction)){
- //如果向左从自己身上走过
- if((x[head]==x[head-1]+1)&&y[head]==y[head-1]) message="提示:不能从自己身上过!";
- else message="提示:你不能碰到你自己呢!";
- }
- }
- public void gameOver(){
- //停止计时
- flag=false;
- JOptionPane.showMessageDialog(Snak.this, "恭喜你过了这一关!","过关了哦!",JOptionPane.INFORMATION_MESSAGE);
- }
- //处理蛇吃食物
- public void eatFood(String direction){
- if("up".equals(direction)){
- //System.out.println("eatfood-up");
- //蛇的长度加1
- longer+=1;
- //加入这节长度的坐标,事实就把食物的位置改为增加一节的位置
- x[longer-1]=x[head];
- y[longer-1]=y[head]-1;
- //把蛇头换到第一节的位置
- head=longer-1;
- //显示第二个食物
- food+=1;
- message="提示:你成功吃下"+(++eatnum)+"个食物哦!";
- //向上移动
- moving("up");
- }else if("down".equals(direction)){
- //System.out.println("eatfood-down");
- //蛇的长度加1
- longer+=1;
- //加入这节长度的坐标,事实就把食物的位置改为增加一节的位置
- x[longer-1]=x[head];
- y[longer-1]=y[head]+1;
- //把蛇头换到第一节的位置
- head=longer-1;
- //显示第二个食物
- food+=1;
- message="提示:你成功吃下"+(++eatnum)+"个食物哦!";
- //向下移动
- moving("down");
- }else if("right".equals(direction)){
- //System.out.println("eatfood-right");
- //蛇的长度加1
- longer+=1;
- //加入这节长度的坐标,事实就把食物的位置改为增加一节的位置
- x[longer-1]=x[head]+1;
- y[longer-1]=y[head];
- //把蛇头换到第一节的位置
- head=longer-1;
- //显示第二个食物
- food+=1;
- message="提示:你成功吃下"+(++eatnum)+"个食物哦!";
- //向上移动
- moving("right");
- }else if("left".equals(direction)){
- //System.out.println("eatfood-left");
- //蛇的长度加1
- longer+=1;
- //加入这节长度的坐标,事实就把食物的位置改为增加一节的位置
- x[longer-1]=x[head]-1;
- y[longer-1]=y[head];
- //把蛇头换到第一节的位置
- head=longer-1;
- //显示第二个食物
- food+=1;
- message="提示:你成功吃下"+(++eatnum)+"个食物哦!";
- //向上移动
- moving("left");
- }
- }
- //处理蛇的动作
- public void moving(String direction){
- if("up".equals(direction)){
- //从尾开始移动
- corewalk();
- //蛇头向上移一步
- y[longer-1]-=1;
- }else if("down".equals(direction)){
- //从尾开始移动
- corewalk();
- //蛇头向下移一步
- y[longer-1]+=1;
- }else if("right".equals(direction)){
- //从尾开始移动
- corewalk();
- //蛇头向右移一步
- x[longer-1]+=1;
- }else if("left".equals(direction)){
- //从尾开始移动
- corewalk();
- //蛇头向左移一步
- x[longer-1]-=1;
- }
- }
- //处理蛇移动的核心方法
- public void corewalk(){
- //从尾开始移动
- for(int i=1;i<=longer-1;i++){
- //如果后一节在前一节的左边
- if((x[i-1]==x[i]-1)&&y[i-1]==y[i])
- x[i-1]+=1;
- //如果后一节在前一节的右边
- else if((x[i-1]==x[i]+1)&&y[i-1]==y[i])
- x[i-1]-=1;
- //如果后一节在前一节的下边
- else if(x[i-1]==x[i]&&(y[i-1]==y[i]+1))
- y[i-1]-=1;
- //如果后一节在前一节的上边
- else if(x[i-1]==x[i]&&(y[i-1]==y[i]-1))
- y[i-1]+=1;
- }
- }
- @Override
- public void mouseDragged(MouseEvent e) {
- }
- @Override
- public void mouseMoved(MouseEvent e) {
- int xx=e.getX();
- int yy=e.getY();
- //用来显示 Component的"提示"
- if(a[xx/10][yy/10]==1)
- //提示这是墙壁
- this.setToolTipText("这是墙壁");
- else if(a[xx/10][yy/10]==2)
- //提示这是蛇身
- this.setToolTipText("这是蛇身");
- else if(a[xx/10][yy/10]==3)
- //提示这是蛇头
- this.setToolTipText("这是蛇头");
- else if(a[xx/10][yy/10]==4)
- //提示这是食物
- this.setToolTipText("这是食物");
- else
- //提示这是空地
- this.setToolTipText("这是空地");
- }
- @Override
- public void run() {
- long start=System.currentTimeMillis();
- while(flag){
- try {
- Thread.sleep(1000);
- long recond=(System.currentTimeMillis()-start)/1000;
- if(recond>60){
- time=recond/60+"分"+recond%60+"秒";
- }else{
- time=recond+"秒";
- }
- repaint();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public static void main(String[] args) {
- JFrame pn=new JFrame("界面");
- JLabel label=new JLabel("贪吃蛇游戏",JLabel.CENTER);
- pn.setSize(506, 550);
- pn.setResizable(false);
- pn.setDefaultCloseOperation(3);
- pn.getContentPane().add(label,BorderLayout.NORTH);
- pn.getContentPane().add(new Snak(),BorderLayout.CENTER);
- pn.setVisible(true);
- }
- }