java贪吃蛇小程序源代码_贪吃蛇java小程序

class Control代码:

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

public class Control implements KeyListener { //对键盘进行监听

SnakeModel snake=null;

public Control(SnakeModel snake) {

this.snake=snake;

}

@Override

public void keyPressed(KeyEvent e) {

if(e.getKeyCode()==KeyEvent.VK_UP){

snake.changeDirection(SnakeModel.UP);

}

if(e.getKeyCode()==KeyEvent.VK_DOWN){ //监听按键↓,向下移动

snake.changeDirection(SnakeModel.DOWN);

}

if(e.getKeyCode()==KeyEvent.VK_LEFT){ //监听按键←,向左移动

snake.changeDirection(SnakeModel.LEFT);

}

if(e.getKeyCode()==KeyEvent.VK_RIGHT){ //监听按键↑,向上移动

snake.changeDirection(SnakeModel.RIGHT);

}

if(e.getKeyCode()==KeyEvent.VK_RIGHT){ //监听按键→,向右移动

snake.changeDirection(SnakeModel.RIGHT);

}

if(e.getKeyCode()==KeyEvent.VK_R){//监听按键R,重置

snake.reStart();

}

}

@Override

public void keyTyped(KeyEvent e) {}

@Override

public void keyReleased(KeyEvent e) {}

}

class SnakeModel 代码:

import java.awt.Canvas;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.Random;

import javax.swing.Timer;

import cn.hncu.xh.Snake.snakePoint.point;

/*

* 思路: 利用动态数组装蛇模型,蛇身的点都只跟着蛇头(即:数组的第一个元素)动,

* 每 repaint()一次,就把动态数组里面的蛇全部数出来。

* 每吃一个食物时,就添加在蛇头,蛇头往后移动一步,然后蛇身跟着移动。

* 注意:在蛇吃到食物时,要避免捆绑!!!

*/

