最终效果

整个项目都是基于swing实现的。窗是口将图片加载到JPanel面板,然后将面板添加到到JFrame窗口实现显示。

这个类是选择几只像素鸟的类,也是main函数里执行的方法,代码有详细的注释,这里就不废话了public class select extends JPanel {

/**

*

*/

private static final long serialVersionUID = 1L;

Image background;//添加到窗口的背景图片

Image title1;//添加到窗口的游戏名称图片

JFrame jf; //选择小鸟的窗口

JButton []b ;//按钮数组

client t,t1,t2;//主游戏类

public select(){

jf = new JFrame();//实例化窗口

jf.setTitle("请小心选择小鸟数量");//窗口的标题

jf.setSize(300, 300);//设置窗口大小

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗口关闭方式,关闭即退出程序

jf.setLocationRelativeTo(null);//设置窗口在屏幕中间显示

jf.setResizable(true);//窗口不可更改大小

jf.add(this);//将面板加入窗口

setLayout(null);//设置面板的布局为空,从而可以任意位置放置按钮

final ImageIcon icon = new ImageIcon("Image/2.png");

background = ((ImageIcon) icon).getImage();

title1 = new ImageIcon("Image/title.png").getImage();

b = new JButton[3];

//实例化按钮

for(int i = 0;i < 3;i++)

b[i] = new JButton();

//为按钮添加照片、设置背景位置

b[0].setIcon(new ImageIcon("Image/bird0_0.png"));

b[0].setBounds(120,80,40,30);

this.add(b[0]);

//为第二个按钮添加照片、设置背景位置

b[1].setIcon(new ImageIcon("bird3_2.png"));

b[1].setBounds(95,130,100,33);

this.add(b[1]);

//外第三个按钮添加照片

b[2].setIcon(new ImageIcon("bird3_3.png"));

b[2].setBounds(70,185,146,35);

this.add(b[2]);

//为第一个按钮添加点击事件

b[0].addActionListener(new ActionListener(){

public void actionPerformed(final ActionEvent e) {

t = new client();//启动游戏类对象

jf.dispose();//撤销当前窗口

t.init1();//初始化即进入游戏

}

});

//为第二个按钮添加点击事件

b[1].addActionListener(new ActionListener(){

public void actionPerformed(final ActionEvent e) {

jf.dispose();

t = new client();

t.init2();

}

});

//为第三个按钮添加点击事件

b[2].addActionListener(new ActionListener(){

public void actionPerformed(final ActionEvent e) {

jf.dispose();

t = new client();

t.init3();

}

});

jf.setVisible(true);//设置窗口可见

}

//启动窗口后会自动调用这个画画方法,将背景图片画到界面上

public void paint(final Graphics g){

super.paint(g);

g.drawImage(background,0,0,300,300,this);

g.drawImage(title1,55,20,174,48,this);

}

}

