import java.awt.event.KeyListener;
import javax.swing.JFrame;
import GG.ggh;
public class snackMain extends JFrame{
SnakeYard snac;
public snackMain() {
this.setTitle("简单的贪吃蛇游戏");//标题
this.setSize(SnakeYard.GameWidth+25,SnakeYard.GameHeight+50);//窗体大小
snac=new SnakeYard();//创建对象SnakeYard, snac是对象的引用
this.addKeyListener(snac);//绑定键盘事件
this.getContentPane().add(snac);//把容器加入到面板中
this.setLocation(200,200);//位置
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭
}
public static void main(String[] args) {
new snackMain().setVisible(true);//窗体可见
}
}
---------------------------------------------------------------------------------------
package MySnakeEatEgg;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SnakeYard extends JPanel implements KeyListener{
static final int GameWidth=600,GameHeight=450;//面板的宽和高
static boolean startFlag=false;//开始标记
snake sna;//创建对象引用
static int foodx,foody;//食物随机出现的坐标位置
public SnakeYard(){
sna = new snake();//创建对象 new snake,并被一个对象引用 sna 指向
foodx = (int)(Math.random()*(GameWidth-50));//随机生成食物的x坐标
foody = (int)(Math.random()*(GameHeight-50));//随机生成食物的y坐标
new Thread(new SnakeYardThread()).start();//线程
}
public static void main(String[] args) {
}
public void paint(Graphics g) {//重写paint()方法,画矩形面板,
super.paint(g);
g.setColor(Color.white);//画笔为白色
g.fillRect(0, 0, GameWidth, GameHeight);//// 用白色 填充一个矩形区域
g.setColor(Color.BLACK);//画笔为黑色
g.drawRect(0, 0, GameWidth, GameHeight);//用黑色笔划一个矩形
g.setColor(Color.GREEN);
g.fillOval(foodx, foody, 15,15);//绿色的食物
g.setColor(Color.blue);
sna.drawSnake(g);//蓝色的蛇身,调用drawSnake()画蛇
}
//线程处理过程
class SnakeYardThread implements Runnable{
@Override
public void run() {
while(true) {
try {
Thread.sleep(100);//每100毫秒(0.1秒),执行一次
repaint();//调用paint(),方法,有刷新页面的作用
if(startFlag)//startFlag 是开始标记,键盘事件中绑定了,是按下回车键,startFlag就变为true
sna.snakeMove();//调用snakeMove()方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void keyPressed(KeyEvent e) {//键盘事件
switch(e.getKeyCode()) {
case KeyEvent.VK_UP: if(snake.direction == 1) break;//上键
sna.dire(0);break;
case KeyEvent.VK_DOWN: if(snake.direction == 0) break;//下键
sna.dire(1);break;
case KeyEvent.VK_LEFT: if(snake.direction == 3) break;//左键
sna.dire(2);break;
case KeyEvent.VK_RIGHT: if(snake.direction == 2) break;//右键
sna.dire(3);break;
case KeyEvent.VK_SPACE: startFlag = false; break;//空格键
case KeyEvent.VK_ENTER: startFlag = true; break;//回车键
}
}
@Override
public void keyReleased(KeyEvent arg0) {}
@Override
public void keyTyped(KeyEvent arg0) {}
}
-----------------------------------------------------------------------
package MySnakeEatEgg;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class snake{
static final int UP=0,DOWN=1,LEFT=2,RIGHT=3;
static int size=15;//size 为蛇长
static int direction=RIGHT;
boolean eat=false;
boolean dead=false;
List<node> list=new ArrayList<node>();//集合用来存每个蛇的坐标
public void drawSnake(Graphics g) {
for (int i=0; i<list.size(); i++) {//画蛇
if(i==0) {
g.setColor(Color.RED);//蛇头用红色画
g.fillOval(list.get(i).getX(),list.get(i).getY(), size, size);// 用红色 填充一个椭圆区域,即为画蛇头,下同
}else {
g.setColor(Color.blue);//蓝色画蛇身
g.fillOval(list.get(i).getX(),list.get(i).getY(), size, size);
}
}
}
public snake(){
// 蛇初始化为5个节点
node node0 = new node(90,90);//蛇头的位置,
node node1 = new node(75,90);//创建对象new node,并被一个对象引用node1指向。 末尾的(75,90)意味着在对象创建后,立即调用node类的构造方法
node node2 = new node(60,90);
node node3 = new node(45,90);
node node4 = new node(30,90);
list.add(node0);//把 对象引用 添加到集合中去
list.add(node1);
list.add(node2);
list.add(node3);
list.add(node4);
}
public void snakeMove() {
int NewX,NewY;//两个变量先保存蛇头的初始值,因为不知道往哪里运动
NewX = list.get(0).getX();
NewY = list.get(0).getY();
switch(direction) {//direction的初始值为3,即RIGHT,通过键盘事件来改变direction的值
case UP: NewY = list.get(0).getY()-size; break;//UP为0(当按下 上箭头键 后,direction的值就变为0),向上运动,即y的值-size , x的值不变,下同
case DOWN: NewY = list.get(0).getY()+size; break;
case LEFT: NewX = list.get(0).getX()-size; break;
case RIGHT: NewX = list.get(0).getX()+size; break;
}
node NodeHead = new node(NewX,NewY);//新的头坐标,此时的两个变量是变化后的值
node newNode = new node();//新的尾坐标
// Math.abs绝对值
if(Math.abs(list.get(0).getX()-SnakeYard.foodx)<= size && Math.abs(list.get(0).getY()-SnakeYard.foody)<= size) {
eat = true;//吃到标记
newNode = new node(list.get(list.size()-1).getX(),list.get(list.size()-1).getY());//吃到食物就保存尾坐标
while(true) {
SnakeYard.foodx = (int)(Math.random()*(SnakeYard.GameWidth-50));//随机生成食物的x坐标
SnakeYard.foody = (int)(Math.random()*(SnakeYard.GameHeight-50));//随机生成食物的y坐标
if(list.get(0).getX() == SnakeYard.foodx && list.get(0).getY()== SnakeYard.foody) {
continue;
}else {
break;
}
}
}
//把前一个点的对象引用给后一点
for (int i = list.size()-1;i>0;i--){
list.set(i, list.get(i-1));
}
list.set(0, NodeHead);//新的头坐标
//是否碰到边缘
if(list.get(0).getX()+size<=0||list.get(0).getX()+size>=SnakeYard.GameWidth||list.get(0).getY()+size<=0||list.get(0).getY()+size>=SnakeYard.GameHeight){
JOptionPane.showMessageDialog(null, "GAME OVER!!", "Message", JOptionPane.ERROR_MESSAGE);
System.exit(-1);
}
//是否吃到自己
for(int i=1;i<list.size();i++) {
if(list.get(0).getX()==list.get(i).getX() && list.get(0).getY()==list.get(i).getY()) {
JOptionPane.showMessageDialog(null, "GAME OVER!!", "Message", JOptionPane.ERROR_MESSAGE);//提示
System.exit(-1);//退出
}
}
//如果吃到食物,添加新的节点,加尾节点
if(eat) {
list.add(newNode);
eat=false;
}
}
//蛇的坐标
class node{
int x,y;
public node(int x,int y) {
this.x=x;
this.y=y;
}
public node() {
}
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;
}
}
//蛇的运动方向,当触发键盘事件后,direction的值就改变了
public void dire(int dire) {
this.direction=dire;
}
}