贪吃蛇项目(java版)
1. 首先创键一个蛇的类,包含成员x,y来确定蛇的位置
public class SNode {
//x坐标
int x;
//y坐标
int y;
//节点的颜色
Color color;
//构造函数 用来创建对象的 但是需要你给我传递x y 颜色这三个变量
public SNode(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
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 Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
2.在中间容器Mainpanel上面画蛇运动的地图
public class MainPanel extends JPanel {
//定义整个活动范围
static int xWidth = 30; //表示x方向有30个格子
static int yWidth = 30;
static int unit = 20; //表示格子的宽度
3.蛇的初始化,由于Java的坐标系中左上角(0,0)而且向下y值增大,向右x值增大,故编码如下
public MainPanel() {
SNode node1 = new SNode(xWidth / 2, yWidth / 2, Color.red);
SNode node2 = new SNode(xWidth / 2, yWidth / 2 + 1, Color.red);
snake.add(node1);
snake.add(node2);
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < snake.size(); i++) {
// g.setColor 设置颜色的
g.setColor(snake.get(i).getColor());
//画图形 fillOval 画矩形
g.fillOval(snake.get(i).getX() * unit, snake.get(i).getY() * unit, unit, unit);
}
g.setColor(food.getColor());
//画图形 fillOval 画矩形
g.fillOval(food.getX() * unit, food.getY() * unit, unit, unit);
}
`
4.生成一个键盘事件,能够控制蛇的移动,而且蛇在没有控制下,会自动移动
4.1键盘事件
KeyAdapter keyAdapter = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int key=e.getKeyCode();
int dir=0;
//根据按键的不同,我们需要去调整蛇的移动位置
if(key==KeyEvent.VK_UP){
dir=1;
}else if (key==KeyEvent.VK_DOWN){
dir=-1;
}else if (key==KeyEvent.VK_LEFT){
dir=2;
}else if (key==KeyEvent.VK_RIGHT){
dir=-2;
}
snakeMove(dir);
}
4.2 自动移动代码
int autoDir=1;//自动移动的反向
int delay=2000;
Timer t;
KeyAdapter keyAdapter = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int key=e.getKeyCode();
int dir=0;
//根据按键的不同,我们需要去调整蛇的移动位置
if(key==KeyEvent.VK_UP){
dir=1;
}else if (key==KeyEvent.VK_DOWN){
dir=-1;
}else if (key==KeyEvent.VK_LEFT){
dir=2;
}else if (key==KeyEvent.VK_RIGHT){
dir=-2;
}
autoDir=dir;
//按下了键 就应该要移动,所以就在键盘事件中调用移动方法
snakeMove(dir);
}
ActionListener actionListener=new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
snakeMove(1);//定时器中的方向应该是受键盘控制的
}
};
t = new Timer(2000,actionListener);//注意进口是javax.swing.Timer();
t.start();
}
//我们将蛇运动的逻辑定义一个方法,dir表示移动的方向
void snakeMove (int dir){
int oldHeadX=snake.get(0).getX();
int oldHeadY=snake.get(0).getY();
if (oldHeadX==food.x&&oldHeadY==food.y){
snake.add(food);
//吃了东西我就判断一下 调整下定时器的速度
if((snake.size()-2)%2==0){
delay=delay-100;
//注意我们带了delay 还需要设置该定时器 才会生效--
t.setDelay(delay);
}
food=createNewNode();
}
switch(dir){
case 1:
oldHeadY--;//(我们的原点是 0 0)
break;
case -1:
oldHeadY++;
break;
case 2://表示左
oldHeadX--;
break;
case -2://表示右
oldHeadX++;
break;
}
//再去掉最后一个节点
snake.removeLast();
//最后把新的头节点接在最前面
SNode node1=new SNode(oldHeadX,oldHeadY,Color.red);
snake.addFirst(node1);
repaint();//图形界面需要手动刷新
}
5.创建食物
food=createNewNode();
SNode createNewNode(){
boolean flag=true;
Random random =new Random();
int x=0;
int y=0;
while(flag){
//不断生成点(随机生成)
x=random.nextInt(xWidth-5);
y=random.nextInt(yWidth-5);
for (int i=0;i<snake.size();i++){
SNode node=snake.get(i);
//重复了 结束内循环
if(node.getX()==x&&node.getY()==y){
break;
}
if(i==snake.size()-1){
flag=false;//结束循环
}
}
}
SNode sNode=new SNode(x,y,Color.black);
return sNode;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(food.getColor());
//画图形 fillOval 画矩形
g.fillOval(food.getX() * unit, food.getY() * unit, unit, unit);
}
6.游戏死亡规则
撞到自己
//死亡判断--撞自己
for (int i=1;i<snake.size();i++){
SNode node=snake.get(i);
if (oldHeadX==node.getX() && oldHeadY==node.getY()){
System.out.println("撞自己");
System.exit(-1);
}
}
撞墙
//是否撞墙
if (oldHeadX<0||oldHeadX>xWidth-1||oldHeadY<0||oldHeadY>yWidth-1){
System.out.println("撞墙");
System.exit(-1);
}
7.难度升级机制
if (oldHeadX==food.x&&oldHeadY==food.y){
snake.add(food);
//吃了东西我就判断一下 调整下定时器的速度
if((snake.size()-2)%2==0){
delay=delay-100;
//注意我们带了delay 还需要设置该定时器 才会生效--
t.setDelay(delay);
}
8.运行主函数
public static void main(String[] args) {
JFrame frame = new JFrame("贪吃蛇");
frame.setBounds(0, 0, xWidth * unit, yWidth * unit);
MainPanel sn = new MainPanel();
frame.add(sn);//顶层容器去放中间容器
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
//如果要让键盘事件生效,需要让MainPanel获取焦点
sn.setFocusable(true);
}
}
总结*:通过本次项目,让我见识到了Java的swing类的强大,对Java的学习也充满了信心,但是在编程的过程中也意识到了自己实际开发的思维还不够成熟,知识只停留于表面,还需要多多开发项目*