创建GameWin.java
package com.sxt;
import com.sxt.obj.BodyObj;
import com.sxt.obj.FoodObj;
import com.sxt.obj.HeadObj;
import com.sxt.utils.GameUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
public class GameWin extends JFrame {
//游戏状态 0.未开始 1.游戏中 2.暂停 3.失败 4.通关 5.失败后重新开始 6.下一关
public static int state = 0;
//分数
public int score = 0;
//定义双缓存图片
Image offScreenImage = null;
//窗口宽高
int winWidth = 800;
int winHeight = 600;
//蛇头对象
public HeadObj headObj = new HeadObj(GameUtils.rightImg,60,570,this);
//蛇的身体集合
public List<BodyObj> bodyObjList = new ArrayList<>();
//食物
public FoodObj foodObj = new FoodObj().getFood();
public void launch(){
//设置窗口是否可见
this.setVisible(true);
//设置窗口的大小
this.setSize(winWidth,winHeight);
//设置窗口的位置在屏幕上居中
this.setLocationRelativeTo(null);
//设置窗口的标题
this.setTitle("尚学堂贪吃蛇");
//蛇身体的初始化
bodyObjList.add(new BodyObj(GameUtils.bodyImg,30,570,this));
bodyObjList.add(new BodyObj(GameUtils.bodyImg,0,570,this));
//键盘事件
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE){
switch (state){
case 0:
//未开始
state = 1;
break;
case 1:
//游戏中
state = 2;
repaint();
break;
case 2:
//游戏暂停
state = 1;
break;
case 3:
//失败后重新开始
state = 5;
break;
case 4:
//下一关
state = 6;
break;
default:
break;
}
}
}
});
while (true){
if (state == 1){
//游戏中才调用
repaint();
}
//失败重启
if (state == 5){
state = 0;
resetGame();
}
//通关下一关
if (state == 6 && GameUtils.level != 3){
state = 1;
GameUtils.level++;
resetGame();
}
try {
//1秒1000毫秒
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void paint(Graphics g) {
//初始化双缓存图片
if (offScreenImage == null){
offScreenImage = this.createImage(winWidth,winHeight);
}
//获取图片对应的graphics对象
Graphics gImage = offScreenImage.getGraphics();
//灰色背景
gImage.setColor(Color.gray);
gImage.fillRect(0,0,winWidth,winHeight);
//网格线
gImage.setColor(Color.black);
//横线
for (int i = 0; i <= 20 ; i++) {
//横线
gImage.drawLine(0,i * 30,600,i * 30);
//竖线
gImage.drawLine(i * 30,0,i * 30,600);
}
//绘制蛇身体
for (int i = bodyObjList.size() - 1; i >= 0; i--) {
bodyObjList.get(i).paintSelf(gImage);
}
//绘制蛇头
headObj.paintSelf(gImage);
//食物绘制
foodObj.paintSelf(gImage);
//关卡
GameUtils.drawWord(gImage,"第"+GameUtils.level+"关",Color.orange,40,650,260);
//分数绘制
GameUtils.drawWord(gImage,score + " 分",Color.BLUE,50,650,330);
//绘制提示语
gImage.setColor(Color.gray);
prompt(gImage);
//将双缓存图片绘制到窗口中
g.drawImage(offScreenImage,0,0,null);
}
//绘制提示语
void prompt(Graphics g){
//未开始
if (state == 0){
g.fillRect(120,240,400,70);
GameUtils.drawWord(g,"按下空格键开始游戏",Color.yellow,35,150,290);
}
//暂停
if (state == 2){
g.fillRect(120,240,400,70);
GameUtils.drawWord(g,"按下空格键继续游戏",Color.yellow,35,150,290);
}
//失败
if (state == 3){
g.fillRect(120,240,400,70);
GameUtils.drawWord(g,"失败,按空格重新开始",Color.red,35,150,290);
}
//通关
if (state == 4){
g.fillRect(120,240,400,70);
if (GameUtils.level == 3){
GameUtils.drawWord(g,"达成条件,游戏通关",Color.green,35,150,290);
} else {
GameUtils.drawWord(g,"达成条件,空格下一关",Color.green,35,150,290);
}
}
}
//游戏重置
void resetGame(){
//关闭当前窗口
this.dispose();
//开启新窗口
String[] args = {};
main(args);
}
public static void main(String[] args) {
GameWin gameWin = new GameWin();
gameWin.launch();
}
}
身体:BodyObj
package com.sxt.obj;
import com.sxt.GameWin;
import java.awt.*;
public class BodyObj extends GameObj {
public BodyObj(Image img, int x, int y, GameWin frame) {
super(img, x, y, frame);
}
@Override
public void paintSelf(Graphics g) {
super.paintSelf(g);
}
@Override
public String toString() {
return "BodyObj{" +
"img=" + img +
", x=" + x +
", y=" + y +
'}';
}
}
食物:FoodObj
package com.sxt.obj;
import com.sxt.GameWin;
import com.sxt.utils.GameUtils;
import java.awt.*;
import java.util.Random;
public class FoodObj extends GameObj {
//随机
Random r = new Random();
public FoodObj() {
super();
}
public FoodObj(Image img, int x, int y, GameWin frame) {
super(img, x, y, frame);
}
//获取食物
public FoodObj getFood(){
return new FoodObj(GameUtils.foodImg,r.nextInt(20) * 30,(r.nextInt(19) + 1) * 30,this.frame);
}
@Override
public void paintSelf(Graphics g) {
super.paintSelf(g);
}
}
面板:GameObj
package com.sxt.obj;
import com.sxt.GameWin;
import java.awt.*;
public class GameObj {
//图片
Image img;
//坐标
int x;
int y;
//宽高
int width = 30;
int height = 30;
//窗口类的引用
GameWin frame;
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = img;
}
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 int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public GameWin getFrame() {
return frame;
}
public void setFrame(GameWin frame) {
this.frame = frame;
}
public GameObj() {
}
public GameObj(Image img, int x, int y, GameWin frame) {
this.img = img;
this.x = x;
this.y = y;
this.frame = frame;
}
public GameObj(Image img, int x, int y, int width, int height, GameWin frame) {
this.img = img;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.frame = frame;
}
//绘制自身
public void paintSelf(Graphics g){
g.drawImage(img,x,y,null);
}
}
头部:HeadObj
package com.sxt.obj;
import com.sxt.GameWin;
import com.sxt.utils.GameUtils;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class HeadObj extends GameObj {
//方向 up down left right
private String direction = "right";
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
public HeadObj(Image img, int x, int y, GameWin frame) {
super(img, x, y, frame);
//键盘监听事件
this.frame.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
changeDirection(e);
}
});
}
//控制移动方向 w -up a - left d -right s-down
public void changeDirection(KeyEvent e){
switch (e.getKeyCode()){
case KeyEvent.VK_A:
if (!"right".equals(direction)){
direction = "left";
img = GameUtils.leftImg;
}
break;
case KeyEvent.VK_D:
if (!"left".equals(direction)){
direction = "right";
img = GameUtils.rightImg;
}
break;
case KeyEvent.VK_W:
if (!"down".equals(direction)){
direction = "up";
img = GameUtils.upImg;
}
break;
case KeyEvent.VK_S:
if (!"up".equals(direction)){
direction = "down";
img = GameUtils.downImg;
}
break;
default:
break;
}
}
//蛇的移动
public void move(){
//蛇身体的移动
java.util.List<BodyObj> bodyObjList = this.frame.bodyObjList;
for (int i = bodyObjList.size() - 1; i >= 1; i--) {
bodyObjList.get(i).x = bodyObjList.get(i - 1).x;
bodyObjList.get(i).y = bodyObjList.get(i - 1).y;
//蛇头与身体的碰撞判断
if (this.x == bodyObjList.get(i).x && this.y == bodyObjList.get(i).y){
//失败
GameWin.state = 3;
}
}
bodyObjList.get(0).x = this.x;
bodyObjList.get(0).y = this.y;
//蛇头的移动
switch (direction){
case "up":
y -= height;
break;
case "down":
y += height;
break;
case "left":
x -= width;
break;
case "right":
x += width;
default:
break;
}
}
@Override
public void paintSelf(Graphics g) {
super.paintSelf(g);
//蛇吃食物
FoodObj food = this.frame.foodObj;
//身体最后一节的坐标
Integer newX = null;
Integer newY = null;
if (this.x == food.x && this.y == food.y){
this.frame.foodObj = food.getFood();
//获取蛇身的最后一个元素
BodyObj lastBody = this.frame.bodyObjList.get(this.frame.bodyObjList.size() - 1);
newX = lastBody.x;
newY = lastBody.y;
//分数+1
this.frame.score++;
}
//通关判断
if (this.frame.score >= 10){
//通关
GameWin.state = 4;
}
move();
//move结束后,新的bodyObj对象添加到bodyObjList
if (newX != null && newY != null){
this.frame.bodyObjList.add(new BodyObj(GameUtils.bodyImg,newX,newY,this.frame));
}
//越界处理
if (x < 0){
x = 570;
} else if (x > 570){
x = 0;
} else if (y < 30){
y = 570;
}else if (y > 570){
y = 30;
}
}
@Override
public String toString() {
return "HeadObj{" +
"img=" + img +
", x=" + x +
", y=" + y +
'}';
}
}
GameUtils
package com.sxt.utils;
import java.awt.*;
public class GameUtils {
//蛇头
public static Image upImg = Toolkit.getDefaultToolkit().getImage("img/up.png");
public static Image downImg = Toolkit.getDefaultToolkit().getImage("img/down.png");
public static Image leftImg = Toolkit.getDefaultToolkit().getImage("img/left.png");
public static Image rightImg = Toolkit.getDefaultToolkit().getImage("img/right.png");
//蛇身
public static Image bodyImg = Toolkit.getDefaultToolkit().getImage("img/body.png");
//食物
public static Image foodImg = Toolkit.getDefaultToolkit().getImage("img/food.png");
//关卡
public static int level = 1;
//绘制文字
public static void drawWord(Graphics g,String str,Color color,int size,int x,int y){
g.setColor(color);
g.setFont(new Font("仿宋",Font.BOLD,size));
g.drawString(str,x,y);
}
}