Java Greedy Snake, need to be updated

this is the interface:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

This is the source code:

/**
 * @(#)GreedSnake.java
 *
 *现在还有两个问题没有结局,一个是加速问题,食物会消失,范围
 *吃到的食物没有有可能不会加到末端,原因在于吃到食物的一瞬间,必须迅速添加结点,否则,会偏移
 *这样一个有些的缺点是每个蛇结点都是一个线程,开销比较大
 * @author 
 * @version 1.00 2019/4/4
 */
package com.view.test;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class GreedSnake extends JFrame {
	
    public GreedSnake() {
    	MyPanel mp=new MyPanel();
    	Thread t=new Thread(mp);
    	t.start();
    	this.addKeyListener(mp);
    	this.add(mp);
    	this.setSize(600,400);
    	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	this.setVisible(true);
    }
    public static void main(String[] args){
    	GreedSnake gs=new GreedSnake();
    }
    
    public void actionPerformed(ActionEvent e)
    {
    	
    }
   
}
class MyPanel extends JPanel implements KeyListener,Runnable{
	boolean gameOver=false;
	Food food=null;
	Snake snake=null;
	Node node=null;
	Thread t=null;
	Vector<Node> vn=new Vector<Node>();
	Vector<Snake> vs=new Vector<Snake>();
	public MyPanel(){
		//初始化产生一个食物
		food=new Food(60,60);
		//初始化产生十个蛇结点,便于调测蛇的移动
		snake=new Snake(200,100,3);
		Thread t=new Thread(snake);
		t.start();
		vs.add(snake);
	}
	public void paint(Graphics g)
	{   
		super.paint(g);
		g.fillRect(0,0,600,400);
		g.setColor(Color.red);
		g.fillOval(food.getX(),food.getY(),20,20);
		g.setColor(Color.green);
		for(int i=0;i<600/20;i++)
			g.drawLine(i*20, 0, i*20, 400);
		for(int i=0;i<400/20;i++)
			g.drawLine(0, i*20, 600, i*20);
		g.setColor(Color.blue);
		for(int i=0;i<vs.size();i++)
			g.fillOval(vs.get(i).getX(), vs.get(i).getY(), 20, 20);
		
		if(gameOver=GameOver())
		{
			Font myFont=new Font("仿宋",Font.ITALIC,80);
			g.setFont(myFont);
			g.setColor(Color.yellow);
			g.drawString("游戏结束!", 200, 200);
		}
	}
public void eatFood(){
		System.out.println(food.getX()+""+food.getY());
		System.out.println(vs.get(0).getX());
		if((vs.get(0).getX()==food.getX())&& (vs.get(0).getY()==food.getY()))
		{
			int x=(int)(Math.random()*580);
			x-=x%20+20;
			int y=(int)(Math.random()*380);
			y-=y%20+20;
			System.out.println("food location"+x+","+y);
			food=new Food(x,y);
			//根据蛇尾的方向,增加新的蛇结点,每个蛇节点都是一个线程,方向跟随蛇尾方向
			switch((vs.get(vs.size()-1)).getDirect())
			{
			case 1:
				snake=new Snake(vs.lastElement().getX(),vs.lastElement().getY()+20,1);
				t=new Thread(snake);
				t.start();
				vs.add(snake);
				break;
			case 2:
				snake=new Snake(vs.lastElement().getX(),vs.lastElement().getY()-20,2);
				t=new Thread(snake);
				t.start();
				vs.add(snake);
				break;
			case 3:
				snake=new Snake(vs.lastElement().getX()+20,vs.lastElement().getY(),3);
				t=new Thread(snake);
				t.start();
				vs.add(snake);
				break;
			case 4:
				snake=new Snake(vs.lastElement().getX()-20,vs.lastElement().getY(),4);
				t=new Thread(snake);
				t.start();
				vs.add(snake);
				break;
			}
			System.out.println("eatfood");
		}
	}
public void Move()
	{
		for(int i=0;i<vn.size();i++)
		{
			for(int j=0;j<vs.size();j++)
			{
				if(vs.get(j).getX()==vn.get(i).getX() && vs.get(j).getY()==vn.get(i).getY())
				{
					vs.get(j).setDirect(vn.get(i).getDirect());
				}
			}
		}
		//如果所有节点的方向一样,我就把所有转向点去除
		for(int i=0;i<vs.size();i++)
		{
			if(vs.get(i).getDirect()==vs.get(0).getDirect())
			{
				continue;
			}else{
				return;
			}
		}
		vn.removeAllElements();
		System.out.println("vn.size:"+vn.size());
	}
public boolean GameOver()
	{
		boolean Gameover=false;
		for(int i=1;i<vs.size();i++)
		{
			if(vs.get(i).getX()==vs.get(0).getX() && vs.get(i).getY()==vs.get(0).getY())
			{
				Gameover=true;
			}
		}
		if(vs.get(0).getX()>600 ||vs.get(0).getX()<0 ||vs.get(0).getY()>400 ||vs.get(0).getY()<0)
		{
			Gameover=true;
		}
		return Gameover;
	}
public void keyReleased(KeyEvent e)
	{
		
	}
	public void keyTyped(KeyEvent e){
	}
	
