源代码下载: https://github.com/Fattybenny/javaswingproject/tree/main/java%E9%A3%9E%E6%9C%BA%E5%A4%A7%E6%88%98.
首先,要把整体的游戏框架和内容构思出来(根据预先构思游戏里存在的组件内容和游戏功能抽象出指定类)。以我的小游戏为例:
2.弹出界面类:Dialog (extends JDialog)
弹出设置界面(声音开关)、弹出游戏成功、失败界面
JDialog 窗体的功能是从一个窗体中弹出另一个窗体,就像是在使用 IE 浏览器时弹出的确定对话框,JDialog 窗体与 JFrame 窗体形式基本相同,设置窗体的特性时调用的方法名称都基本相同,如设置窗体大小、窗体关闭状态等
背景动画
动态的图像(视频)原理:视频由一张张静态的图片快速变换形成,连续的图像变化每秒超过24帧(frame)画面以上时,根据视觉暂留原理,人眼无法辨别单幅的静态画面;看上去是平滑连续的视觉效果。
在java程序中,如果通过人手动点击一次换一次图片,那么要想实现肉眼看见的视频效果需要我们一秒钟至少点击24次,这是非常困难的。而我们希望的是通过一次点击就可以产生动画效果,让其自动每隔一段极短的时间就换一次图片。于是可以采用多线程的方法来实现。由于动画效果是在当前的GameFrame类中实现的,可以直接定义一个内部类继承Thread,当然也可以新建一个class文件定义。
获取包中的图片:
菜单选项
设置不同的JLabel标签添加到界面的相应位置。
一般容器都有默认布局方式,但是有时候需要精确指定各个组建的大小和位置,就需要用到空布局。
首先利用setLayout(null) 语句将容器的布局设置为null布局(空布局)
再调用组件的setBounds(int x, int y, int width,int height) 方法设置组件在容器中的大小和位置,单位均为像素。
通过JLabel组件添加一张图片:
问题与解决:
1.先添加的组件会覆盖影响到后添加的组件。
例如这里有三个JLabel组件,其中一个是带有背景图片的,其他两个是带有文字的,一定要最后添加带有背景图片的,否则无法将文字显示在图片上。
2.注意画笔绘制图片的覆盖问题:
后面经常要用到drawimage方法,要注意,画笔后画的内容会覆盖先画的内容;画笔画的内容会覆盖类似JLabel这种组件,无论组件先添加还是后添加(解决办法:在组件添加到相应的容器之后再设置坐标位置(setbounds),或者如上文所说的通过按正确顺序添加JLabel组件的方法来达到设置背景图片的功能,避免了用drawimage)。
添加(键盘)监听器
问题与解决
焦点的获取
在使用键盘监听器的时候,一定要让监听对象获取焦点,如果焦点不在监听对象上,那么键盘输入的内容就无法被监听到。
使用requestFocusInWindow()方法
注意在监听器方法中的this关键字
在添加监听器时有两种不同的方法:
1.this.addKeyListener(listener);
listener是用户定义的监听器类,这个类implements相应接口。
2.直接在当前类定义监听器;
按钮区和分数区都分别添加相应的JButton按钮,并添加ActionListener监听器即可
动态游戏显示区(双缓冲)
还是和GameFrame中的背景动画类似,都采用多线程方法。
问题与解决:
1.Canvas使用
Canvas是AWT组件,JPanel是Swing组件,Swing组件是以AWT组件为基础的,从理论上来说,Canvas要比JPanel更轻量些.如果canvas能满足需求,就用canvas.Canvas 组件表示屏幕上一个空白矩形区域,应用程序可以在该区域内绘图,或者可以从该区域捕获用户的输入事件。
不能直接使用该类,需要继承Canvas并重写其paint方法.
repaint paint update 三个方法的调用顺序:
repaint->update->paint
paint源码:
update源码:
由此看来我们可以选择性的重写update或者paint方法来满足程序绘画需要,如果不需要清除界面就去除 g.clearRect(0, 0, width, height)方法,在本例中就需要执行这一步,因为每次重绘图片如果都执行一遍清除界面操作就会出现闪烁现象。(如果是用户自己定义的绘制方法,不需要用到paint方法进行重绘,则不用重写这些方法,需要用到双缓冲技术,如下所示)
除此以外解决图片闪烁现象,还要用到双缓冲技术:
先在内存中预先分配一定大小的图片缓冲区,在将所有绘图方法绘制到缓冲区之后,再最后将图片缓冲区的内容绘制出来;
这三个不同的飞机类内容基本相同:
两张图片(飞机和飞机,飞机和子弹)是否相碰,需要判断的是矩形图片是否有重叠部分。
以飞机与飞机相碰为例:
按照x,y坐标的大小不同,总共有2*2四种情况:
存储子弹:
弹出对话框和JFrame类似,往里面添加各种组件和监听器即可。
除了上文中所解决的问题,还有一点就是,对于多线程到底该什么时候去创建?或者说多线程该设置在什么位置?(以下是我自己的理解)
直观的感受就是多线程是在自动持续执行时引入的,对于飞机大战来说,动画界面一旦开始执行(在满足条件的情况下),会一直执行直到满足结束条件就退出,很明显,背景、玩家飞机、敌机、boss飞机等等这些图片都是在自动不断刷新,刚开始会想到让这些自动执行的类都实现多线程(extends Thread),要完成刷新的同步,只需要统一好阻塞时间就行了,但是这样实现会发现代码开销比较大,且不便于统一管理。所以可以将这些类统一用一个Thread类实现同步的控制(只需要在这个Thread类中调用各个类中的方法即可)。
在本例中就是用GamePanel(可以直接让GamePanel extends Thread 或者创建一个内部Thread类)来控制背景、飞机等各种图片的绘制和图片移动。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/10563.html