GUI编程实战--贪吃蛇
GUI编程实战--贪吃蛇
参考:遇见狂神说
界面绘制
- 帧:如果时间片足够小,就是动画,一秒30帧。连起来是动画,拆开是静态的图片
- 键盘监听
- 定时器 Timer
package com.ssl.Snake;
import javax.swing.*;
//游戏的主启动类
public class StartGame {
public static void main(String[] args) {
JFrame frame = new JFrame("基于java-GUI的贪吃蛇小游戏");
frame.setBounds(50,50,900,800);
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false); //大小不可变
//正常游戏界面都应该在面板上!
frame.add(new GamePanel());
}
}
package com.ssl.Snake;
import javax.swing.*;
import java.net.URL;
//数据中心
public class Data {
//相对定位 tx.jpg
//绝对定位 / 相当于当前项目
public static URL headerURL = Data.class.getResource("statics/header.png");
public static ImageIcon header = new ImageIcon(headerURL);
public static URL headURL = Data.class.getResource("statics/head.png");
public static ImageIcon head = new ImageIcon(headURL);
public static URL leftURL = Data.class.getResource("statics/left.png");
public static ImageIcon left = new ImageIcon(leftURL);
public static URL rightURL = Data.class.getResource("statics/right.png");
public static ImageIcon right = new ImageIcon(rightURL);
public static URL upURL = Data.class.getResource("statics/up.png");
public static ImageIcon up = new ImageIcon(upURL);
public static URL downURL = Data.class.getResource("statics/down.png");
public static ImageIcon down = new ImageIcon(downURL);
public static URL foodURL = Data.class.getResource("statics/food.png");
public static ImageIcon food = new ImageIcon(foodURL);
public static URL bodyURL = Data.class.getResource("statics/body.png");
public static ImageIcon body = new ImageIcon(bodyURL);
}
package com.ssl.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.security.Key;
import java.util.Random;
//游戏面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {
//定义蛇的数据结构
int length; //蛇的长度
int[] snakeX = new int[600]; //蛇的x坐标 25*25
int[] snakeY = new int[500]; //蛇的y坐标 25*25
//脑袋的初始方向
String fx;
//游戏当前状态 开始/停止
boolean isStart;
//游戏速度
int speed = 100;
//定时器
Timer timer = new Timer(speed,this); //100ms执行一次
//食物的坐标 x:25:850 y:150:725
int foodx;
int foody;
Random random = new Random();
//游戏失败
boolean isfall = false;
//成绩
int score;
//构造器
public GamePanel(){
init();
//获得焦点和键盘事件
this.setFocusable(true); //获得焦点事件
this.addKeyListener(this);
}
public void init(){
//初始化长度为3
length=3;
snakeX[0]=100; snakeY[0]=200; //脑袋坐标
snakeX[1]=75; snakeY[1]=200; //第一个身体
snakeX[2]=50; snakeY[2]=200; //第二个身体
fx = "R";
isStart = false;
speed=100;
timer.start();//定时器
//把食物随机放上
foodx = 25 + 25 * random.nextInt(34);
foody = 150 +25 * random.nextInt(24);
score = 0;
}
//绘制面板,游戏中所用东西都用这个画笔来画。
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //清屏,不用会闪烁
//绘制静态的面板
this.setBackground(Color.WHITE);
Data.head.paintIcon(this,g,0,0); //广告栏
g.fillRect(25,150,850,600);//默认的游戏界面
//画积分
g.setColor(Color.BLACK);
//设置字体
g.setFont(new Font("微软雅黑",Font.BOLD,20));
//放入字
g.drawString("长度:"+length,750,50);
g.drawString("得分:"+score,750,100);
//画食物
Data.food.paintIcon(this,g,foodx,foody);
//把小蛇画上去
//头 需要通过方向来判断
if(fx.equals("R")){
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if(fx.equals("L")){
Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if(fx.equals("U")){
Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if(fx.equals("D")){
Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
}
//身体
for(int i=1;i<length;i++){
Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
}
//游戏状态
if(!isStart){
g.setColor(Color.WHITE);
//设置字体
g.setFont(new Font("微软雅黑",Font.BOLD,40));
//放入字
g.drawString("按下空格开始游戏",300,400);
}
//如果游戏失败
if(isfall){
g.setColor(Color.RED);
//设置字体
g.setFont(new Font("微软雅黑",Font.BOLD,40));
//放入字
g.drawString("游戏失败,按下空格重新开始",150,400);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//键盘的监听事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode(); //获得键盘的按键
if(keyCode == KeyEvent.VK_SPACE){ //如果按下的是空格键
if(isfall){
//重新开始
isfall = false;
init();
}else{
isStart = !isStart;
}
repaint();
}
//小蛇移动
if(keyCode == KeyEvent.VK_UP && (fx.equals("R")||fx.equals("L")) ){
fx="U";
}else if(keyCode == KeyEvent.VK_DOWN && (fx.equals("R")||fx.equals("L"))){
fx="D";
}else if(keyCode == KeyEvent.VK_LEFT && (fx.equals("U")||fx.equals("D")) ){
fx="L";
}else if(keyCode == KeyEvent.VK_RIGHT && (fx.equals("U")||fx.equals("D"))){
fx="R";
}
}
@Override
public void keyReleased(KeyEvent e) {
}
//事件监听 通过固定的事件刷新 1s 10次
@Override
public void actionPerformed(ActionEvent e) {
//如果游戏是开始状态,就让小蛇动起来
if(isStart && isfall == false){
//吃食物
if(snakeX[0]==foodx && snakeY[0]==foody){
length++;
foodx = 25 + 25 * random.nextInt(34);
foody = 150 +25 * random.nextInt(24);
//变速
speed= speed - 1;
score+=10;
}
//身体的移动 后一节变到前一节
for(int i=length -1;i>0;i--){
snakeX[i]=snakeX[i-1];
snakeY[i]=snakeY[i-1];
}
//右移
if(fx.equals("R")){
snakeX[0]=snakeX[0]+25;
}else if(fx.equals("L")){
snakeX[0]=snakeX[0]-25;
}else if(fx.equals("U")){
snakeY[0]=snakeY[0]-25;
}else if(fx.equals("D")){
snakeY[0]=snakeY[0]+25;
}
//边界判断
if(snakeX[0]>850){
snakeX[0]=25;
}
if(snakeX[0]<25){
snakeX[0]=850;
}
if(snakeY[0]>725){
snakeY[0]=150;
}
if(snakeY[0]<150){
snakeY[0]=725;
}
//失败判定,撞到自己就算失败
for(int i=1;i<length;i++){
if(snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i])
isfall=true;
}
repaint();
}
if(speed<50){
speed=50;
}
timer.start();//定时器
}
}
GUI编程实战--贪吃蛇的更多相关文章
- GUI简单实战——贪吃蛇
将前面学到的GUI基础知识完成实战,完成一个简单的贪吃蛇项目 项目功能 用键盘上下左右实现贪吃蛇的自动移动 贪吃蛇吃到食物后,长度加一,分数加一 贪吃蛇吃到自己的身体,则游戏结束 按空格键实现游戏的暂 ...
- 使用Java的GUI技术实现 “ 贪吃蛇 ” 游戏
详细教程: 使用Java的GUI技术实现 " 贪吃蛇 " 游戏_IT打工酱的博客-CSDN博客
- Linux Curses编程实现贪吃蛇
curses库 简单而言,提供UNIX中多种终端 操作光标和显示字符 的接口.我们常见的vi就是使用curses实现的.现在一般都用ncurses库. Linux下curses函数库 Linux ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(六) - 蛇实现
这一篇是关于设置蛇的属性的,接上一篇(五). 设置蛇的速度,很简单,只要不是负数就行了. void SNK_SetSnakeSpeed(Snake *snake, int speed) { ) sna ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(四) - 食物实现
由于食物是贪吃蛇游戏中最简单的一部分,而且和其他部分关联性不强,基本上是一个独立的部分,所以我打算先实现它. 我的想法是食物必须在世界中才能被创造出来,也就是说,先有世界再有食物,所以我得先判断世界是 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(三) - 蛇定义
蛇是这个游戏的主角,要实现的功能也是最复杂的一个.因为蛇不止有属性,还有行为.它会动,还会吃东西,还会长大!而且还会死!这是很要命的.我一向看不懂复杂的代码,也写不出复杂的代码.所以对于蛇,我很纠结, ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(二) - 食物定义
游戏中的食物没有那么多复杂属性,特别是贪吃蛇游戏中,我把食物看待的很简单: 1. 它必须属于世界,才能出现在世界.不可能一个不属于世界的食物,出现在世界中:但是可能存在着一个食物,它属于世界,但是却没 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(一) - 世界定义
每个游戏都有一个很明确的目的或者说游戏主题,贪吃蛇的目的很明确:蛇找到并吃掉食物.只有目的是很无聊的,算不上一个好游戏.所以设计者增加了创意:1. 吃掉食物后蛇会增长:2. 吃掉食物后分数会增加.有些 ...
- Java 用java GUI写一个贪吃蛇小游戏
目录 主要用到 swing 包下的一些类 上代码 游戏启动类 游戏数据类 游戏面板类 代码地址 主要用到 swing 包下的一些类 JFrame 窗口类 JPanel 面板类 KeyListener ...
- 第70讲:Scala界面GUI编程实战详解
今天又学习了王家林老师的scala学习讲座第70讲,关于scala的界面编程,让我们来初步学习一下scala中界面编程的过程. 信息来源于 DT大数据梦工厂微信公众账号:DT_Spark 关注微信账号 ...
随机推荐
- Docker学习——Dockerfile 指令详解(五)
我们已经介绍了 FROM (指定基础镜像) , RUN(执行命令) ,还提及了 COPY , ADD ,其实 Dockerfile 功能很强大,它提供了十多个指令.下面我们继续讲解其他的指令. COP ...
- C++ OnlineJudge
基本输入输出 1.接收多行数据,直到文件末尾 1 #include <iostream> 2 //#include <bits/stdc++.h> 3 #include < ...
- if __name__ == '__main__':中的语句无法执行
在pycarm中我们用了pytest或unittest框架写测试用例,我们如果我们在最后加上if name == 'main':,如以下代码所示.最后我们右键点击运行的时候是不会执行**if name ...
- AI基本知识
一.什么是flops 对flops有疑惑,首先得先捋清这个概念: FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为 ...
- 【loguru】Python简单的日志管理模块
简介 在部署一些定时运行或者长期运行的任务时,为了留存一些导致程序出现异常或错误的信息,通常会才用日志的方式来进行记录这些信息. 在 Python 中用到日志记录,那就不可避免地会用到内置的 logg ...
- int 和vachar后面的数字代表的含义
在创建数据表的时候,我们经常会给每一个字段设置一个长度,例如:int(5).varchar(10) 等等,但是他们代表的意思是什么呢?是该列允许存储值的最大宽度吗? 场景1:为什么我设置成 int(1 ...
- node后台项目所需中间件梳理
0.nodemon 全局工具,监听项目文件变动,并自动重启项目 一.node内置模块 1.fs fs.readFile() 读取指定文件中的内容fs.writeFile() 向指定的文件中写入内容 ...
- window10下,命令行与端口
netstat -ano 查看端口情况 tasklist|findstr "9220" 通过PID号"9220"查看对应端口被什么进程占用了 netstat - ...
- 量化交易 - matplotlib画candle图
需要mplfinance包 pip install mplfinance --upgrade from matplotlib import style import pandas as pd im ...
- Linux 常用杂项命令
1.查看监听端口的进程名称 lsof -i:[3306] # 3306是端口名称 2.查看PID进程文件的位置 ls -al /proc/51955/exe # 51955是进程PID