	public void keyPressed(KeyEvent e)
	{	
		//按下方向键,设置蛇头方向
		//其实头的方向也没有必要设置,只要设置转向点就可以了
		//如果有不止一个蛇结点,就有必要在转向时设置转向点
		//其实也没有必要,只有一个结点的时候,增加了的转向点在后面的操作中会很快将其删除
		
		if(e.getKeyCode()==KeyEvent.VK_UP)
		{	
			vs.get(0).setDirect(1);
			
		}else if(e.getKeyCode()==KeyEvent.VK_DOWN)
		{
			vs.get(0).setDirect(2);
		}else if(e.getKeyCode()==KeyEvent.VK_LEFT)
		{
			vs.get(0).setDirect(3);
		}
		else if(e.getKeyCode()==KeyEvent.VK_RIGHT)
		{
			vs.get(0).setDirect(4);
		}else if(e.getKeyCode()==KeyEvent.VK_A)
		{
			snake.speed+=20;
		}
		node=new Node(vs.get(0).getX(),vs.get(0).getY(),vs.get(0).getDirect());
		vn.add(node);
	}
public void run()
	{
		while(true)
		{
			try{
				Thread.sleep(200);	
			}catch(Exception e){
				e.printStackTrace();
			}
			//面板线程只负责重绘,不参与吃和移动,吃和移动是蛇的属性
			this.repaint();
			eatFood();
			Move();
		}
	}
}

class Snake implements Runnable
{
	int x;
	int y;
	int speed=20;
	int direct;//规定:1向上 2向下 3向左 4向右
	public Snake(int x,int y,int direct)
	{
		this.x=x;
		this.y=y;
		this.direct=direct;
	}
	
	public int getX(){
		return x;
	}
	public void setX(int x){
		this.x=x;
	}
	public int getY(){
		return y;
	}
	public void setY(int y){
		this.y=y;
	}
	public int getSpeed(){
		return speed;
	}
	public void setSpeed(int speed){
		this.speed=speed;
	}
	public int getDirect(){
		return direct;
	}
	public void setDirect(int direct){
		this.direct=direct;
	}
public void run()
	{
		//蛇之所以能移动的关键在于此线程
		while(true){
			try{
				Thread.sleep(1000);
			}catch(Exception e){
				e.printStackTrace();
			}
			switch(direct)
			{
			case 1:
				y-=speed;
				break;
			case 2:
				y+=speed;
				break;
			case 3:
				x-=speed;
				break;
			case 4:
				x+=speed;
				break;
			}
			
		}
	}
}
class Node{
	int x;
	int y;
	int direct;
	public Node(int x,int y,int direct){
		this.x=x;
		this.y=y;
		this.direct=direct;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getDirect(){
		return direct;
	}
	public void setDirect(int direct){
		this.direct=direct;
	}
	
}
class Food{
	int x;
	int y;
	public Food(int x,int y){
		this.x=x;
		this.y=y;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值