client类,游戏主类。Main入口方法也放在了这里public class client extends JPanel implements KeyListener{

/**

*

*/

private static final long serialVersionUID = 1L;

private Image background1,background2; //定义两张图片作为背景

private Plane pl; //定义一个线程

private pipe P[]=new pipe[300];//定义柱子数组对象

ArrayList list=new ArrayList();//存放柱子的集合

Random ran=new Random();

public int k=0;

public int score = 0;

private bird b1,b2,b3; //定义一个小鸟

int flag;//判断调用哪个初始化函数,即创建几个小鸟

private int x = 0; //这个变量是用来改变小鸟的飞行状态,起到切换图片的作用

public static Music m;//背景音乐

public static Music m2;//结束时的声音

JFrame jf;

public Image gameover = new ImageIcon("Image/text_game_over.png").getImage();//游戏结束的图片

//分别获取三只小鸟的散装飞行状态的图片

ImageIcon icon1 = new ImageIcon("Image/bird0_0.png");

ImageIcon icon2 = new ImageIcon("Image/bird0_1.png");

ImageIcon icon3 = new ImageIcon("Image/bird0_2.png");

ImageIcon icon4 = new ImageIcon("Image/bird1_0.png");

ImageIcon icon5 = new ImageIcon("Image/bird1_1.png");

ImageIcon icon6 = new ImageIcon("Image/bird1_2.png");

ImageIcon icon7 = new ImageIcon("Image/bird2_0.png");

ImageIcon icon8 = new ImageIcon("Image/bird2_1.png");

ImageIcon icon9 = new ImageIcon("Image/bird2_2.png");

public boolean b = true;//判断是否进入画排行榜的变量

Font font = new Font("宋体",Font.BOLD,30);

//存放从文件中获取的分数

int ScoreArray[] = new int[300];

JButton continueButton,outButton;

RandomAccessFile Score;//定义随机流变量

int nandu = 1;//游戏难度

//实例化一个游戏类

public static void main(String[] args) {

new select();

}

public int produce() {

return (int)(Math.random()*30 );

}

//主类的构造方法

public client(){

jf = new JFrame("请注意!即将开始游戏,控制三只小鸟的按钮依次时是:Q,W,E");//新建一个窗口

jf.setSize(600, 393);//设置窗口大小

jf.setLocationRelativeTo(null);//设置窗口在屏幕中间显示

jf.setResizable(false);//窗口不可更改大小

jf.add(this);//将面板加入窗口

jf.setVisible(true);//设置窗口可见

jf.addKeyListener(this); //为窗口注册按键事件

m=new Music("风中舞.WAV");//因为这个文件太大,在资源中我已经删掉了。想要背景音乐的话下载一个wav格式的音乐放到文件目录下。然后在这里输入资源名称即可

m2=new Music("小黄人2.WAV");

//通过ImageIcon类加载背景图片

ImageIcon icon = new ImageIcon("Image/3.png");

// ImageIcon icon1=new ImageIcon("Image/pipe_down.png");

background1 = icon.getImage();

background2 = icon.getImage();

//给柱子初始化

for(int i=0;i<300;i++){

P[i]=new pipe(600+k,produce(),this);

list.add(P[i]);

k+=150;

}

}

//数据初始化方法

//创建一只小鸟的时候调用

public void init1()

{

flag = 1;//设置小鸟数为1,为下面的画小鸟做准备

b1 = new bird(0,100,this);//创建一个小鸟对象

b1.setbird(icon1,icon2,icon3);

pl = new Plane(background1,background2,0,0,this);//创建一个线程对象

m.play();

pl.start(); //

}

//两只小鸟一起飞时调用

public void init2()

{

flag = 2;

b1 = new bird(0,100,this);//创建一个小鸟对象

b1.setbird(icon1,icon2,icon3);

b2 = new bird(50,100,this);//创建一个小鸟对象

b2.setbird(icon4,icon5,icon6);

pl = new Plane(background1,background2,0,0,this);//创建一个线程对象

m.play();

pl.start(); //开始线程

}

//三只小鸟一起飞时调用

public void init3()

{

flag = 3;

b1 = new bird(0,100,this);//创建一个小鸟对象

b1.setbird(icon1,icon2,icon3);

b2 = new bird(50,100,this);//创建一个小鸟对象

b2.setbird(icon4,icon5,icon6);

b3 = new bird(100,100,this);//创建一个小鸟对象

b3.setbird(icon7,icon8,icon9);

pl = new Plane(background1,background2,0,0,this);//创建一个线程对象

m.play();

pl.start(); //开始线程

}

//JPanel面板的画图方法-------这个方法需不断地被执行,我们放在自己创建的一个线程里执行

public void paint(Graphics g){

super.paint(g);

g.drawImage(pl.background1, pl.x, pl.y, 600, 393, this);//画第一张背景图

g.drawImage(pl.background2,599+pl.x, pl.y, 600, 393, this);//画第二张背景图

//通过判断flag值来确定画几个小鸟

String s = Integer.toString(score);

String n = Integer.toString(nandu);

this.drawBirdAndJump(g);

//画柱子和柱子的移动

for(int i=0;i

list.get(i).drawDown(g);

list.get(i).drawUp(g);

list.get(i).move();

}

g.setColor(Color.RED);

g.setFont(font);

g.drawString("得分:"+s, 150, 25); //画分数

g.setColor(Color.PINK);

g.drawString("难度:"+n, 380, 25);

this.isDead(g);

try {

this.showScore(g);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void isDead(Graphics g){

//柱子和1只小鸟碰撞

if(flag==1){

for(int i = 0;i < list.size();i++){

if(b1.Getrect().intersects(list.get(i).GetDOWNrect()) ||//第一只鸟与上边界柱子相碰

b1.Getrect().intersects(list.get(i).GetUPrect())//第一只鸟与下边界柱子相碰

|| b1.gety() < 0 || b1.gety() > 393)//小鸟往上飞出窗口或者往下掉出窗口

{

pl.setFlag(false);//柱子停止移动

m.stop();//游戏结束时停止背景音乐

g.drawImage(gameover,200,180,204,54,this);//画出游戏结束图片

}

}

}

//2只小鸟时,小鸟与柱子的碰撞

else if(flag==2){

for(int i = 0;i < list.size();i++){//

if(b1.Getrect().intersects(list.get(i).GetDOWNrect()) ||

b1.Getrect().intersects(list.get(i).GetUPrect())

|| b2.Getrect().intersects(list.get(i).GetDOWNrect())

|| b2.Getrect().intersects(list.get(i).GetUPrect())

|| b1.gety() < 0 || b1.gety() > 393

|| b2.gety() < 0 || b2.gety() > 393)

{

pl.setFlag(false);

m.stop();//游戏结束时停止背景音乐

g.drawImage(gameover,200,180,204,54,this);

}

}

}

//三只小鸟时候的小鸟与柱子碰撞

else if(flag==3){

for(int i = 0;i < list.size();i++){

if(b1.Getrect().intersects(list.get(i).GetDOWNrect()) ||

b1.Getrect().intersects(list.get(i).GetUPrect())

|| b2.Getrect().intersects(list.get(i).GetDOWNrect())

|| b2.Getrect().intersects(list.get(i).GetUPrect())

|| b3.Getrect().intersects(list.get(i).GetDOWNrect())

|| b3.Getrect().intersects(list.get(i).GetUPrect())

|| b1.gety() < 0 || b1.gety() > 393

|| b2.gety() < 0 || b2.gety() > 393

|| b3.gety() < 0 || b3.gety() > 393)

{

pl.setFlag(false);

m.stop();//游戏结束时停止背景音乐

g.drawImage(gameover,200,180,204,54,this);

}

}

}

if(pl.getFlag())

{

for(int i = 0;i < list.size();i++){

if(list.get(i).getUppipex() < 0){

//每十根柱子更改移动速度

if(score % 10 == 0 && score != 0){

pipe.setMoveSp();

nandu++;

}

list.remove(i);

Music mus=new Music("小黄人1.WAV"); ;//定义多个过柱子时的笑声

mus.play();

score++ ;

}

}

}

}

/*

* 画出排行榜

* 画出当前分数的排行

*/

public void showScore(Graphics g) throws IOException{

int max,sedmax,threemax;//三个变量保存分数的前三名

if(!pl.getFlag()&&b){

b = false;//避免线程刷新画面时重新进入浪费资源,设置为false

int i;

//创建随机流访问文件

//判断是几只小鸟,然后将分数存到不同的文件中

if(flag == 1)

Score = new RandomAccessFile("scoreOneBird.dat","rw");

else if(flag == 2)

Score = new RandomAccessFile("scoreTwoBird.dat","rw");

else

Score = new RandomAccessFile("scoreThreeBird.dat","rw");

//将位置跳到文件末,存放分数

Score.seek(Score.length());

Score.writeInt(score);

//关闭文件

Score.close();

i =0;

while(true){

//判断是在玩几只小鸟,然后打开不同的存分数文件

if(flag == 1)

Score = new RandomAccessFile("scoreOneBird.dat","rw");

else if(flag == 2)

Score = new RandomAccessFile("scoreTwoBird.dat","rw");

else

Score = new RandomAccessFile("scoreThreeBird.dat","rw");

//每隔四个字节读取一个整形数

Score.seek(i*4);

//将分数保存到数组中

ScoreArray[i] = Score.readInt();

i++;

//如果到文件末尾,退出循环

if(Score.length() == i*4){

break;

}

}

//关闭文件

Score.close();

//初始化三个变量

max = sedmax = threemax = 0;

//将数组按顺序排序

Arrays.sort(ScoreArray);

//轻松获取前三大值

max = ScoreArray[ScoreArray.length-1];

sedmax = ScoreArray[ScoreArray.length-2];

threemax = ScoreArray[ScoreArray.length-3];

//记录排名,从末尾往前

int count = ScoreArray.length;

for(i = 0;i < ScoreArray.length;i++)

{

//如果分数比数组里的数大,排名往前一位

if(ScoreArray[i] < score )

count--;

//如果等0,说明是第一名

if(count == 0)

count = 1;

}

//三个整形转换成字符型

String ScMax = Integer.toString(max);

String ScSeMax = Integer.toString(sedmax);

String ScThMax = Integer.toString(threemax);

//设置字体大小、改变颜色、画出排名

g.setFont(font);

g.setColor(Color.MAGENTA);

g.drawString("当前排名:"+count,150, 90);

g.setColor(Color.ORANGE);

g.drawString("得分排名第一:"+ScMax, 150, 120);

g.setColor(Color.CYAN);

g.drawString("得分排名第二:"+ScSeMax, 150, 150);

g.setColor(Color.GREEN);

g.drawString("得分排名第三:"+ScThMax, 150, 180);

//实例两个按钮

continueButton = new JButton("重新开始");

outButton = new JButton("退出游戏");

//将按钮添加到面板上、设置背景颜色、出现的位置以及大小

this.add(continueButton);

this.add(outButton);

continueButton.setBackground(Color.green);

continueButton.setBounds(140,240,100,50);

outButton.setBackground(Color.CYAN);

outButton.setBounds(350,240,100,50);

//为继续按钮添加点击事件

continueButton.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e) {

jf.dispose();

new select();

}

});

// 为退出游戏按钮添加点击事件

outButton.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

jf.dispose();

}

});

}

}

