news 2026/10/9 2:23:19

Java学习进程12

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java学习进程12

线程游戏的实现 2

关于缓冲区

经过线程游戏的初步设计,直接在窗口分层绘制图像时,画面频繁闪烁;是因为分层绘图按代码顺序逐次刷新,清屏与重绘交替出现,形成视觉频闪;因此引入图像缓冲区,所有图层预先绘制至缓冲画布,整帧绘制完毕后一次性输出至窗口,解决闪烁问题。

1.缓冲初始化
所有画面元素都调用 buffG.xxx() 绘制,不要用窗口原始画笔g

// 创建缓冲图片,尺寸与游戏窗口一致BufferedImagebufferedImage=newBufferedImage(800,800,BufferedImage.TYPE_INT_BGR);// 获取缓冲画布画笔,所有绘图统一使用 buffGGraphicsbuffG=bufferedImage.getGraphics();

2.最终统一刷新每一帧末尾

// 整帧统一绘制完毕,将缓冲图片贴到窗口g.drawImage(bufferedImage,0,0,null);
实现背景图片的滚动效果

准备两张相同的背景图,一张放在可视窗口,一张紧贴在第一张图片正上方,两张同步向下移动,当任意一张图片完全滑出屏幕底部,立刻将它挪到另一张图片的头顶循环往复,实现无限向下滚动

1.设置滚动成员变量

// 两张背景图相同publicImageback;publicImageback2;// 背景纵向偏移publicintbgY=0;// 滚动速度数值越大,滚动越快publicintbgSpeed=2;// 窗口宽高和画布一致publicfinalintWIN_HEIGHT=800;

2.构造器加载背景

back=newImageIcon("resources\\Starrysky.JPG").getImage();back2=newImageIcon("resources\\Starrysky.JPG").getImage();

3.坐标更新

// 若暂停游戏,不更新角色、子弹位置,仍绘制当前画面if(!listener.isPause){bgY+=bgSpeed;// 图片滑出屏幕底部,坐标归零循环if(bgY>=WIN_HEIGHT){bgY=0;}}

4.两张图片的拼接

// 第一张正常下移buffG.drawImage(back,0,bgY,null);// 第二张紧贴第一张正上方,无缝衔接buffG.drawImage(back2,0,bgY-WIN_HEIGHT,null);
资源根导入照片
项目文件夹 └── src ├── com/xxx/各类Java代码包(GameThread、GameUI等) └── resources 【必须新建resources文件夹,放在src同级】 └── Starrysky.JPG

代码不用写电脑C盘/D盘完整路径,使用资源相对根路径

publicGameThread(Graphicsg,MPlanemp,ArrayList<Bullet>bullets,GameListenerlistener){this.g=g;this.mp=mp;this.bullets=bullets;this.listener=listener;back=newImageIcon("resources\\Starrysky.JPG").getImage();back2=newImageIcon("resources\\Starrysky.JPG").getImage();//第二张初始放在第一张正上方bgY=0;}
实现图片按钮

依靠缓冲画布绘制按钮图片,配合鼠标监听坐标判断点击区域,实现游戏内嵌图片按钮,用于开始界面切换游戏画面
1.设置按钮相关成员变量

// 开始按钮图片对象publicImageIconstartImage;// 按钮绘制范围常量,与绘图坐标匹配privatefinalintbtnX=200;privatefinalintbtnY=600;privatefinalintbtnW=200;privatefinalintbtnH=100;

2.构造器加载按钮图片

startImage=newImageIcon("resources\\Start Game Button.PNG");

3.画布绘制按钮图片

// 在缓冲画布绘制按钮图片,确定按钮显示位置与大小buffG.drawImage(startImage.getImage(),200,600,200,100,null);

4.鼠标点击坐标判定逻辑

// 获取鼠标点击坐标,判断是否落在按钮矩形范围内intmx=e.getX();intmy=e.getY();booleanhitBtn=mx>=btnX&&mx<=btnX+btnW&&my>=btnY&&my<=btnY+btnH;// 仅在开始界面、未创建玩家时点击生效,切换游戏画面if(hitBtn&&gt.start&&mp==null){mp=newMPlane(350,600);gt.setMp(mp);gt.isStart(false);}

5.窗口绑定全套鼠标监听

// 绑定鼠标移动监听、鼠标点击监听gamePanel.addMouseMotionListener(listener);gamePanel.addMouseListener(listener);
添加背景音乐

Java原生音频类 Clip 仅支持 .wav 无损音频文件,通过自定义音频工具类实现多首音乐自由切换、游戏暂停同步控音功能
1.音频资源准备完成后,在游戏主线程、窗口类中创建音频对象

// 1. 定义背景音乐路径数组String[]musicList={"resources/bg1.wav","resources/bg2.wav","resources/bg3.wav"};// 2. 创建音频工具对象AudioMusicaudio=newAudioMusic(musicList);// 3. 加载并播放第一首audio.loadMusic(audio.currentIndex);audio.playLoop();

2.控制音乐切换
(1)键盘按键切换

@OverridepublicvoidkeyPressed(KeyEvente){// F1切换下一首if(e.getKeyCode()==KeyEvent.VK_F1){audio.nextMusic();}}

(2)画面图片按钮切换
绘制按钮图片,记录按钮坐标范围;鼠标点击监听中判断坐标,命中则执行切换

@OverridepublicvoidmouseClicked(MouseEvente){intx=e.getX();inty=e.getY();// 判断是否点击音乐切换按钮区域if(x>=10&&x<=110&&y>=10&&y<=60){audio.nextMusic();}}

3.游戏暂停/继续同步控制音乐

if(isPause){audio.stopMusic();// 暂停游戏,停止音乐}else{audio.playLoop();// 恢复游戏,继续播放音乐}

4.在画布绘制文字提示当前播放音乐

// g为缓冲画笔buffGg.setColor(Color.WHITE);g.setFont(newFont("黑体",Font.BOLD,30));g.drawString("当前背景音乐:第"+(audio.currentIndex+1)+"首",20,60);
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 2:22:29

维度砍一半,检索到底差多少:自测 + 独立信源对账

版权与内容来源声明 本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容&#xff0c;均在附表 A 中标注来源&#xff1b;引用官方原文保持原样&#xff0c;不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准&#xff0c;标注「待验证」的部…

作者头像 李华
网站建设 2026/10/9 2:20:47

谁说GLM5.2部署不到A100上?用TaoToken统一Key打通推理链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/9 2:18:54

基于BERT的文本纠错模型实战:从数据构造到推理调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/9 2:16:29

RS485老电表不换表上云:DTU、采集器、边缘网关三条路径对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华