java小游戏第三弹 贪吃蛇

/*
 * 贪吃蛇,采取了组件,集合的思想,
 * 简单的图形界面运用+集合处理

 */

package cn.hncu.games;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
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.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

import cn.hncu.set.MySet;

public class RetroSnaker extends JFrame{
	
	private String dir="./images_RetroSnaker/";
	private JMenu[] jmenu;
	private JMenuItem[][] jmenuItem;
	/*
	 * 菜单处理
	 */
	private ActionListener jmenuListener=new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent e) {
			if(e.getActionCommand().equals("newGame")){
				//snaker.newGame();
				newGame();
			}else if(e.getActionCommand().equals("break")){
				if(timer==null||!timer.isRunning())
					return;
				timer.stop();
				removeKeyListener(keyListener);
				jmenuItem[0][1].setEnabled(false);
				jmenuItem[0][2].setEnabled(true);
			}else if(e.getActionCommand().equals("continue")){
				if(timer==null||timer.isRunning())
					return;
				timer.restart();
				addKeyListener(keyListener);
				jmenuItem[0][2].setEnabled(false);
				jmenuItem[0][1].setEnabled(true);
			}else if(e.getActionCommand().equals("exit")){
				if (timer!=null&&timer.isRunning()) {
					timer.stop();
				}
				//System.exit(0);
				dispose();
			}else if(e.getActionCommand().equals("nightmare")){
				delay=40;
				setDifficultyLabel(2);
				repaint();
			}else if(e.getActionCommand().equals("hard")){
				delay=100;
				setDifficultyLabel(1);
				repaint();
			}else if(e.getActionCommand().equals("low")){
				delay=600;
				setDifficultyLabel(0);
				repaint();
			}
		}
	};
	//private SnakerJPanel snaker;
	private Timer timer;
	/*
	 * 动态监听,移动(更新)贪吃蛇
	 */
	private ActionListener listener=new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent e) {
			upDete();
		}
	};
	/*
	 * 键盘监听,控制方向
	 */
	private KeyListener keyListener=new KeyListener() {
		@Override
		public void keyTyped(KeyEvent e) {
		}
		@Override
		public void keyReleased(KeyEvent e) {
		}
		@Override
		public void keyPressed(KeyEvent e) {
			if(timer==null||!timer.isRunning()||mySet.size()<1)
				return;
			timer.stop();
			int keyCode=e.getKeyCode();
			switch(keyCode){
			case KeyEvent.VK_DOWN:
				((SnakerBody)mySet.get(0)).direction="down";
				break;
			case KeyEvent.VK_UP:
				((SnakerBody)mySet.get(0)).direction="up";
				break;
			case KeyEvent.VK_LEFT:
				((SnakerBody)mySet.get(0)).direction="left";
				break;
			case KeyEvent.VK_RIGHT:
				((SnakerBody)mySet.get(0)).direction="right";
				break;
			}
			upDete();
			timer.restart();
		}
	};
	private int delay=600;
	private int score=0;
	private MySet mySet=new MySet();
	private JLabel snakerlabel,difficultylabel;
	private SnakerBody nextSnaker;
	private boolean isOver;

	public RetroSnaker() {
		super("简易版贪吃蛇");
		setBounds(100, 20, 1200, 660);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		
		//菜单
		JMenuBar bar=new JMenuBar();
		
		String[] str={"游戏","选项"};
		String[][] strs={{"新游戏","暂停","继续","退出"},
				         {"噩梦","困难","普通"}};
		String[][] strs_english={{"newGame","break","continue","exit"},
				                 {"nightmare","hard","low"}};
		jmenu=new JMenu[str.length];
		jmenuItem=new JMenuItem[strs.length][];
		for (int i = 0; i < jmenu.length; i++) {
			jmenu[i]=new JMenu(str[i]);
			jmenuItem[i]=new JMenuItem[strs[i].length];
			for (int j = 0; j < jmenuItem[i].length; j++) {
				jmenuItem[i][j]=new JMenuItem(strs[i][j]);
				jmenuItem[i][j].addActionListener(jmenuListener);
				jmenuItem[i][j].setActionCommand(strs_english[i][j]);
				if(jmenuItem[i][j].getActionCommand().equals("continue"))
					jmenuItem[i][j].setEnabled(false);
				if(jmenuItem[i][j].getActionCommand().equals("break"))
					jmenuItem[i][j].setEnabled(false);
				jmenu[i].add(jmenuItem[i][j]);
			}
			bar.add(jmenu[i]);
		}
		setJMenuBar(bar);
		//snaker=new SnakerJPanel();
		//getContentPane().add(snaker);
		
		setBack();
		
		setVisible(true);
	}
    //设置背景
	private void setBack() {
		getContentPane().setLayout(null);
		for (int i = 0; i < 50; i++) {
			for (int j = 0; j < 30; j++) {
				if(i==0||j==0||i==49||j==29){
					JLabel jlbwall=new JLabel(new ImageIcon(dir+"zhuqiang.jpg"));
					jlbwall.setBounds(i*20, j*20, 20, 20);
					getContentPane().add(jlbwall);
				}
			}
		}
		
		JPanel scoreP=new JPanel(){
			@Override
			public void paint(Graphics g) {
				super.paint(g);
				g.setColor(Color.red);
				g.setFont(new Font("叶根友毛笔行书2.0版", Font.ITALIC, 20));
				g.drawString("游戏得分:", 20, 20);
				g.drawString("游戏难度:", 20, 120);
				g.setFont(new Font("叶根友毛笔行书2.0版", Font.ITALIC, 80));
				g.drawString(""+score, 40, 80);
				
				g.drawImage(Toolkit.getDefaultToolkit().createImage(dir+"she.jpg"),0,150,200,500,this);
			}
		};
		scoreP.setBounds(1000, 0, 200, 660);
		getContentPane().add(scoreP);
		
		scoreP.setLayout(null);
		
		difficultylabel=new JLabel();
		setDifficultyLabel(0);
		difficultylabel.setBounds(20, 100, 140, 200);
		scoreP.add(difficultylabel);
		
		JLabel shelabel=new JLabel(new ImageIcon(dir+"she.jpg"));
		shelabel.setBounds(20, 300, 160, 300);
		scoreP.add(shelabel);
	}
    /*
     * 难度标签
     */
	private void setDifficultyLabel(int num) {
		String[] strlabel={"low.png","hard.png","nightmare.png"};
		Icon img=new ImageIcon(dir+strlabel[num]);
		difficultylabel.setIcon(img);
	}
	/*
	 * 游戏初始化处理
	 */
	private void newGame() {
		
		if(timer!=null&&timer.isRunning())
			timer.stop();
		//初始化设置
		isOver=true;
		removeKeyListener(keyListener);
		addKeyListener(keyListener);
		jmenuItem[0][1].setEnabled(true);
		jmenuItem[0][2].setEnabled(false);
		jmenuItem[1][0].setEnabled(false);
		jmenuItem[1][1].setEnabled(false);
		jmenuItem[1][2].setEnabled(false);
		score=0;
		 // 自制集合MySet(文章后有集合链接),
		 // 清空集合,将蛇头加入

		for (int i = 0; i < mySet.size(); i++) {
			JLabel snakercomp=((SnakerBody)mySet.get(i)).snaker;
			getContentPane().remove(snakercomp);
		}
		mySet.removeAll();

		//头部标签设置位置,图片
		JLabel snakerhead=new JLabel(new ImageIcon(dir+"longtou.png"));
		mySet.add(new SnakerBody(new Point(20, 20), "right", snakerhead));
		
		snakerhead.setBounds(20, 20, 20, 20);
		getContentPane().add(snakerhead);
		
		//boxDifficulty.setSelectedIndex(boxDifficulty.getSelectedIndex());
		timer=new Timer(delay, listener);
		timer.start();
		
		nextSnaker=nextBody();
		
		repaint();
	}
	/*
	 * 下一个蛇身出现的随机处理
	 */
	private SnakerBody nextBody() {
		
		Random random=new Random();
		int x,y;
		//while(true)使随机出现的新点不在蛇身
		while (true) {
			x = random.nextInt(49) * 20;
			y = random.nextInt(29) * 20;
			if(x==0||y==0)
				continue;
			boolean flag=true;
			for (int i = 0; i < mySet.size(); i++) {
				SnakerBody body=((SnakerBody)mySet.get(i));
				if(x==body.point.x&&y==body.point.y){
					flag=false;
					break;
				}
			}
			if(flag)
				break;
		}
		if(snakerlabel!=null)
			getContentPane().remove(snakerlabel);
			
		snakerlabel=new JLabel(new ImageIcon(dir+"longshen.png"));
		snakerlabel.setBounds(x, y, 20, 20);
		getContentPane().add(snakerlabel);
		return new SnakerBody(new Point(x, y), "", snakerlabel);
		
	}
    //更新贪吃蛇
	private void upDete() {
		if(mySet.size()<1||!isOver)
			return;
		//先移除所有组件
		for (int i = 0; i < mySet.size(); i++) {
			JLabel snakercomp=((SnakerBody)mySet.get(i)).snaker;
			getContentPane().remove(snakercomp);
		}
		
		//移动位置,在集合中处理(由尾到头,使位置向上个进行改变)
		SnakerBody lastend=new SnakerBody((SnakerBody)mySet.get(mySet.size()-1));
		for (int i = mySet.size()-1; i > 0; i--) {
			SnakerBody last=((SnakerBody)mySet.get(i-1));
			SnakerBody body=((SnakerBody)mySet.get(i));
			body.point.x=last.point.x;
			body.point.y=last.point.y;
			body.direction=last.direction;
		}
		//头部处理
		SnakerBody head=((SnakerBody)mySet.get(0));
		String state=head.direction;
		if(state.equals("down"))
			head.point.y+=20;
		else if(state.equals("up"))
			head.point.y-=20;
		else if(state.equals("left"))
			head.point.x-=20;
		else if(state.equals("right"))
			head.point.x+=20;
		//判断是否结束
		boolean flag=isGameOver(head);
		//添加
		if(head.point.x==nextSnaker.point.x&&head.point.y==nextSnaker.point.y){
			addNextSnaker(lastend);
		}
		//添加组件显示
		int i = 0;
		if(flag)
			i=1;
		for (; i < mySet.size(); i++) {
			SnakerBody snakerb=((SnakerBody)mySet.get(i));
			JLabel snakercomp=snakerb.snaker;
			snakercomp.setLocation(snakerb.point);
			getContentPane().add(snakercomp);
		}
		repaint();
	}

	private boolean isGameOver(SnakerBody head) {
		//撞自身结束
		for (int k = 1; k < mySet.size(); k++) {
			SnakerBody bodynum=(SnakerBody)mySet.get(k);
			if(head.point.x==bodynum.point.x&&head.point.y==bodynum.point.y){
				overMessags();
				return true;
			}
		}
		//撞墙结束
		int i=head.point.x/20;
		int j=head.point.y/20;
		if(!(i<=0||j<=0||i>=49||j>=29))
			return false;
		else
			overMessags();
		return true;
	}
	/*
	 * 结束游戏显示
	 */
	private void overMessags() {
		int option=JOptionPane.showConfirmDialog(this, "得分:"+score+"。是否再来一次?", "游戏结束", JOptionPane.YES_NO_CANCEL_OPTION);
		if(option==JOptionPane.OK_OPTION)
			newGame();
		else if(option==JOptionPane.NO_OPTION){
			if (timer!=null&&timer.isRunning()) {
				timer.stop();
			}
			//System.exit(0);
			dispose();
		}else{
			timer.stop();
			isOver=false;
			removeKeyListener(keyListener);
			jmenuItem[0][1].setEnabled(false);
			jmenuItem[0][2].setEnabled(false);
			jmenuItem[1][0].setEnabled(true);
			jmenuItem[1][1].setEnabled(true);
			jmenuItem[1][2].setEnabled(true);
		}
	}
	/*
	 * 吃到,添加一个蛇身
	 */
	private void addNextSnaker(SnakerBody lastend) {
		nextSnaker.direction=lastend.direction;
		nextSnaker.point.x=lastend.point.x;
		nextSnaker.point.y=lastend.point.y;
		mySet.add(nextSnaker);
		score+=1;
		nextSnaker=nextBody();
	}

	/*
	 * 集合的封装类
	 * 将标签,位置,方向封装成一个类
	 */
	private class SnakerBody{
		private Point point;
		private String direction;
		private JLabel snaker;
		
		public SnakerBody(Point point,String direction,JLabel snaker){
			this.point=point;
			this.direction=direction;
			this.snaker=snaker;
		}
		public SnakerBody(SnakerBody snakerlast){
			this.point=new Point(snakerlast.point);
			this.direction=snakerlast.direction;
			this.snaker=snakerlast.snaker;
		}
	}
	public static void main(String[] args) {
		new RetroSnaker();
	}

}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值