public void drawBirdAndJump(Graphics g){

//画一只小鸟

if(flag == 1)

{

jf.setTitle("单飞像素鸟 跳跃键:Q");

b1.draw(g,x);//调用小鸟对象的画图方法画一个小鸟

}

//flag=2 画2只小鸟

else if(flag == 2)

{

jf.setTitle("双飞像素鸟 跳跃键:Q、W");

b1.draw(g,x);

b2.draw(g,x);

}

//画三只小鸟

else

{

jf.setTitle("三飞像素鸟 跳跃键:Q、W、E");

b1.draw(g,x);//调用小鸟对象的画图方法画一个小鸟

b2.draw(g,x);

b3.draw(g,x);

}

x++;//每次跑都改变小鸟飞行的图片

if(flag == 1)

b1.move();//小鸟往下掉的方法

else if(flag == 2)

{

b1.move();

b2.move();

}

else if(flag == 3){

b1.move();//小鸟往下掉的方法

b2.move();

b3.move();

}

if(x == 3)//小鸟飞行有三张图片,循环变换

x = 0;

}

//按下键盘时自动调用的方法

public void keyPressed(KeyEvent e) {

}

//按下并且释放键盘时自动调用的方法

public void keyReleased(KeyEvent e) {

//通过flag值判断调用多少个小鸟的按键函数

if(flag == 1)

b1.keyPressed1(e);//调用小鸟类的按键方法

else if(flag == 2){

b1.keyPressed1(e);

b2.keyPressed2(e);

}

else{

b1.keyPressed1(e);//调用小鸟类的按键方法

b2.keyPressed2(e);

b3.keyPressed3(e);

}

}