public class SnakeModel extends Canvas implements ActionListener {

private snakePoint[] snakePoint; //装蛇的数组

private static Timer timer; //定时器

private static int score = 0; //分数

private int Dx, Dy;// 蛇头所在坐标

private int Px, Py; //食物的坐标

static final int LEFT = 1;

static final int UP = 2;

static final int DOWN = 4;

static final int RIGHT = 3;

int direction = 4; //初始方向为向下移动

boolean isFrist = true; //控制第一个食物的位置

boolean isOne = true; //控制每次刷新一次蛇只能按一次键盘

boolean food; //控制没吃到一个食物才去刷新食物的坐标

public SnakeModel(int delay) {// 构造蛇模型

this.snakePoint = new snakePoint[300]; // 用来装蛇头

snakePoint[1] = new snakePoint(100, 100);// 画蛇头

// 使用定时器

timer = new Timer(delay, this);

timer.start();

}

public static int getScore() { // 获取分数

return score;

}

class snakePoint { //蛇身(每条蛇由很多蛇身构成)

int x, y;

public snakePoint(int x, int y) {

this.x = x;

this.y = y;

}

snakePoint(snakePoint p) {

this.x = p.x;

this.y = p.y;

}

}

@Override

public void paint(Graphics g) {

//食物

creatFood();

// 每走一次就让数组自动移动一次

if (score != 0) {

for (int i = score + 2; i > 1; i--) {

snakePoint[i] = new snakePoint(snakePoint[i - 1]);

}

}

switch (direction) {// 判断蛇头的走向

case UP:

snakePoint[1].y -= 10;

break;

case DOWN:

snakePoint[1].y += 10;

break;

case LEFT:

snakePoint[1].x -= 10;

break;

case RIGHT:

snakePoint[1].x += 10;

break;

}

// 吃到了食物

//要考虑食物的坐标不可能与蛇头坐标重合

if (snakePoint[1].x <= Px + 7 && snakePoint[1].x >= Px - 5

&& snakePoint[1].y <= Py + 7 && snakePoint[1].y >= Py - 5) {

score++; // 分数加一

food = true; // 刷新食物

SnakeMain.re(); // 刷新分数

timer.setDelay((timer.getDelay() - 4) <= 0 ? 20

: timer.getDelay() - 4); //每次吃到食物后就会加速蛇的移动速度

// System.out.println(timer.getDelay());

// 吃掉一个食物后,在蛇头增加一个长度

for (int j = score + 1; j > 1; j--) {

snakePoint[j] = new snakePoint(snakePoint[j - 1]);

}

// 让蛇头往移动方向走一步

switch (direction) {// 判断蛇头的走向

case UP:

snakePoint[1].y -= 10;

break;

case DOWN:

snakePoint[1].y += 10;

break;

case LEFT:

snakePoint[1].x -= 10;

break;

case RIGHT:

snakePoint[1].x += 10;

break;

}

}

g.setColor(Color.RED);//食物为红色

g.fillRect(Px, Py, 10, 10);// 画食物

g.setColor(Color.BLACK);//蛇为黑色

// 画蛇,把蛇从数组中画出来

for (int i = 1; i <= score + 1; i++) {

g.fillRect(snakePoint[i].x, snakePoint[i].y, 10, 10);

}

}

private void creatFood() {

if (isFrist) {

Px = legal(380);// 获得合法的x值,

Py = legal(330);// 获得合法的y值,即与x组合成食物坐标后不在蛇身上

isFrist = false;

return;

}

// 下一个食物坐标

if (food) {

Px = legal(380);//同上

Py = legal(330);

food = false;

}

// System.out.println(Px);

// System.out.println(Py);

}

private int legal(int i) {

Random r = new Random(); //生成随机数

if (i == 380) { //生成食物的y坐标

while (true) {

int n = (r.nextInt(37) + 1) * 10;

for (int j = 1; j <= score + 1; j++) { //每次都要与蛇身进行匹配,避免食物出现在蛇身上;下同

if (snakePoint[j].x != n && j == (score + 1)) {

return n;

}

}

}

}

if (i == 330) { //生成食物的x坐标

while (true) {

int n = (r.nextInt(32) + 1) * 10;

for (int j = 1; j <= score + 1; j++) {

if (snakePoint[j].y != n && j == (score + 1)) {

return n;

}

}

}

}

return 0;

}

@Override

public void actionPerformed(ActionEvent e) {

isOver();// 判断是否结束游戏

repaint();

isOne = true;

// System.out.println(snakePoint[1].x+" "+snakePoint[1].y);

}

private void isOver() {

if (isCondition()) {// isCondition()//判断是否结束的所有条件放在里面

timer.stop();

SnakeMain.gameOver(); // 游戏结束,弹出对话框

}

}

private boolean isCondition() { //游戏结束的条件

// 出界(撞墙)

if (snakePoint[1].x <= 0 || snakePoint[1].x >= 380

|| snakePoint[1].y <= 0 || snakePoint[1].y >= 330) {

return true;

}

//蛇头吃到蛇身了

for (int i = 2; i <= score + 1; i++) {

if (snakePoint[1].x == snakePoint[i].x

&& snakePoint[1].y == snakePoint[i].y) {

return true;

}

}

return false;

}

public void changeDirection(int newDirection) { // 改变方向

if (direction % 2 != newDirection % 2 && isOne) {// 改变的方向不能与原来的方向相同或相反

direction = newDirection;

isOne = false;

}

}

public static void stop() {

timer.stop();

}

public static void start() {

timer.start();

}

//重置所有的数据

public void reStart(){

score=0;

direction = 4;

isFrist = true;

isOne = true;

food=false;

//snakePoint=null;

snakePoint[1].x=100;

snakePoint[1].y=100;

creatFood();

timer.start();

}

}

class SnakeMain 代码:

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class SnakeMain extends JFrame implements ActionListener {

private static JTextField scoreField;

private JButton stop,start;

public static void main(String[] args) {

new SnakeMain();

}

public SnakeMain() {

super("贪吃蛇");

this.setBounds(300, 100, 400, 400);

this.setDefaultCloseOperation(EXIT_ON_CLOSE);

this.setResizable(false);

JPanel p = new JPanel();

this.getContentPane().add(p, "North");

p.add(new JLabel("Score:"));

scoreField = new JTextField("0", 5);

scoreField.setEditable(false);

stop = new JButton("stop");

start = new JButton("start");

// 让这些组件丢失焦点

scoreField.setFocusable(false);

stop.setFocusable(false);

start.setFocusable(false);

//添加组件到面板p

p.add(scoreField);

p.add(stop);

p.add(start);

SnakeModel snake = new SnakeModel(400);// 500为刷新时间

this.getContentPane().add(snake); // 把蛇加入到面板中 (蛇的运行范围:0<=x<=380

// 0<=y<=330)

Control control = new Control(snake); // 控制蛇

// 进行监听

stop.addActionListener(this);

start.addActionListener(this);

this.addKeyListener(control);

// 显示

this.setVisible(true);

}

public static void re() { // 刷新分数框

scoreField.setText("" + SnakeModel.getScore());

}

public static void gameOver() {// 游戏结束

JOptionPane.showMessageDialog(null, "Game Over!!!");

}

@Override

public void actionPerformed(ActionEvent e) {

if (e.getSource() == stop) {

SnakeModel.stop();

}

if (e.getSource() == start) {

SnakeModel.start();

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值