JFrame窗体
import com.sun.xml.internal.ws.handler.HandlerException;
import javax.swing.*;
public class MainFrame extends JFrame {
public MainFrame() throws HandlerException{
//初始化窗口参数
initFrame();
}
//初始化窗口参数
private void initFrame() {
//设置岩体高地
setSize(610,640);
//设置窗体位置
setLocation(400,400);
//设置关闭按钮(退出)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗体大小不可变
setResizable(false);
}
public static void main(String[] args) {
//创建窗体对象,显示窗体
new MainFrame().setVisible(true);
}
}
JPanel面板 创建游戏棋盘
创建食物
import java.util.Random;
/*
节点: 每一条蛇是由若干节点组成,每个节点(食物)都有横纵坐标确定位置
*/
public class Node {
private int x;
private int y;
public Node() {
}
public Node(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;
}
//随机生成食物位置
public void random(){
//创建对象
Random r=new Random();
//随机生成横坐标
this.x=r.nextInt(40);
//随机生成纵坐标
this.y = r.nextInt(40);
}
}
创建蛇
import java.util.LinkedList;
/*
每个节点用LinkedList集合储存Node节点,蛇出生有6个节点
*/
public class snake {
//蛇身体
private LinkedList<Node> body;
public snake(){
//初始化蛇身体
initsnake();
}
private void initsnake() {
//创建集合
body=new LinkedList<>();
//创建6个节点作为蛇身体
body.add(new Node(16,20));
body.add(new Node(17,20));
body.add(new Node(18,20));
body.add(new Node(19,20));
body.add(new Node(20,20));
body.add(new Node(21,20));
}
public LinkedList<Node> getBody() {
return body;
}
public void setBody(LinkedList<Node> body) {
this.body = body;
}
}
完整代码
主函数:MainFrame
import com.sun.xml.internal.ws.handler.HandlerException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
public class MainFrame extends JFrame {
private snake snake;
private JPanel jPanel;//游戏棋盘
private Timer timer;//定时器 在指定时间调用蛇移动的方法
private Node food;//食物
public MainFrame() throws HandlerException{
//初始化窗口参数
initFrame();
//初始化游戏棋盘
initGamePanel();
//初始化蛇
initsnake();
//初始化食物
initFood();
//初始化定时器
initTimer();
//设置键盘监听,让蛇随着键盘方向移动
setKeyListener();
}
//初始化食物
private void initFood() {
food=new Node();
food.random();//调用Random方法 随机生成食物
}
private void setKeyListener() {
addKeyListener(new KeyAdapter() {
@Override
//pressed按下 当键盘按下时,会自动调用此方法
public void keyPressed(KeyEvent e) {
//键盘中每一个键都有编号 获取编号
switch (e.getKeyCode()){
case KeyEvent.VK_UP: //上键
//修改蛇的运动方向
//当向上走的时候,做判断 如果蛇的运动方向不是下,才能走
if (snake.getDirection()!=Direction.DOWN){
snake.setDirection(Direction.UP);
}
//snake.setDirection(Direction.UP);
break;
case KeyEvent.VK_DOWN: //下键
if (snake.getDirection()!=Direction.UP){
snake.setDirection(Direction.DOWN);
}
// snake.setDirection(Direction.DOWN);
break;
case KeyEvent.VK_LEFT: //左键
if (snake.getDirection()!=Direction.RIGHT){
snake.setDirection(Direction.LEFT);
}
// snake.setDirection(Direction.LEFT);
break;
case KeyEvent.VK_RIGHT: //右键
if (snake.getDirection()!=Direction.LEFT){
snake.setDirection(Direction.RIGHT);
}
// snake.setDirection(Direction.RIGHT);
break;
}
}
});
}
//初始化定时器
private void initTimer() {
timer=new Timer();
//初始化定时任务
TimerTask timerTask = new TimerTask(){
@Override
public void run() {
snake.nove();
//判断蛇吃食物 蛇头与食物重合
Node head = snake.getBody().getFirst();
if (head.getX()==food.getX()&&head.getY()==food.getY()){
snake.eat(food);
food.random();
}
//每次移动都重绘游戏棋盘(刷新)
jPanel.repaint();
}
};
//每一百毫米执行一次任务 0秒开始执行(延迟) 过程为100毫秒
timer.scheduleAtFixedRate(timerTask,0,120);
}
//初始化蛇
private void initsnake() {
snake=new snake();
}
//初始化游戏棋盘
private void initGamePanel() {
jPanel = new JPanel(){
@Override
//绘制游戏棋盘中的内容
public void paint(Graphics g) {
//清空棋盘
g.clearRect(0,0,600,600);
//Graphics g可以看做画笔,提供了很多方法绘制基本的图像
//绘制40调横线 40.fori快速生成
/*
第一条:起点(0,0) 终点(600,0)
第二条:起点(0,15)终点(600,15)
....
第n条:起点(0,n*15)终点(600,n*15)
*/
for (int i = 0; i <=40; i++) {
g.drawLine(0,i*15,600,i*15);
}
//绘制40条竖线
/*
第一条:起点(0,0) 终点(0,600)
第n条:起点(15*n,0)终点(0,600)
*/
for (int i = 0; i <=40; i++) {
g.drawLine(i*15,0,i*15,600);
}
//绘制蛇
LinkedList<Node> body = snake.getBody();
for (Node node:body){
g.fillRect(node.getX()*15,node.getY()*15,15,15);
}
//绘制食物
g.fillRect(food.getX()*15,food.getY()*15,15,15);
}
};
//把棋盘添加到窗体中
add(jPanel);
}
//初始化窗口参数
private void initFrame() {
//设置岩体高地
setSize(610,640);
//设置窗体位置
setLocation(400,400);
//设置关闭按钮(退出)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗体大小不可变
setResizable(false);
}
public static void main(String[] args) {
//创建窗体对象,显示窗体
new MainFrame().setVisible(true);
}
}
节点:Node
import java.util.Random;
/*
节点: 每一条蛇是由若干节点组成,每个节点(食物)都有横纵坐标确定位置
*/
public class Node {
private int x;
private int y;
public Node() {
}
public Node(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;
}
//随机生成食物位置
public void random(){
//创建对象
Random r=new Random();
//随机生成横坐标
this.x=r.nextInt(40);
//随机生成纵坐标
this.y = r.nextInt(40);
}
}
蛇:snake
import java.util.LinkedList;
/*
每个节点用LinkedList集合储存Node节点,蛇出生有6个节点
*/
public class snake {
//蛇身体
private LinkedList<Node> body;
//蛇的运动方向 默认为左边
private Direction direction=Direction.LEFT;
//用于判断蛇是否活着
private boolean isliving=true;
public snake(){
//初始化蛇身体
initsnake();
}
private void initsnake() {
//创建集合
body=new LinkedList<>();
//创建6个节点作为蛇身体
body.add(new Node(16,20));
body.add(new Node(17,20));
body.add(new Node(18,20));
body.add(new Node(19,20));
body.add(new Node(20,20));
body.add(new Node(21,20));
}
//蛇沿着蛇头方向移动
// 控制蛇移动 在蛇头运动的方向添加一个节点 同时在蛇尾的节点删除,实现移动
public void nove(){
if (isliving) {
//获取蛇头
Node head = body.getFirst();
switch (direction) {
case UP://如果向上 则在蛇的上面添加一个节点 横坐标不变,纵坐标-1
body.addFirst(new Node(head.getX(), head.getY() - 1));
break;
case DOWN:
body.addFirst(new Node(head.getX(), head.getY() + 1));
break;
case LEFT:
body.addFirst(new Node(head.getX() - 1, head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX() + 1, head.getY()));
break;
}
//删除蛇尾的节点
body.removeLast();
//判断是否撞墙 撞墙则将状态转为false
head=body.getFirst();
if (head.getX()<0||head.getY()<0||head.getX()>=40||head.getY()>=40){
isliving=false;
System.out.println("分数:"+ body.size());
}
//判断蛇是否吃到自己 用蛇头与身体各位置比较 如果位置相同 就吃到自己
for (int i=1;i<body.size();i++){ //i=1,不是等于0,等于0直接死
Node node = body.get(i);
if (head.getX()==node.getX()&&head.getY()==node.getY()){
isliving=false;
System.out.println("分数:"+ body.size());
}
}
}
}
public LinkedList<Node> getBody() {
return body;
}
public void setBody(LinkedList<Node> body) {
this.body = body;
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
//蛇吃食物 沿着蛇头方向添加一个节点 与移动蛇的代码相同
public void eat(Node food) {
Node head = body.getFirst();
switch (direction) {
case UP://如果向上 则在蛇的上面添加一个节点 横坐标不变,纵坐标-1
body.addFirst(new Node(head.getX(), head.getY() - 1));
break;
case DOWN:
body.addFirst(new Node(head.getX(), head.getY() + 1));
break;
case LEFT:
body.addFirst(new Node(head.getX() - 1, head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX() + 1, head.getY()));
break;
}
}
}
枚举:按键 Direction 用Enum建
/*
枚举:几个固定常量,制作按键:来定义控制键
*/
public enum Direction {
UP,DOWN,LEFT,RIGHT
}