线程类非常简单。只要一个死循环就行public class Plane extends Thread {

public Image background1, background2; // 定义两张背景

public int x = 0; // 背景图片x坐标

public int y = 0;// 背景图片y坐标

public JPanel jp;// 定义一个面板

public int movesp = 5;// 背景图的移动速度

public boolean flag = true;

public Music m = new Music("风中舞.WAV");

public Music m2 = new Music("小黄人2.WAV");

// 构造方法

public Plane(Image background1, Image background2, int x, int y, JPanel jp) {

m.play();

this.background1 = background1;

this.background2 = background2;

this.x = x;

this.y = y;

this.jp = jp;// 将面板传进来主要是为了在线程中调用窗口面板的repaint

// 方法,重画游戏窗口

}

public boolean setFlag(boolean flag) {

this.flag = flag;

return flag;

}

public boolean getFlag() {

return flag;

}

public void run() {

// 在线程中循环调用背景图的move方法,并且重画面板

while (true) {

if (flag) {

//移动就是通过不断刷新更改x,y值实现的

jp.repaint();

} else {

m.stop();

m2.play();

}

try {

Thread.sleep(100);// 线程睡眠0.1秒

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

还有一个柱子类、封装的调用播放音乐的类非常非常简单这里就不放占用资源了。下载地址

像素鸟源代码下载下载后直接导入到myeclipse中就可以运行了噢

像素鸟多线程java_用java Swing做的小游戏像素鸟-Go语言中文社区相关推荐

  1. 用java Swing做的小游戏quot;像素鸟quot;

    最终效果 整个项目都是基于swing实现的.窗是口将图片加载到JPanel面板,然后将面板添加到到JFrame窗口实现显示. 这个类是选择几只像素鸟的类,也是main函数里执行的方法,代码有详细的注释 ...

  2. 基于Java+Swing实现雷电小游戏

    基于Java+Swing实现雷电小游戏 一.系统介绍 二.功能展示 三.其他系统 四.获取源码 一.系统介绍 基于java的雷电游戏基本功能包括:敌方飞机随机飞行.我方飞机手动控制飞行,射击比拼,游戏 ...

  3. java.swing 飞机大战小游戏

    上午没事刷到网上最近炒热了一些简单的小游戏和爱心代码,单身8个月了,对爱心代码不是很感冒,所以想蹭个热度,写一个飞机大站来玩玩. 首先,分析小游戏需要那些技术与怎么设计: 窗体,因为是java小游戏, ...

  4. Java Swing 贪吃蛇小游戏

    静态资源参考: 注:实际上没有用到header.png. 工程目录: 源码: package snake;import javax.swing.*; import java.net.URL;/*** ...

  5. Java Swing制作2048小游戏【完整版】

    技术讨论群:1005611884 可获取各种资料/代码,群内有Java/Python/C++/C#方向大佬,妹子多 /*** 技术 Swing* 实现思路:* 1. 绘制窗口* 2. 初始化游戏界面* ...

  6. Java swing写五子棋小游戏(分析)

    五子棋游戏开发 实现的功能 步骤实现代码分析 完整代码展示 实现的功能 五子棋,双方交互下,五字连珠即获胜 开始游戏,悔棋,认输,设置等选项 下方提示剩余时间,上方提示该谁下 效果图片展示如下 步骤实 ...

  7. java swing GUI 雷电小游戏,适合初级小白

    基于java的雷电游戏基本功能包括:敌方飞机随机飞行.我方飞机手动控制飞行,射击比拼,游戏闯关等.本系统结构如下:  (1)雷电游戏状态调整功能:     在游戏启动时,游戏会自动进行初始化的验证. ...

  8. grpc java 泛型_关于使用GRPC遇到的BUG-Go语言中文社区

    GRPC获取服务器数据是耗时操作,不能写在UI主线程中,可以写在子线程或使用AsyncTask实现获取数据,但实测,仅仅是获取少量数据,可以写在UI主线程中(虽然不推荐这么做).目前博主在AsyncT ...

  9. java控制系统音量_Java 控制 Windows 系统音量-Go语言中文社区

    目录 1.使用 Java 来控制 Windows 系统音量,使用 JNA 调用 windows 底层 API 因为有点麻烦,所以这里采用纯 Java API结合 VBS 脚本的方式进行控制. 2.可以 ...

最新文章

  1. 如何解决Asp.Net MVC和WebAPI的Controller名称不能相同的问题
  2. iOS Sprite Kit教程之xcode安装以及苹果帐号绑定
  3. Sklearn:sklearn.preprocessing之StandardScaler 的transform()函数和fit_transform()函数清晰讲解及其案例应用
  4. CentOS 下 yum(基于rpm的包管理工具) 命令详解
  5. C#怎么遍历一个对象里面的全部属性?
  6. python面向对象编程的语言_怎么使用python面向对象编程
  7. C# 文件流相关操作
  8. 设计模式 代理模式和装饰模式的区别
  9. 14天1000+大集群滚动升级,银行柜台竟然毫无感觉
  10. Android功耗优化(6)---如何确定阻止进入suspend的原因
  11. phalcon + nginx 混合模式配置
  12. 利用Node.js为Node.js生成HttpStatusCode辅助类并发布到npm
  13. mopso算法代码程序_程序员如何跨越35岁危机?这篇给点干货建议!
  14. 三极管饱和时内部状态再探
  15. IEEE1588v2解析(4)--透明时钟/一步时钟/二步时钟
  16. 显示器刷新率30hz_如何使您的120Hz或144Hz显示器使用其广告刷新率
  17. C语言经典问题——兑换硬币
  18. 为什么Java大数据是最火爆的编程语言?
  19. 清空数据库表结构的几种方式
  20. 基于PHP的图书商城系统

热门文章

  1. 【26天高效学习Java编程】Day19:60 多个实例讲解,彻底搞懂Java 多线程 【可查阅,可复习,可面试】
  2. HarmonyOS内存占用,华为HarmonyOS对比EMUI11:内存占用更少 系统更流畅
  3. 荷兰国土不大,人口不多,为什么有那么多世界级大公司?
  4. 白加黑加载方式_AVG中国实验室发现“白加黑”型恶意程序
  5. hpm1005能扫描不能打印_小米米家喷墨打印一体机体验:500元以内学生和职场人的实惠选择...
  6. 前端笔试面试题之三(2015美的前端笔试)
  7. ME2188A33M3G 高效、同步的PFM升压直流-直流转换器
  8. ajax post无效,jQuery AJAX Post无效
  9. CRM为3Com带来什么?
  10. CMake I add_custom_command命令详解(构建)