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
资源评论
毕业小助手
- 粉丝: 2765
- 资源: 5583
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 英雄联盟(League of Legends, LOL)数据集,包含:英雄联盟比赛数据,英雄联盟选手数据(KDA,伤害数,承伤数,补刀等),英雄联盟对战情况数据
- Python爬虫开发与实战-从入门到精通
- Spring项目集成FastDFS文件服务器代码
- 江科大STM32学习笔记(上)-最终版本
- 2024 Java offer 收割指南.pdf
- 12万字 java 面经总结.pdf
- SpringMVC面试题.pdf
- JAVA核心面试知识整理.pdf
- SpringCloud面试题.pdf
- SpringBoot面试题.pdf
- Spring面试专题.pdf
- 并发编程基础知识.pdf
- 代码随想录知识星球精华(最强八股文)第五版(Go篇).pdf
- 代码随想录知识星球精华(最强八股文)第五版(概述).pdf
- 代码随想录知识星球精华(最强八股文)第五版(面经篇).pdf
- 代码随想录知识星球精华(最强八股文)第五版(星球资源篇).pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功