package com.zcz.view;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import com.zcz.model.DirectEnum;
import com.zcz.model.GameLogic;
import com.zcz.model.Location;
import com.zcz.model.SnakeBodyPoint;
import com.zcz.utils.ThreadUtils;
/**
* The game panel.
*
* @author zhangchizhan
* @since 2020/12/8
*/
public class GamePanel extends JPanel implements Runnable, KeyListener {
private static final long serialVersionUID = 629752198065812670L;
GameLogic gameLogic;
int panelWidth, panelHeight;
int pointWidth, pointHeight;
boolean gameIsRunning;
boolean showGameOverLabel;
int moveSpeed;
boolean speedWaitToChange;
public GamePanel(int panelWidth, int panelHeight, int horizontalGrids, int verticalGrids) {
super();
this.moveSpeed = 1;
this.speedWaitToChange = false;
this.gameIsRunning = false;
this.showGameOverLabel = false;
this.panelWidth = panelWidth;
this.panelHeight = panelHeight;
this.pointWidth = (int)(panelWidth / horizontalGrids);
this.pointHeight = (int)(panelHeight / verticalGrids);
this.gameLogic = new GameLogic(horizontalGrids, verticalGrids);
gameLogic.init();
}
@Override
public void run() {
gameIsRunning = true;
while (gameIsRunning) {
// Check whether the game is over.
if (gameLogic.checkIfGameOver()) {
gameIsRunning = false;
showGameOverLabel = true;
break;
}
// Expand snake body if its head can attach the next point or step the snake body.
if (gameLogic.checkCanExpand()) {
gameLogic.expandBody();
gameLogic.genDefaultNextPoint();
} else {
gameLogic.stepSnakeBody();
}
// Repaint the screen. This function will automatically call function "paint()".
repaint();
ThreadUtils.sleep((long)(300 / moveSpeed));
}
// Show game over screen. The game over label will keep twinkling.
while (true) {
repaint();
this.showGameOverLabel = !this.showGameOverLabel;
ThreadUtils.sleep(500);
}
}
public void paint(Graphics g) {
super.paint(g);
drawBackground(g);
if (gameIsRunning) {
drawSnake(g);
} else {
drawGameOver(g);
}
}
private void drawBackground(Graphics g) {
g.setColor(new Color(238, 232, 170));
g.fillRect(0, 0, panelWidth, panelHeight);
}
private void drawSnake(Graphics g) {
// Draw snake body.
g.setColor(Color.GREEN);
for(SnakeBodyPoint sbp : gameLogic.getSnakeBodyPoints()) {
drawPoint(g, sbp.getLocation());
}
// Draw the next point.
g.setColor(Color.RED);
drawPoint(g, gameLogic.getNextPoint().getLocation());
}
private void drawPoint(Graphics g, Location loc) {
g.fill3DRect(
loc.width * pointWidth,
loc.height * pointHeight,
pointWidth, pointHeight,
false
);
}
private void drawGameOver(Graphics g) {
if (showGameOverLabel) {
// Show game over label.
g.setColor(new Color(255, 20, 147));
g.setFont(new Font("Times New Roman", Font.BOLD, 50));
g.drawString("GAME OVER!", 250, 380);
}
g.setColor(Color.BLACK);
g.setFont(new Font("Times New Roman", Font.BOLD, 20));
g.drawString("Press any key to exit...", 300, 500);
}
@Override
public void keyPressed(KeyEvent arg0) {
if (!gameIsRunning) return;
boolean directChanges = false;
SnakeBodyPoint head = gameLogic.getSnakeHead();
DirectEnum headLastMoveDirect = head.getLastMoveDirection();
if(arg0.getKeyCode() == KeyEvent.VK_UP && headLastMoveDirect != DirectEnum.DOWN) {
// up
head.setDirection(DirectEnum.UP);
directChanges = true;
}
else if(arg0.getKeyCode() == KeyEvent.VK_DOWN && headLastMoveDirect != DirectEnum.UP) {
// down
head.setDirection(DirectEnum.DOWN);
directChanges = true;
}
else if(arg0.getKeyCode() == KeyEvent.VK_LEFT && headLastMoveDirect != DirectEnum.RIGHT) {
// left
head.setDirection(DirectEnum.LEFT);
directChanges = true;
}
else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT && headLastMoveDirect != DirectEnum.LEFT) {
// right
head.setDirection(DirectEnum.RIGHT);
directChanges = true;
}
if (directChanges) {
if (speedWaitToChange) {
moveSpeed = 3;
} else {
speedWaitToChange = true;
}
}
}
@Override
public void keyReleased(KeyEvent arg0) {
moveSpeed = 1;
speedWaitToChange = false;
}
@Override
public void keyTyped(KeyEvent arg0) {
if (!gameIsRunning) {
System.exit(0);
} else {
keyPressed(arg0);
keyReleased(arg0);
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
资源推荐
资源详情
资源评论
收起资源包目录
Java入门贪吃蛇小游戏.zip (25个子文件)
ori_code_game
.classpath 386B
.settings
org.eclipse.jdt.core.prefs 584B
org.eclipse.core.resources.prefs 53B
org.eclipse.core.runtime.prefs 50B
src
com
zcz
utils
ThreadUtils.java 228B
RandomUtils.java 494B
view
GameWindow.java 947B
GamePanel.java 4KB
model
GameLogic.java 3KB
SnakeBodyPoint.java 1KB
DirectEnum.java 83B
Location.java 824B
main
Main.java 177B
img
GreedySnake.png 135KB
bin
.gitignore 6B
com
zcz
utils
ThreadUtils.class 579B
RandomUtils.class 752B
view
GamePanel.class 4KB
GameWindow.class 1KB
model
DirectEnum.class 1KB
Location.class 1KB
SnakeBodyPoint.class 2KB
GameLogic.class 4KB
main
Main.class 496B
.project 370B
共 25 条
- 1
资源评论
毕业小助手
- 粉丝: 2747
- 资源: 5583
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 7fe9198d9e3a020dd32b09bda2cdd7ab_1731557932240_1
- VaM_Updater.zip
- C#MVC5+EasyUI企业快速开发框架源码 BS开发框架源码数据库 SQL2012源码类型 WebForm
- zblog站群:zblog seo站群高收录排名全地域霸屏
- 【安卓毕业设计】数独联网对战APP源码(完整前后端+mysql+说明文档).zip
- 【安卓毕业设计】Android天气小作业源码(完整前后端+mysql+说明文档).zip
- 【安卓毕业设计】群养猪生长状态远程监测源码(完整前后端+mysql+说明文档).zip
- 【安卓毕业设计】奶牛管理新加功能源码(完整前后端+mysql+说明文档).zip
- C#.NET公墓陵园管理系统源码数据库 SQL2008源码类型 WebForm
- 作业这是作业文件这是作业
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功