自己完成的过程确很有意思,作为基础练习,进行了部分改进,以后或许会再次改进?
- 贪吃蛇头部不可与前进方向相反
- 增加了食物的数量和种类
SnakeInit
package com.thf.Snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
public class SnakeInit extends JPanel implements KeyListener, ActionListener {
private int[] SnakeX = new int[816];
private int[] SnakeY = new int[816];
private int[] FoodX = new int[3];
private int[] FoodY = new int[3];
private int FoodNum;
private int[] FoodKind = new int[3];
private int SnakeLength;
private boolean GameState;
String Direction01;
boolean isFail= false;
int score;
Timer timer = new Timer(100,this);
Random random = new Random();
public SnakeInit() {
init();
this.setFocusable(true);
this.addKeyListener(this);
timer.start();
}
public void init(){
GameState=false;//如果不在此将其初始化为false,则只需要按一次空格
SnakeLength = 3;
SnakeX[0] = 100; SnakeY[0] = 75;//蛇头坐标
SnakeX[1] = 75; SnakeY[1] = 75;//蛇的初始身体坐标
SnakeX[2] = 50; SnakeY[2] = 75;//蛇的初始身体坐标
Direction01= "right";
FoodNum = 3;
//产生食物的数量,种类和位置
for (int i = 0; i < FoodNum; i++) {
FoodX[i] = 25+25*random.nextInt(34);
//rand.nextInt(34);中的34是随机数的上限,产生的随机数为0-34的整数,不包括34。
FoodY[i] = 75+25*random.nextInt(24);
FoodKind[i] = random.nextInt(30);
}
score = 0;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.black);
g.setColor(Color.DARK_GRAY);
// 绘制外层矩形框
g.drawRect(25,75,850,600);
for(int i = 0; i < 34; i ++) {
// 绘制第i条竖直线
g.drawLine(50+25*i,75,50+25*i,675);
if(i<=23){
// 绘制第i条水平线
g.drawLine(25,100+25*i,875,100+25*i);
}
}
g.setColor(Color.DARK_GRAY);
g.drawRect(25,1,850,70);
//绘制食物
for (int i = 0; i <FoodNum ; i++) {
if(0<=FoodKind[i]&&FoodKind[i]<=26){
GameData.food.paintIcon(this,g,FoodX[i],FoodY[i]);
}else if(27<=FoodKind[i]&&FoodKind[i]<=28){
GameData.yellowFood.paintIcon(this,g,FoodX[i],FoodY[i]);//黄色食物
}else if(FoodKind[i]==29){
GameData.redFood.paintIcon(this,g,FoodX[i],FoodY[i]);//红色食物
}
}
//设定并绘制贪吃蛇的头部方向
if (Direction01.equals("right") ) {
GameData.right.paintIcon(this, g, SnakeX[0], SnakeY[0]);
}
if (Direction01.equals("left") ) {
GameData.left.paintIcon(this, g, SnakeX[0], SnakeY[0]);
}
if (Direction01.equals("up") ) {
GameData.up.paintIcon(this, g, SnakeX[0], SnakeY[0]);
}
if (Direction01.equals("down") ) {
GameData.down.paintIcon(this, g, SnakeX[0], SnakeY[0]);
}
//绘制贪吃蛇的身体
for (int i = 1; i < SnakeLength; i++) {
GameData.body.paintIcon(this, g, SnakeX[i], SnakeY[i]);
}
g.setColor(Color.DARK_GRAY);
g.setFont(new Font("仿宋",Font.PLAIN,15));
g.drawString("得分"+score,30,30);
g.drawString("长度"+SnakeLength,30,50);
g.drawString("蓝色食物分数+10,长度+1",150,30);
g.drawString("红色食物分数-10,长度-3",150,50);
g.drawString("黄色食物分数+100,长度+1",350,30);
//打印开始文字
/*
Font.PLAIN(普通)
Font.BOLD(加粗)
Font.ITALIC(斜体)
Font.BOLD+ Font.ITALIC(粗斜体)
*/
if(!GameState){
g.setColor(Color.lightGray);
g.setFont(new Font("仿宋",Font.BOLD,40));
g.drawString("按空格开始游戏",300,400);
} else if (isFail) {
g.setColor(Color.lightGray);
g.setFont(new Font("仿宋",Font.BOLD,40));
g.drawString("按空格重新开始游戏",300,400);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//按键监听
@Override
public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();
if (keycode == KeyEvent.VK_SPACE) {
if(isFail){
//如果isFail的状态改变为true,则令其重新为false,并且初始化所有数据
isFail=false;
init();
}else {
GameState = !GameState;
}
repaint();
}
if(GameState){
if(keycode == KeyEvent.VK_UP||keycode == KeyEvent.VK_W){
if(Direction01.equals("down")){
Direction01 = "down";
}else{
Direction01 = "up";
}
}else if(keycode == KeyEvent.VK_DOWN||keycode == KeyEvent.VK_S){
if(Direction01.equals("up")){
Direction01 = "up";
}else{
Direction01 = "down";
}
}else if(keycode == KeyEvent.VK_LEFT||keycode == KeyEvent.VK_A){
if(Direction01.equals("right")){
Direction01 = "right";
}else{
Direction01 = "left";
}
}else if(keycode == KeyEvent.VK_RIGHT||keycode == KeyEvent.VK_D){
if(Direction01.equals("left")){
Direction01 = "left";
}else{
Direction01 = "right";
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
//监听事件
@Override
public void actionPerformed(ActionEvent e) {
//绘制食物
if(GameState&&!isFail){
for (int i = 0; i <FoodNum ; i++) {
if(SnakeX[i]==FoodX[i]&&SnakeY[i]==FoodY[i]&&FoodKind[i]>=0&&FoodKind[i]<=26){
//蓝色食物分数+10,长度+1
SnakeLength++;
score+=10;
FoodX[i] = 25+25*random.nextInt(34);
FoodY[i] = 75+25*random.nextInt(24);
FoodKind[i] =random.nextInt(30);
}else if(SnakeX[i]==FoodX[i]&&SnakeY[i]==FoodY[i]&&FoodKind[i]>=27&&FoodKind[i]<=28){
//黄色食物分数+100,长度+1
SnakeLength++;
score+=100;
FoodX[i] = 25+25*random.nextInt(34);
FoodY[i] = 75+25*random.nextInt(24);
FoodKind[i] =random.nextInt(30);
}else if(SnakeX[i]==FoodX[i]&&SnakeY[i]==FoodY[i]&&FoodKind[i]==29){
//红色食物分数-10,长度-3
if((SnakeLength-=3)<=2){
SnakeLength=2;//保证贪吃蛇长度最低为2
}else {
SnakeLength-=3;
}
score-=10;
FoodX[i] = 25+25*random.nextInt(34);
FoodY[i] = 75+25*random.nextInt(24);
FoodKind[i] =random.nextInt(30);
}
}
//让蛇的身体随着时间变动,只适用于蛇的长度不变或者长度增加1
for (int i = SnakeLength-1; i >0; i--) {
SnakeX[i] = SnakeX[i-1];
SnakeY[i] = SnakeY[i-1];
}
if(Direction01.equals("right")){
//蛇的右边界判定
SnakeX[0] = SnakeX[0] + 25;
if(SnakeX[0]>850){
SnakeX[0]=25;
}
}else if(Direction01.equals("up")){
//蛇的上边界判定
SnakeY[0] = SnakeY[0] - 25;
if(SnakeY[0]<75){
SnakeY[0]=650;
}
}else if(Direction01.equals("down")){
//蛇的下边界判定
SnakeY[0] = SnakeY[0] + 25;
if(SnakeY[0]>650){
SnakeY[0]=75;
}
}else if(Direction01.equals("left")){
//蛇的左边界判定
SnakeX[0] = SnakeX[0] - 25;
if(SnakeX[0]<25){
SnakeX[0]=850;
}
}
//蛇的身体和头部碰撞导致的失败判定
for (int i = 1; i <SnakeLength ; i++) {
if(SnakeX[0]==SnakeX[i]&&SnakeY[0]==SnakeY[i]) {
isFail = true;
}
}
repaint();
}
}
}
GameData
package com.thf.Snake;
import javax.swing.*;
import java.net.URL;
public class GameData {
public static URL upURL = GameData.class.getResource("/com/thf/Image/up.png");
public static ImageIcon up =new ImageIcon(upURL);
public static URL downURL = GameData.class.getResource("/com/thf/Image/down.png");
public static ImageIcon down =new ImageIcon(downURL);
public static URL leftURL = GameData.class.getResource("/com/thf/Image/left.png");
public static ImageIcon left =new ImageIcon(leftURL);
public static URL rightURL = GameData.class.getResource("/com/thf/Image/right.png");
public static ImageIcon right =new ImageIcon(rightURL);
public static URL foodURL = GameData.class.getResource("/com/thf/Image/food.png");
public static ImageIcon food =new ImageIcon(foodURL);
public static URL redFoodURL = GameData.class.getResource("/com/thf/Image/redFood.png");
public static ImageIcon redFood =new ImageIcon(redFoodURL);
public static URL yellowFoodURL = GameData.class.getResource("/com/thf/Image/yellowFood.png");
public static ImageIcon yellowFood =new ImageIcon(yellowFoodURL);
public static URL bodyURL = GameData.class.getResource("/com/thf/Image/body.png");
public static ImageIcon body =new ImageIcon(bodyURL);
}
附带图片资源
right.jpg
redfood.jpg
up.jpg
left.jpg
food.jpg
down.jpg
body.jpg
yellowfood.jpg